At school we used a pair of equations to generate sinewaves.
x = x + y / n y = y - x / n
Itterate them and apply y or x to a D to A converter. You get a sine wave as long at n is quite large.
One of the most striking things to me is the stability of the prediction.
The amplitude remains constant of very many cycles.
INT_SERVICE_TMR2 OStimeSlice MOVFW OSloops MOVWF OScnt OStimeSlice1 BCF PIR1, TMR2IF ; want x=x+y/256 ; want y=y-x/256 ; x=x+y/256 BCF STATUS,C MOVFW OSyh ;y/256 ADDWF OSxl,f ; add the carry BTFSC STATUS,C INCF OSxh,f ; sign extend the MSB ; add 0xFF is MSB if OSyh is set ; note we add OSy BTFSC OSyh,7 DECF OSxh,f ; y=y-x/256 BCF STATUS,C MOVFW OSxh;x/256 SUBWF OSyl,f ;x/256 BTFSS STATUS,C DECF OSyh,f ; now subtract sign extended OSx ; MOVLW 0 ; BTFSC OSxh,7 ; MOVLW 0xff ; SUBWF OSyh,f ; if MSB of OSxh,7 is set then sign extend and subtract -1 from OSyh by adding 1 to OSyh BTFSC OSxh,7 INCF OSyh,f DECFSZ OScnt GOTO OStimeSlice1 ; if you use OSyh at this point you get a discontinuty at the peaks ; if you use OSxh at this point you get a smaller discontinuty on the way up ; MOVFW OSyh ;y/256 MOVFW OSxh ;y/256 ADDWF OSoffset,w BANKSEL CCPR1L MOVWF CCPR1L return
I set up the PWM using
ifdef buildPWM ; Configure Tmr 1 MOVLW 0x0 | 1<<TMR1ON | 3 <<T1CKPS0 MOVWF T1CON CLRF OSxh CLRF OSxl CLRF OSyh CLRF OSyl MOVLW 0x1f MOVWF OSxhStart CLRF OSxlStart MOVLW 0x01 MOVWF OSloops MOVLW 0x40 MOVWF OSoffset endif
and
PWinit ; set up the PWM ifdef buildPWM ; Move the PWM period into PR2 MOVLW 0 CALL EEread BANKSEL PR2 MOVWF PR2 MOVLW 0 MOVWF TRISB MOVLW 1 CALL EEread BANKSEL CCPR1L MOVWF CCPR1L MOVLW 1 << TMR2ON MOVWF T2CON BANKSEL CCP1CON MOVLW 1<< CCP1X | 1<< CCP1Y | ( .12 << CCP1M0 ) MOVWF CCP1CON ; ; init SHM sinewave generator. ; MOVFW OSxhStart MOVWF OSxh MOVFW OSxlStart MOVWF OSxl CLRF OSyh CLRF OSyl endif RETURN
This was added to: http://www.dougrice.plus.com/hp/freq/freq.htm
; x=x+y/16 BCF STATUS,C SWAPF OSyh,w ;y/256 ; sign extend OSyh ANDLW 0x0F BTFSC OSyh,7 IORLW 0xF0 ADDWF OSxh,f ; add the carry BTFSC STATUS,C INCF OSxh,f ; y=y-x/16 BCF STATUS,C SWAPF OSxh,w ;y/256 ; sign extend OSxh ANDLW 0x0F BTFSC OSxh,7 IORLW 0xF0 SUBWF OSyh,f ;x/256 BTFSS STATUS,C DECF OSyh,f MOVFW OSxh ;y/256 ADDWF OSoffset,w BANKSEL CCPR1L MOVWF CCPR1L
;************************************************************************** ; SR002.ASM ; ; PROGRAM: Simple Serial Project ; ; DESCRIPTION: ; simple serial project that receives serial commands ; spaces are important ; ; Serial Commands:- ; ; File Regiters ; <CR>wAADD; write DD to register AA ; <CR>rAA; read AA and output to serial port ; ; EEPROM ; <CR>pAADD; write DD to EEPROM register AA ; <CR>gAA; read EEPROM register AA and output to serial port ; ; PRIPHERALS ; <CR>f; init PWM ; ; sets up PWM module ; W92FF; - PR2 - set PWM period max ; W1532; - CCPR1L - Duty Cycle / ON period ; W8600; - TRISB - All Outputs ; W1204; - T2CON - Set up Tmr 2 ; W173C; - CCP1CON - Set up as PWM module. ; W9265; - PR2 - set PWM period for 10Khz if 4Mhz crystal. ; ; ; SERIAL PORT CONTROL: ; ; PORT A0 is Serial input ; PORT A0 is serial output ; ; usb gmus-03 USB Serial Adapter ; ; TX D9 Pin 3 -[4k7]----+-----PA0 ; RX D9 Pin 2 ----------/ ; ; GND D9 Pin 5 ---------------- 0V ; ; AUTHOR: Douglas Rice ; Copyright 2004 ; ; Crystal: 4MHz ; ; I/O used:- ; ; ; Port B is used for the LCD ; ; ;************************************************************************** ;-------------------------------------------------------------------------- ; Sec 0. #Defines tofor different chips ;-------------------------------------------------------------------------- ; uncomment only one of these ; ;#define pic16F84 1 #define pic16F628 1 ;#define pic16F876 1 ;#define pic12F675 1 LIST w=0, R=DEC ;-------------------------------------------------------------------------- ; Sec 0.1 #Defines for 16F84 ;-------------------------------------------------------------------------- ifdef pic16F84 LIST P=16F84, R=DEC INCLUDE "p16F84.inc" __idlocs 0x0084 __config _XT_OSC & _PWRTE_ON & _WDT_OFF cblock 0x0c endc PORT_RS232 EQU PORTA TRIS_RS232 EQU TRISA RS232tx EQU 0 ; Serial Out RS232rx EQU 0 ; Serial In needs to be equal to BUTTON_RS232 endif ;-------------------------------------------------------------------------- ; Sec 0.2 #Defines for 16F628 ;-------------------------------------------------------------------------- ifdef pic16F628 #define buildPWM 1 LIST P=16F628, R=DEC INCLUDE "p16F628.inc" __idlocs 0x0628 __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _INTRC_OSC_CLKOUT & _MCLRE_OFF & _LVP_OFF cblock 0x20 endc ; *********** I/O EQUATES ************** PORT_RS232 EQU PORTA TRIS_RS232 EQU TRISA RS232tx EQU 0 ; Serial Out RS232rx EQU 0 ; Serial In needs to be equal to BUTTON_RS232 endif ;-------------------------------------------------------------------------- ; Sec 0.3 #Defines for 16F876 ;-------------------------------------------------------------------------- ifdef pic16F876 #define buildPWM 1 LIST P=16F876, R=DEC INCLUDE "p16F876.inc" __idlocs 0x0876 __CONFIG _CP_OFF & _DEBUG_OFF & _WRT_ENABLE_ON & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _HS_OSC & _LVP_OFF cblock 0x20 endc ; *********** I/O EQUATES ************** PORT_RS232 EQU PORTA TRIS_RS232 EQU TRISA RS232tx EQU 0 ; Serial Out RS232rx EQU 0 ; Serial In needs to be equal to BUTTON_RS232 endif ;-------------------------------------------------------------------------- ; Sec 0.4 #Defines for 12F675 ;-------------------------------------------------------------------------- ifdef pic12F675 LIST P=12F675, R=DEC INCLUDE "p12F675.inc" __idlocs 0x0675 __config _PWRTE_ON & _WDT_OFF & _BODEN_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF cblock 0x20 endc ; *********** I/O EQUATES ************** PORT_RS232 EQU GPIO TRIS_RS232 EQU TRISIO RS232tx EQU 5 ; Serial Out RS232rx EQU 5 ; Serial In needs to be equal to BUTTON_RS232 PORTA EQU GPIO PORTB EQU GPIO TRISA EQU TRISIO TRISB EQU TRISIO endif ;-------------------------------------------------------------------------- ; Sec 1. Equates and Constants ;-------------------------------------------------------------------------- ; The General Purpose Registers start at the end of the ; Special Purpose Registers. ; IPMentState values ; in normal running or in time setting modes ; ; DoTimeSlice bits ; these bits are set to schedule a timer chain event DTsS4event EQU 0 ; RUN_BUFF EQU 0 ; ; IPtrigMenu DTSFast EQU 0 ;-------------------------------------------------------------------------- ; Sec 1.1 Button and LED ;-------------------------------------------------------------------------- BUTTON_RS232 EQU RS232rx ; EDG - Bottom Buttom BUTTON_DOWN EQU 6 ; EDG - Bottom Buttom ;-------------------------------------------------------------------------- ; Sec 2.0 Variables ;-------------------------------------------------------------------------- ; Variables start 0x0C ; ; DoTimeSlice Bits, to schedule, set bit cblock DoTimeSlice IPnew IPlast IPbuttonEvent IPnewFast IPlastFast IPbuttonEventUp IPtrigMenu ; variables used by Serial input and output routines RStxTemp RSloopCnt RSdelayCnt RSin RSout ; Serial input buffer RSipBuffCnt ; input buffer counter ; start of buffer RScmd RSAa ; RSaA ; RSDd ; RSdD ; RSterminator ; end of buffer ; temporary variables RSaddr RSdata ; ; Sinewave Oscillator variables OSxhStart OSxlStart OSloops OSoffset ; working variables OSxh OSxl OSyh OSyl OScnt ENDC ;-------------------------------------------------------------------------- ; Sec 3. MACROS ;-------------------------------------------------------------------------- TEST_STRADDLE MACRO START if high( $ ) != high( START ) Error "Table straddles Page Boundary " + Start endif endm ;-------------------------------------------------------------------------- ; Sec 4. Program Code ;-------------------------------------------------------------------------- ORG 0 GOTO Start ORG 4 RETFIE GOTO Intrtn ;-------------------------------------------------------------------------- ; Sec 4.1 Main Program Init Code ;-------------------------------------------------------------------------- Start CALL INinit CALL INsayHello GOTO MainLoop INT_SERVICE_TMR2 OStimeSlice MOVFW OSloops MOVWF OScnt OStimeSlice1 BCF PIR1, TMR2IF ; want x=x+y/256 ; want y=y-x/256 ; x=x+y/256 BCF STATUS,C MOVFW OSyh ;y/256 ADDWF OSxl,f ; add the carry BTFSC STATUS,C INCF OSxh,f ; sign extend the MSB ; add 0xFF is MSB if OSyh is set ; note we add OSy BTFSC OSyh,7 DECF OSxh,f ; y=y-x/256 BCF STATUS,C MOVFW OSxh;x/256 SUBWF OSyl,f ;x/256 BTFSS STATUS,C DECF OSyh,f ; now subtract sign extended OSx ; MOVLW 0 ; BTFSC OSxh,7 ; MOVLW 0xff ; SUBWF OSyh,f ; if MSB of OSxh,7 is set then sign extend and subtract -1 from OSyh by adding 1 to OSyh BTFSC OSxh,7 INCF OSyh,f DECFSZ OScnt GOTO OStimeSlice1 ; if you use OSyh at this point you get a discontinuty at the peaks ; if you use OSxh at this point you get a smaller discontinuty on the way up ; MOVFW OSyh ;y/256 MOVFW OSxh ;y/256 ADDWF OSoffset,w BANKSEL CCPR1L MOVWF CCPR1L return ;-------------------------------------------------------------------------- ; Sec 4.2 Main Program ;-------------------------------------------------------------------------- MainLoop BTFSC PIR1, TMR2IF CALL INT_SERVICE_TMR2 CALL IPtimesliceFast ; test for rising edge BTFSC IPbuttonEventUp,BUTTON_RS232 ; RS232 input start CALL IPrs232 MOVF DoTimeSlice,w Bz MainLoop BTFSC DoTimeSlice,RUN_BUFF CALL DLrunBuff GOTO MainLoop ;-------------------------------------------------------------------------- ; Sec 5. Subroutines, procedures and functions ;-------------------------------------------------------------------------- ;-------------------------------------------------------------------------- ; Sec 5.1 Button Poll Routine ;-------------------------------------------------------------------------- IPtimeslice ; --_____ button press ; ----___ ; __----- /IPnew ; ----___ IPlast ; __--___ ; ; ; ; This reads all Port A inputs and looks for Press MOVFW IPnew MOVWF IPlast MOVFW PORTA MOVWF IPnew ; IP last contains new setting, IPlast contains previous ; look for falling edges COMF IPnew,W ANDWF IPlast,W ; now force IPbuttonEvent bits to high for new pressed button ; the service routine should reset the bit to clear the event. IORWF IPbuttonEvent,F RETURN IPtimesliceFast ; Look for rising edges MOVFW IPnewFast MOVWF IPlastFast MOVFW PORT_RS232 MOVWF IPnewFast COMF IPlastFast,W ANDWF IPnewFast,W IORWF IPbuttonEventUp,F RETURN ;-------------------------------------------------------------------------- ; Sec 5.2 ;-------------------------------------------------------------------------- ;-------------------------------------------------------------------------- ; Sec 5.2 .1 run process on request ;-------------------------------------------------------------------------- DLrunBuff BCF DoTimeSlice,RUN_BUFF ; MOVFW '#' ; CALL RStxChar MOVFW RSin CALL RSbuffInput return ;-------------------------------------------------------------------------- ; Sec 5.3 Button Input functions ;-------------------------------------------------------------------------- IPdownPressed BCF IPbuttonEvent,BUTTON_DOWN return IPrs232 BCF IPbuttonEventUp,BUTTON_RS232 GOTO RSrs232in ;-------------------------------------------------------------------------- ; Sec 5.4 Clock Chain Routine ;-------------------------------------------------------------------------- CLtimeslice ; BTFSS INTCON,T0IF RETURN ; TMR0 timeout BCF INTCON,T0IF BSF DoTimeSlice,DTsS4event CALL IPtimeslice RETURN ;-------------------------------------------------------------------------- ; Sec 5.5 Serial Input Routine ;-------------------------------------------------------------------------- ;************************************************** RSrs232in ; Test is in main loop or uncomment code below to ; spin for a start bit ; CLRWDT ; BTFSS PORT_RS232,RS232rx ; GOTO RSrs232in CALL RSdelayBit ; delay through Stop Bit CALL RSdelayHalfBit ; delay halfway into first bit movlw 8 movwf RSloopCnt RSrs232inL0 MOVFW PORT_RS232 ANDLW 1<< RS232rx ; mask off bit ADDLW -1<< RS232rx ; use ripple carry to move into C RRF RSin,F CALL RSdelayBit DECFSZ RSloopCnt,f goto RSrs232inL0 ; test for Stop bit COMF RSin,f BSF DoTimeSlice,RUN_BUFF RETURN ;-------------------------------------------------------------------------- ; Sec 5.6 Serial Output Routines ;-------------------------------------------------------------------------- RSwrtHexNibble ; currently only displays 0..9, A..F ANDLW 0x0F ADDLW 0x06 ; is it A..F, if so trigger a digit overflow SKPNDC ADDLW 7; subtract 10, then add 'A'-'0' ADDLW 0x30-6 ; Subtract extra 6 added to cause DC MOVWF RSout GOTO RStxChar RStxChar ; ; Output Start Bit ; Start bit is low, data bits are inverted ; movwf RStxTemp comf RStxTemp,f BCF PORT_RS232,RS232tx ; Make RS232 pin an ouput while transmitting character BANKSEL TRIS_RS232 BCF TRIS_RS232,RS232tx BANKSEL PORT_RS232 ; 1200 baud output ; move the char into RStxtemp, it is destroyed. ;Start Bit BSF PORT_RS232,RS232tx call RSdelayBit movlw 8 movwf RSloopCnt RStxCharLp1 ; After start bit, which is 1, then test each bit ; I need to set PA:0 to same as LSB RStxTemp ; this compares PA:0 with RStxTemp so see if it needs toggling ; The xorwf PORT_RS232,f causes the bit to be toggled if required. RRF RStxTemp,f movfw STATUS andlw 1 << C ; mask off bit addlw ( 1 << RS232tx) -1 ; shift bit by using a ripple carry xorwf PORT_RS232,W ; Doeas output need toggling ? andlw 1 << RS232tx ; Mask off output pin xorwf PORT_RS232,f ; Toggle output pin if needed call RSdelayBit ; delay bit decfsz RSloopCnt,f goto RStxCharLp1 BCF PORT_RS232,RS232tx call RSdelayBit ; apply stop bit ; Make RS232 pin an input so that main loop can test for start bit BANKSEL TRIS_RS232 BSF TRIS_RS232,RS232tx BANKSEL PORT_RS232 RETURN ; timing functions to delay serial routines for a bit or half bit. RSdelayHalfBit MOVLW 0x1D ; shorten delay as edge detector takes about 22 us for 4800 baud GOTO RSdelayBit0 RSdelayBit NOP MOVLW 0x40 ; for 4800 baud RSdelayBit0 MOVWF RSdelayCnt RSdelayBit1 DECFSZ RSdelayCnt,f ; 1 GOTO RSdelayBit1 ; 2 clk CLRWDT RETURN ;-------------------------------------------------------------------------- ; Sec 5.7 Serial Output Format Routines ;-------------------------------------------------------------------------- RSasciiToNibble MOVWF RSin ; if 0..1 then 0x30 to 0x39 ; if A..F then 0x41 to 0x46 ; if a..f then 0x61 to 0x66 ; test if bit 4 set and assume a letter or number BTFSS RSin,4 ADDLW 0x09 ; letter so add 9 ANDLW 0x0F ; mask of nibble return ;-------------------------------------------------------------------------- ; Sec 5.8 Serial Input Buffer Routine ;-------------------------------------------------------------------------- ; take serial input CAADD and put into buffer ; if char id ; the do command ; if char is CR reset buffer pointer ; if buff end then reset buff pointer RSipbuffStart EQU RScmd RSipbuffEnd EQU RSterminator RSbuffInput MOVWF RSin ; look for line feed and reset buff cnt ADDLW -0x0D BNZ RSbuffInput1 MOVLW RSipbuffStart MOVWF RSipBuffCnt RETURN RSbuffInput1 ; end of line command - do command ADDLW -';'+0x0D BNZ RSbuffInput2 GOTO RSbuffInputProcess RSbuffInput2 ; Store the current time into the next register. MOVFW RSipBuffCnt MOVWF FSR MOVFW RSin MOVWF INDF INCFSZ RSipBuffCnt,f MOVFW RSipBuffCnt ADDLW -(RSipbuffEnd+1) ; Check if the end of memory SKPZ GOTO RSbuffInputEnd1 MOVLW RSipbuffStart MOVWF RSipBuffCnt ; reset cursor MOVLW 0x0D CALL RStxChar RETURN RSbuffInputProcess MOVLW RSipbuffStart MOVWF RSipBuffCnt MOVFW RSAa ; if 0..1 then 0x30 to 0x39 ; if A..F then 0x41 to 0x46 ; if a..f then 0x61 to 0x66 ; test if bit 4 set and assume a letter or number BTFSS RSAa,4 ADDLW 0x09 ; letter so add 9 ANDLW 0x0F ; mask of nibble MOVWF RSin SWAPF RSin,F MOVFW RSaA BTFSS RSaA,4 ADDLW 0x09 ; letter so add 9 ANDLW 0x0F ; mask of nibble ADDWF RSin,w MOVWF RSaddr MOVFW RSDd BTFSS RSDd,4 ADDLW 0x09 ; letter so add 9 ANDLW 0x0F ; mask of nibble MOVWF RSin SWAPF RSin,F MOVFW RSdD BTFSS RSdD,4 ADDLW 0x09 ; letter so add 9 ANDLW 0x0F ; mask of nibble ADDWF RSin,w MOVWF RSdata ; CALL RStxChar ; got to end of buffer so process. does not allow for backspace ; Write to file register MOVLW -'w' ADDWF RScmd,w ; test to see if command is s, if so save into register. bnz RSbuffInput3 MOVFW RSaddr MOVWF FSR MOVFW RSdata MOVWF INDF MOVLW '*' CALL RStxChar GOTO RSbuffInputEnd RSbuffInput3 ; put octet in EEPROM MOVLW -'p' ADDWF RScmd,w ; test to see if command is s, if so save into register. bnz RSbuffInput4 MOVFW RSaddr CALL EEsetAddr BANKSEL RSdata MOVFW RSdata CALL EEwrt MOVFW RSdata MOVWF INDF MOVLW '*' CALL RStxChar GOTO RSbuffInputEnd RSbuffInput4 ; read from file register MOVLW -'r' ADDWF RScmd,w ; test to see if command is s, if so save into register. bnz RSbuffInput5 MOVFW RSaddr MOVWF FSR MOVFW INDF MOVWF RSin RSbuffInput4display MOVLW '=' CALL RStxChar SWAPF RSin,w CALL RSwrtHexNibble MOVFW RSin CALL RSwrtHexNibble GOTO RSbuffInputEnd RSbuffInput5 ; get from EEPROM register MOVLW -'g' ADDWF RScmd,w ; test to see if command is s, if so save into register. bnz RSbuffInput6 MOVFW RSaddr CALL EEread MOVWF RSin GOTO RSbuffInput4display RSbuffInput6 ; Initilize PWM MOVLW -'f' ADDWF RScmd,w ; test to see if command is s, if so save into register. bnz RSbuffInput7 CALL PWinit; MOVLW '*' CALL RStxChar GOTO RSbuffInputEnd RSbuffInput7 RSbuffInputEnd MOVLW 0x0D CALL RStxChar MOVLW 0x0A CALL RStxChar RSbuffInputEnd1 return ;-------------------------------------------------------------------------- ; Sec 5.9 Initilization code - ;-------------------------------------------------------------------------- INinit ; Enable Interupts MOVLW H'00' MOVWF INTCON CLRF PORT_RS232 ;Initialize PORT_RS232 by setting ;output data latches ifdef pic12F675 ; get the Oscillator calibration ;MOVLW 0x6C ; load the Calib BSF STATUS,RP0 CALL OscCalValue MOVWF OSCCAL BANKSEL CMCON MOVLW 0X07 ;Turn comparators off and MOVWF CMCON ;enable pins for I/O BANKSEL ANSEL CLRF ANSEL endif ifdef pic16F628 BANKSEL CMCON MOVLW 0X07 ;Turn comparators off and MOVWF CMCON ;enable pins for I/O endif ifdef pic16F876 ;make AtoD inputs digital BANKSEL ADCON1 MOVLW 0X07 ;Turn comparators off and MOVWF ADCON1 ;enable pins for I/O endif banksel TRISB MOVLW 0XF0 MOVWF TRISB BSF TRIS_RS232, RS232tx ; Make PORT_RS232 3:0 INPUTS. banksel RSipbuffStart ; reset input buffer MOVLW RSipbuffStart MOVWF RSipBuffCnt ; Change Prescaler CLRWDT ; Configure Tmr 0 BSF STATUS,RP0 ; Set up prescaller for 8192 / 16 = 512 ticks perseconds. MOVLW 0x0 + 2 ; For Tmr0 0=/2, 1=/4, 2=/8,3=/16 MOVWF OPTION_REG BCF STATUS,RP0 ifdef buildPWM ; Configure Tmr 1 MOVLW 0x0 | 1<<TMR1ON | 3 <<T1CKPS0 MOVWF T1CON CLRF OSxh CLRF OSxl CLRF OSyh CLRF OSyl MOVLW 0x1f MOVWF OSxhStart CLRF OSxlStart MOVLW 0x01 MOVWF OSloops MOVLW 0x40 MOVWF OSoffset endif CLRF DoTimeSlice CLRF IPbuttonEvent CLRF IPbuttonEventUp return INsayHello ; print out power on message MOVLW 0x0D CALL RStxChar MOVLW 0x0A CALL RStxChar MOVLW 'S' CALL RStxChar MOVLW 'R' CALL RStxChar MOVLW 0x0D CALL RStxChar MOVLW 0x0A CALL RStxChar return ;-------------------------------------------------------------------------- ; Sec 5.10 EEprom Routines for 16F628 ;-------------------------------------------------------------------------- EEread ; w contains address banksel EEADR MOVWF EEADR BSF EECON1,RD MOVFW EEDATA banksel 0 RETURN EEsetAddr banksel EEADR MOVWF EEADR RETURN EEwrt ; blocking, EEADR and EEDATA set up. ; BSF STATUS,RP0 banksel EEDATA MOVWF EEDATA BCF INTCON,GIE BCF EECON1,EEIF BSF EECON1,WREN MOVLW 0x55 MOVWF EECON2 MOVLW 0xAA MOVWF EECON2 BSF EECON1,WR ; Now wait for EEwrt to finish write EEwaitForWrt ; block until EEPROM write has finished. BCF EECON1,WREN ; disable EROM BTFSC EECON1,WR GOTO EEwaitForWrt BCF EECON1,EEIF ; EEPROM finished ; BCF STATUS,RP0 banksel 0 RETURN ;-------------------------------------------------------------------------- ; Sec 5.11 Routines to set up PWM on 16F628 ;-------------------------------------------------------------------------- PWinit ; set up the PWM ifdef buildPWM ; Move the PWM period into PR2 MOVLW 0 CALL EEread BANKSEL PR2 MOVWF PR2 MOVLW 0 MOVWF TRISB MOVLW 1 CALL EEread BANKSEL CCPR1L MOVWF CCPR1L MOVLW 1 << TMR2ON MOVWF T2CON BANKSEL CCP1CON MOVLW 1<< CCP1X | 1<< CCP1Y | ( .12 << CCP1M0 ) MOVWF CCP1CON ; ; init SHM sinewave generator. ; MOVFW OSxhStart MOVWF OSxh MOVFW OSxlStart MOVWF OSxl CLRF OSyh CLRF OSyl endif RETURN ;-------------------------------------------------------------------------- ; Sec 6.0 Interrupt Routines ;-------------------------------------------------------------------------- Intrtn RETFIE ;-------------------------------------------------------------------------- ; Program End ;-------------------------------------------------------------------------- ifdef pic12F675 org 0x3FD RETLW 0x6C RETLW 0x6C OscCalValue RETLW 0x6C endif LastProgWord ;-------------------------------------------------------------------------- ; Sec 7.0 EEPROM data ;-------------------------------------------------------------------------- ORG 0x2100 ; first 2 on and off are general ones DE .100,.50 ; 4 cblock LastVar endc END