;+------------------------------------------------------------------------+ ;| PIC16F84 controlled AD9851 DDS unit for universal generator | ;|------------------------------------------------------------------------| ;| MOUSE opto sensor at RA3 and RA4 | ;|------------------------------------------------------------------------| ;| LCD display in 4 bite, high nibble mode at RB4..RB7, control RA0..RA2 | ;|------------------------------------------------------------------------| ;| DDS controlled by RA0,RA1 and RB3 | ;|------------------------------------------------------------------------| ;| Band is read from RB0..RB2 | ;|------------------------------------------------------------------------| ;| (C) Peter Halicky, OM3CPH, Bratislava, Slovakia, Europe...;-) | ;| Contact: halicky@minv.sk www.qsl.net/~om3cph | ;+------------------------------------------------------------------------+ include include ;-------------------------------------------------------------------------- org 0 Start clrf STATUS ; Do initialization, Select bank 0 clrf INTCON ; Clear int-flags, Disable interrupts clrf PCLATH ; Keep in lower 2KByte clrf NUM0 clrf NUM1 clrf NUM2 clrf NUM3 clrf NUM4 clrf NUM5 clrf NUM6 clrf ResB clrf LowB clrf MidB clrf HigB movlw 0FFh movwf BAND ; set nonsense band value ;----------- IF Shift definition ------------------------------------------ movlw b'00000001' ; set IF shift registers movwf SHIFT0 ; 1=Add IF to 1.9 MHz movlw b'00000001' ; 1=Add IF to 3.5 MHz movwf SHIFT1 movlw b'00000001' ; 1=Add IF to 7 MHz movwf SHIFT2 movlw b'00000001' ; 1=Add IF to 14 MHz movwf SHIFT3 movlw b'00000001' ; 1=Add IF to 21 MHz movwf SHIFT4 movlw b'00000000' ; Bite[7]=1 change numbers movwf SHIFT5 ; 0=Sub IF movlw b'00000000' movwf SHIFT6 movlw b'00000000' movwf SHIFT7 ;-------------------------------------------------------------------------- bsf STATUS,RP0 movlw b'00011000' ; RA0..RA2 outputs movwf TRISA ; RA3,RA4 input movlw b'11110111' ; RB3 output, rest inputs movwf TRISB bsf OPTION_REG,NOT_RBPU ; Disable PORTB pull-ups clrwdt bcf STATUS,RP0 ; ; Initilize LC-Display Module ; Busy-flag is not yet valid clrf PORTA ; ALL PORT output should output Low. ; Initilize the LCD Display Module clrf PORTB ; ALL PORT output should output Low bcf PORTA,E ; Clear all controll lines bcf PORTA,RS bcf PORTA,R_W movlw DELAY15000 ; Wait for 15ms for LCD to get powered up movwf R1 clrf R2 LCycle decfsz R2,F goto LCycle ; 3*256 decfsz R1,F ; 3*256+1 goto LCycle ;(3*256+2)*R1=770*R1 in procesor cycles ;+---------------------------------------------------------------------+ ;| Initialization of LCD display | ;+---------------------------------------------------------------------+ movlw 0x0F andwf PORTB,F ; Clear the upper nibble movlw 0x030 ; Command for 4-bit interface high nibble iorwf PORTB,F ; Send data to LCD bsf STATUS,RP0 ; Select Register page 1 movlw 0x0F andwf TRISB,W movwf TRISB ; Set Port for output bcf STATUS,RP0 ; Select Register page 0 bsf PORTA,E ; Clock the initalize command to LCD module bcf PORTA,E movlw DELAY4100 ; Delay for at least 4.1ms before continuing movwf R1 clrf R2 LCycle2 decfsz R2,F goto LCycle2 ; 3*256 decfsz R1,F ; 3*256+1 goto LCycle2 ;(3*256+2)*R1=770*R1 in procesor cycles bsf PORTA,E ; Clock the initalize command to LCD module bcf PORTA,E movlw DELAY100 ; Wait for 100 us movwf R1 clrf R2 LCycle3 decfsz R2,F goto LCycle3 ; 3*256 decfsz R1,F ; 3*256+1 goto LCycle3 ;(3*256+2)*R1=770*R1 in procesor cycles movlw 0x0F andwf PORTB,F ; Clear the upper nibble movlw 020h ; Command for 4-bit interface high nibble iorwf PORTB,F ; Send data to LCD bsf PORTA,E ; Clock the initalize command to LCD module bcf PORTA,E movlw 0x028 ; 4 bits, 2 lines, 5x7 Font call PutCMD movlw B'00001000'; disp.off, curs.off, no-blink call PutCMD movlw 1 ; LCD clear call PutCMD movlw B'00001100'; disp.on, curs.off call PutCMD movlw B'00000110'; auto-inc (shift-cursor) call PutCMD ;+---------------------------------------------------------------------+ ;| Set DDS to serial mode | ;+---------------------------------------------------------------------+ movlw 010h movwf HigB call SetDDS call Delay call SetDDS call Delay clrf HigB goto Entry ;+---------------------------------------------------------------------+ ;| Tables of 3 bytes constants | ;+---------------------------------------------------------------------+ ;| Increment/decrement values | ;+---------------------------------------------------------------------+ Decades addwf PCL,F ; W + PCL -> PCL include ; table is included for convenience ;+---------------------------------------------------------------------+ ;| Table of the middle band frequencies, everybody can feely set | ;| any other values | ;+---------------------------------------------------------------------+ BandTable addwf PCL,F ; W + PCL -> PCL retlw 0 ; 1. retlw 9 ; 1.9 MHz retlw 1 retlw 0 retlw 5 ; 2. retlw 7 ; 3.75 MHz retlw 3 retlw 0 retlw 5 ; 3. retlw 0 ; 7.05 MHz retlw 7 retlw 0 retlw 5 ; 4. retlw 1 ; 14.15MHz retlw 4 retlw 1 retlw 5 ; 5. retlw 1 ; 21.15MHz retlw 1 retlw 2 retlw 0 ; 6. retlw 1 ; 28.10 retlw 8 retlw 2 retlw 0 ; 7. retlw 2 ; 28.20 retlw 8 retlw 2 retlw 0 ; 8. retlw 3 ; 28.30 MHz retlw 8 retlw 2 ;+---------------------------------------------------------------------+ ;| Delay for DDS initialization | ;+---------------------------------------------------------------------+ Delay clrf R1 clrf R2 LCcl decfsz R2,F goto LCcl ; 2+3*256 decfsz 1,F ; 2+3*256 goto LCcl ;(3*256+2)*256 procesor cycles retlw 0 ; 196 352 procesor cycles ;+---------------------------------------------------------------------+ ;| LCD Module Subroutines | ;+---------------------------------------------------------------------+ ;| Busy | ;+---------------------------------------------------------------------+ ;| Returns when LCD busy-flag is inactive | ;+---------------------------------------------------------------------+ Busy ; return bsf STATUS,RP0 ; Select Register page 1 movlw 0xF0 ; Set port to input iorwf TRISB,W ; Only set upper half of port movwf TRISB bcf STATUS,RP0 ; Select Register page 0 bcf PORTA,RS ; Set LCD for Command mode bsf PORTA,R_W ; Setup to read busy flag bsf PORTA,E ; Set E high bcf PORTA,E ; Set E low movf PORTB,W ; Read upper nibble busy flag, DDRam address andlw 0xF0 ; Mask out lower nibble movwf TEMP bsf PORTA,E ; Toggle E to get lower nibble bcf PORTA,E swapf PORTB,W ; Read lower nibble busy flag, DDRam address andlw 0x0F ; Mask out upper nibble iorwf TEMP,W ; Combine nibbles btfsc TEMP,7 ; Check busy flag, high = busy goto Busy ; If busy, check again bcf PORTA,R_W bsf STATUS,RP0 ; Select Register page 1 movlw 0x0F andwf TRISB,W movwf TRISB ; Set Port for output bcf STATUS,RP0 ; Select Register page 0 return ;+---------------------------------------------------------------------+ ;| PutCHAR | ;+---------------------------------------------------------------------+ ;| Sends character to LCD, Required character must be in W | ;+---------------------------------------------------------------------+ PutCHAR movwf CHAR ; Character to be sent is from W saved call Busy ; Wait for LCD to be ready ; Busy routine sets PORTB adequately movlw 0x0F andwf PORTB,F ; Clear the upper nibble movf CHAR,W andlw 0xF0 ; Get upper nibble iorwf PORTB,F ; Send data to LCD bcf PORTA,R_W ; Set LCD to write bsf PORTA,RS ; Set LCD to data mode bsf PORTA,E ; toggle E for LCD bcf PORTA,E movlw 0x0F andwf PORTB,F ; Clear the upper nibble swapf CHAR,W andlw 0xF0 ; Get lower nibble iorwf PORTB,F ; Send data to LCD bsf PORTA,E ; toggle E for LCD bcf PORTA,E return ;+---------------------------------------------------------------------+ ;| PutCMD | ;+---------------------------------------------------------------------+ ;| Sends command to LCD, Required command must be in W | ;+---------------------------------------------------------------------+ PutCMD movwf CHAR ; Command to be sent is from W saved call Busy ; Wait for LCD to be ready movlw 0x0F andwf PORTB,F ; Clear the upper nibble movf CHAR,W andlw 0xF0 ; Get upper nibble iorwf PORTB,F ; Send data to LCD bcf PORTA,R_W ; Set LCD to write bcf PORTA,RS ; Set LCD to command mode bsf PORTA,E ; toggle E for LCD bcf PORTA,E movlw 0x0F andwf PORTB,F ; Clear the upper nibble swapf CHAR,W andlw 0xF0 ; Get lower nibble iorwf PORTB,F ; Send data to LCD bsf PORTA,E ; toggle E for LCD bcf PORTA,E return ;+---------------------------------------------------------------------+ ;| End of LCD Module Subroutines | ;+---------------------------------------------------------------------+ ;| Numeric routines | ;+---------------------------------------------------------------------+ ;| Addition of two 4-byte numbers, takes CARRY into account... | ;| | ;| ResB + R_B -> ResB | ;| LowB + L_B -> LowB | ;| MidB + M_B -> MidB | ;| HigB + H_B -> HigB | ;| | ;+---------------------------------------------------------------------+ Add32 clrf TEMP ; prepare storage for C movf R_B,W ; in W is lowest byte of 1. number bcf STATUS,C ; clear C addwf ResB,F ; R_B + ResB -> ResB btfss STATUS,C ; goto AddSecond ; if not overflowed then jump bcf STATUS,C ; clear C movlw 1 ; carry to higher order addwf LowB,F ; increment LowB btfss STATUS,C goto AddSecond ; if not overflowed then jump bcf STATUS,C movlw 1 addwf MidB,F ; Increment MidB btfss STATUS,C goto AddSecond ; if not overflowed then jump bcf STATUS,C movlw 1 addwf HigB,F ; Increment HigB btfss STATUS,C goto AddSecond ; if not overflowed then jump bsf TEMP,C ; save overflow bite AddSecond movf L_B,W ; into W 2nd byte bcf STATUS,C addwf LowB,F ; L_B + LowB -> LowB btfss STATUS,C goto AddThird bcf STATUS,C movlw 1 addwf MidB,F ; Increment MidB btfss STATUS,C goto AddThird bcf STATUS,C movlw 1 addwf HigB,F ; Increment HigB btfss STATUS,C goto AddThird bsf TEMP,C AddThird movf M_B,W ; into W 3rd byte bsf STATUS,C addwf MidB,F ; M_B + MidB -> MidB, btfss STATUS,C goto AddForth bcf STATUS,C movlw 1 addwf HigB,F ; Increment HigB btfss STATUS,C goto AddForth bsf TEMP,C AddForth movf H_B,W ; into W highest byte bsf STATUS,C addwf HigB,F ; H_B + HigB -> HigB, btfss STATUS,C goto ClearCF bsf STATUS,C goto Add32End ClearCF rrf TEMP,C ; C -> STATUS Add32End retlw 0 ;+---------------------------------------------------------------------+ ;| Substraction of two 4-byte numbers, it takes CARRY into account... | ;| | ;| ResB - R_B -> ResB | ;| LowB - L_B -> LowB | ;| MidB - M_B -> MidB | ;| HigB - H_B -> HigB | ;| | ;| If result is negative it return with C set.... | ;+---------------------------------------------------------------------+ Sub32 clrf TEMP ; prepare to store C movf R_B,W ; lowest byte of 2nd number bsf STATUS,C ; set C subwf ResB,F ; ResB - R_B -> ResB ; if result<0 -> CF=0 btfsc STATUS,C ; goto SubSecond ; if C=1 continue substraction bsf STATUS,C movlw 1 subwf LowB,F ; decrement LowB btfsc STATUS,C goto SubSecond bsf STATUS,C movlw 1 subwf MidB,F ; decrement MidB btfsc STATUS,C goto SubSecond bsf STATUS,C movlw 1 subwf HigB,F ; decrement HigB btfsc STATUS,C goto SubSecond bsf TEMP,C ; set C (bit 0) SubSecond movf L_B,W ; 2nd byte of 2nd number into W bsf STATUS,C ; set C for further testing subwf LowB,F ; LowB - L_B -> LowB btfsc STATUS,C goto SubThird ; if C not changed continue bsf STATUS,C movlw 1 subwf MidB,F ; decrement MidB btfsc STATUS,C goto SubThird bsf STATUS,C movlw 1 subwf HigB,F ; decrement HigB btfsc STATUS,C goto SubThird bsf TEMP,C ; save C SubThird movf M_B,W ; 3rd byte of 2nd number in W bsf STATUS,C subwf MidB,F ; MidB - M_B -> MidB btfsc STATUS,C goto SubForth bsf STATUS,C movlw 1 subwf HigB,F ; decrement HigB btfsc STATUS,C goto SubForth bsf TEMP,C ; set C SubForth movf H_B,W ; 4th byte of 2nd number in W bsf STATUS,C subwf HigB,F ; HigB - H_B -> HigB btfsc STATUS,C goto ClrCF bsf STATUS,C ; set C goto Sub32End ClrCF rrf TEMP,C ; C -> STATUS Sub32End retlw 0 ;+---------------------------------------------------------------------+ ;| Addition of accumulator to 7-byte decimal number, takes CARRY | ;| into account. INDEX contains position. | ;| | ;| 10E6*D6+10E5*D5+10E4*D4+10E3*D3+10E2*D2+10*D1+D0 | ;| + W | ;| ------------------------------------------------- | ;| 10E6*D6+10E5*D5+10E4*D4+10E3*D3+10E2*D2+10*D1+D0 | ;| | ;+---------------------------------------------------------------------+ DecADD movwf TEMP ; push W (W comes with number to be added) movf INDEX,W ; INDEX contains pointer to decimal number movlw NUM0-1 ; NUM0 -> W addwf INDEX,W ; NUM0 + INDEX -> W movwf FSR ; NUM0 + INDEX -> FSR movf INDF,W ; decimal number to W movwf Help ; Help now contains decimal number movf TEMP,W ; pop W addwf Help,F ; Help + W -> Help bsf STATUS,C ; prepare for substraction test movlw 9 movwf TEMP ; 9 to TEMP movf Help,W ; Help to W subwf TEMP,W ; 9 - Help -> W btfss STATUS,C ; if Help was < 10 then C=0 (negative result) goto Proceed movf Help,W ; prepare Help for writting movwf INDF ; writte it to appropriate position return ; return from procedure Proceed movlw .10 subwf Help,W ; Help - 10 -> W movwf INDF ; writte it to appropriate position incf INDEX,F ; increment pointer movlw NUM0+7 ; prepare for test of position bsf STATUS,C subwf INDEX,W ; INDEX - 7 -> W btfsc STATUS,C ; if INDEX < 7 then continue return ; else return from procedure movlw 1 ; overflowed bite to W goto DecADD ; process bite ;+---------------------------------------------------------------------+ ;| Substraction of accumulator from 7-byte decimal number, takes CARRY | ;| into account... | ;| | ;| 10E6*D6+10E5*D5+10E4*D4+10E3*D3+10E2*D2+10*D1+D0 | ;| - W | ;| ------------------------------------------------ | ;| 10E6*D6+10E5*D5+10E4*D4+10E3*D3+10E2*D2+10*D1+D0 | ;| | ;+---------------------------------------------------------------------+ DecSUB movwf TEMP ; push W (W comes with number to be substractedd) movf INDEX,W ; INDEX contains pointer to decimal number movlw NUM0-1 ; NUM0 -> W addwf INDEX,W ; NUM0 + INDEX -> W movwf FSR ; NUM0 + INDEX -> FSR movf INDF,W ; decimal number to W movwf Help ; Help now contains decimal number movf TEMP,W ; pop W bsf STATUS,C ; prepare for substraction subwf Help,W ; Help - W -> W btfss STATUS,C ; if result is negative then C=0 goto Makeit movwf INDF ; write W to appropriate position return ; return from procedure Makeit movlw .10 addwf Help,F movf TEMP,W ; pop W subwf Help,W ; Help - TEMP -> W movwf INDF ; write it to appropriate position incf INDEX,F ; increment pointer movlw NUM0+7 ; prepare for test of position bsf STATUS,C subwf INDEX,W ; INDEX - 7 -> W btfsc STATUS,C ; if INDEX < 7 then continue return ; else return from procedure movlw 1 ; underflowed bite to W goto DecSUB ; process bite ;+---------------------------------------------------------------------+ ;| SendIt | ;+---------------------------------------------------------------------+ ;| Procedure to send one byte in W to DDS. | ;+---------------------------------------------------------------------+ SendIt ; return movwf TEMP ; PUSH W clrf Count ; now starts sending procedure NextBite bcf STATUS,C ; prepare C to accept bite rrf TEMP,F ; rotate right bite to C ; (0th bite to C) clrf Help rlf Help,F ; C to 0th bite of Help movf Help,W nop movwf PORTA ; send bite, bsf PORTA,W_CLK nop nop nop nop bcf PORTA,W_CLK ; send clock incf Count,F movlw 8 bcf STATUS,Z subwf Count,W ; Count - 8 -> W btfss STATUS,Z goto NextBite retlw 0 ;+---------------------------------------------------------------------+ ;| SetDDS | ;+---------------------------------------------------------------------+ ;| Procedure to send one tuning word ResB..HigB to DDS | ;+---------------------------------------------------------------------+ SetDDS movf ResB,W ; 5 bytes are sent to DDS call SendIt movf LowB,W call SendIt movf MidB,W call SendIt movf HigB,W call SendIt movlw 0 ; 0 for 9850, 1 for 9851 if 6*CLOCK call SendIt ; is requited clrf PORTA nop bsf PORTB,FQ_UD ; send UPDATE FREQ command nop nop nop nop bcf PORTB,FQ_UD clrf Semaphore clrf PORTA clrf Help retlw 0 ;+---------------------------------------------------------------------+ ;| Get Band | ;+---------------------------------------------------------------------+ ;| RB0..RB2 inputs - Band selector is connected to RB0..RB2 | ;| According their value it sets BAND and fills middle band frequency | ;| into NUM0..NUM6 and if new band is detected it returns 1 in W. | ;+---------------------------------------------------------------------+ GetBand movf PORTB,W ; read RB andlw b'00000111' ; filter out unsignificant bites movwf Help ; save result, in Help is BAND NUMBER incf Help,F ; get real Band value movf Help,W bcf STATUS,Z ; band changed? subwf BAND,W ; BAND - W -> W btfsc STATUS,Z ; jump if YES retlw 0 ; no change in band movf Help,W ; new band is set! movwf BAND ; set new value of the BAND movwf TEMP bcf STATUS,C ; clear C rlf TEMP,F ; BANDx4 rlf TEMP,F decf TEMP,F movf TEMP,W ; get new frequency call BandTable ; fill out NUM0..NUM6 movwf NUM6 decf TEMP,F movf TEMP,W call BandTable movwf NUM5 decf TEMP,F movf TEMP,W call BandTable movwf NUM4 decf TEMP,F movf TEMP,W call BandTable movwf NUM3 clrf NUM2 clrf NUM1 clrf NUM0 retlw 1 ; indicate change in band ;+---------------------------------------------------------------------+ ;| Counter | ;+---------------------------------------------------------------------+ ;| It increments by each run through GetMouse routine provided the | ;| Semaphore[0] bite is set. | ;| It uses T1 and T2 registers | ;+---------------------------------------------------------------------+ Counter bsf STATUS,Z ; if T1 is FFh then next increment movlw 0FFh ; will give ZERO and higher byte should subwf T1,W ; be incremented (carry) btfss STATUS,Z ; if smaller, increment T1 goto GetCarry ; else process higher byte bsf STATUS,Z ; before incrementation test wheather movlw 0FFh ; both counter bytes aren't full subwf T2,W btfsc STATUS,Z ; if so, do nothing incf T1,F ; otherwise increment T1 return GetCarry bsf STATUS,Z ; if T2 is smaller than FF movlw 0FFh subwf T2,W btfsc STATUS,Z goto Finish incf T2,F clrf T1 Finish retlw 0 ;+---------------------------------------------------------------------+ ;| Test | ;+---------------------------------------------------------------------+ ;| It tests content of the counter. According its value it returns | ;| 1, 2 or 4 in W, which means increase/decrease the frequency | ;| by 10, 100 or 10000 Hz | ;| | ;| The breakpoints are 1 ms and 10 ms | ;| It equals T1=.50, T2=0 and T1=x, T2=2 (approximately, 10MHx Xtal) | ;+---------------------------------------------------------------------+ Test bsf STATUS,C movlw 3 subwf T2,W ; T2 - 3 -> W btfsc STATUS,C ; if T2 in [0..2] => C=0 retlw 1 ; else C=1, use SLOW bcf STATUS,Z movf T2,W btfss STATUS,C ; if T2 in [1,2] => Z=0 retlw 3 ; else (T1=0) use EVERAGE bsf STATUS,C movlw .51 subwf T1,W ; T1 - 51 -> W btfsc STATUS,C ; if T1 in [0..50] => C=0 retlw 3 ; use EVERAGE retlw 5 ; use FAST ;+---------------------------------------------------------------------+ ;| Get Mouse opto coupler signal | ;+---------------------------------------------------------------------+ ;| It tests bites RA3,4 and according their values it increments or | ;| decrements actual frequency, | ;| If no frequency change is needed it returns W=0, otherwise it | ;| returns W=1 | ;+---------------------------------------------------------------------+ GetMouse btfsc Semaphore,0 ; is Semaphore[0]=0? call Counter ; if yes increment Counter movf PORTA,W ; read RA nop movwf TEMP ; save result bcf STATUS,Z ; clear ZERO flag andlw b'00011000' ; clear unsignificant bites btfss STATUS,Z ; if 00 then try to set FLAG's 2nd bite goto TestDir ; else test for 10,11,01 bcf STATUS,Z ; clear ZERO flag movf Semaphore,W ; is Semaphore=0? (all bites=0) btfss STATUS,Z ; if YES than set Semaphore 0-th bite retlw 0 ; else do nothing bsf Semaphore,0 retlw 0 TestDir btfss Semaphore,0 ; if Semaphore's 0-th bite is set then continue retlw 0 ; else do nothing movlw b'00011000' bcf STATUS,Z ; prepare test for 11 subwf TEMP,W ; TEMP - W -> W btfss STATUS,Z ; if 11 then do nothing goto UpDown ; else test 01 or 10 retlw 0 UpDown btfss TEMP,4 ; if Up (=10) increase frequency goto IsDown ; else it must be Down (=01) call Test ; movlw 2 movwf INDEX movlw 1 clrf T1 clrf T2 call DecADD ; increase frequency retlw 1 ; frequency update is needed IsDown call Test ; movlw 2 movwf INDEX movlw 1 clrf T1 clrf T2 call DecSUB ; decrease frequency retlw 1 ; frequency update is needed ;|---------------------------------------------------------------------| ;| Entry point for the main cycle | ;|---------------------------------------------------------------------| ;+---------------------------------------------------------------------+ ;| Registers NUM0..NUM6 are filled with values - ready to be displayed | ;+---------------------------------------------------------------------+ Entry movlw 6 movwf NUMINDEX movlw LINE0 iorlw 080h ; Position cursor leftmost at the 1st line call PutCMD NUMCycle movlw NUM0 ; NUM0 -> W addwf NUMINDEX,W ; NUM1 + NUMINDEX -> W movwf FSR ; NUM1 + NUMINDEX -> FSR bcf STATUS,Z ; prepare for leading ZERO check movf INDF,W ; NUM(0..6) -> W btfsc STATUS,Z ; goto ClearZero iorlw 030h ; set ASCII value call PutCHAR ; Display character goto TestDot ClearZero movlw 6 ; test for first position bsf STATUS,Z subwf NUMINDEX,W btfss STATUS,Z goto ZeroOK movlw ' ' ; this is instead '0' call PutCHAR ; Display character goto TestDot ZeroOK movlw '0' ; this is instead '0' call PutCHAR ; Display character TestDot movlw 5 ; test for decimal point bsf STATUS,Z subwf NUMINDEX,W btfss STATUS,Z goto NoDot movlw ',' ; this can be ' ' or ',' ...... call PutCHAR ; Display character NoDot decfsz NUMINDEX,F goto NUMCycle ; continue with next number movlw NUM0 ; NUM0 -> W movwf FSR ; NUM0 -> FSR movf INDF,W ; [NUM0] -> W iorlw 030h ; set ACSII value call PutCHAR ; Display character movlw LINE1 ; continue at right half of display iorlw 080h ; Function set call PutCMD ; Position cursor leftmost on first line movlw ' ' call PutCHAR ; Display character movlw 'M' call PutCHAR ; Display character movlw 'H' call PutCHAR ; Display character movlw 'z' call PutCHAR ; Display character movlw LINE0 iorlw 080h ; Function set call PutCMD ;+---------------------------------------------------------------------+ ;| Conversion of NUM0..NUM6 into DDS 4 byte tuning word | ;+---------------------------------------------------------------------+ ;| ResB,LowB,MidB and HigB should be filled according NUM0..NUM6 values| | ;| | ;| This procedure also adds or substracts IF from result according | ;| bite set in the SHIFT registers 1=Add 0=Sub | ;+---------------------------------------------------------------------+ movlw 7 ; Set position of decimal number movwf NUMINDEX ; to NUMINDEX clrf ResB ; clear main registers clrf LowB clrf MidB clrf HigB NextNumber movlw NUM0-1 ; NUM0 -> W (get memory address) addwf NUMINDEX,W ; NUM0 + NUMINDEX -> W movwf FSR ; W -> FSR movf INDF,W ; NUM(0..6) -> W bcf STATUS,Z movwf INDEX ; decimal number to INDEX movlw 0FFh andwf INDEX,W btfsc STATUS,Z ; if ZERO do nothing ... goto NextPos movf NUMINDEX,W movwf TEMP bcf STATUS,C rlf TEMP,F rlf TEMP,F ; multiply by 4 decf TEMP,F movf TEMP,W ; fill R_B...H_B with decades call Decades movwf H_B decf TEMP,F movf TEMP,W call Decades movwf M_B decf TEMP,F movf TEMP,W call Decades movwf L_B decf TEMP,F movf TEMP,W call Decades movwf R_B NextAdd call Add32 ; Dx times Add32 decade decfsz INDEX,F goto NextAdd NextPos decfsz NUMINDEX,F ; take next number goto NextNumber ;+---------------------------------------------------------------------+ ;| DDS send data sequence (ResB..HigB contain tuning word) | ;+---------------------------------------------------------------------+ DDS call SetDDS ;+---------------------------------------------------------------------+ ;| Ready to start interfaces checking | ;+---------------------------------------------------------------------+ Work call GetBand movwf Help btfsc Help,0 ; band is not changed goto Entry ; otherwise set new frequency call GetMouse movwf Help btfsc Help,0 ; no signal from optosensors goto Entry ; otherwise set new frequency goto Work ;+---------------------------------------------------------------------+ ;| End of the programme | ;+---------------------------------------------------------------------+ end