; MW transmitter based on an Si5351A PLL and PIC16F628 with LCD for frequency and wavelength ; UP and DN buttons, EEPROM for current frequency (index). There are 122 frequencies from 522 to 1602 kHz. ; Frequency step is 9 kHz (Europe/Asia). ; v0.0 210923 Start project, copy-paste from various previous projects ; v0.1 210924 Removed WDT, fixed data to Si5351A ; v0.2 210925 Buttons, FRINDX ; v0.3 210925 PLL Frequency lookup ; v0.4 210925 Frequency calculation and display ; v0.5 210925 Wavelength display ; v0.6 210925 EEPROM storing of frequency setting ; v1.0 210926 Release LIST P=16F628A, F=INHX8M #include <p16f628a.inc> __CONFIG _INTRC_OSC_NOCLKOUT & _WDT_OFF & _LVP_OFF & _CP_OFF ERRORLEVEL -302 ; remove message about using proper bank ; Equates RESET_V EQU 0x00 ; Address of RESET Vector ; Registers FLAGS EQU 0x20 ; Various flags LCDByte EQU 0x22 ; Byte to send to LCD TEMP1 EQU 0x23 ; Temp register TEMP2 EQU 0x24 ; Temp register d1 EQU 0x25 ; Delay register d2 EQU 0x26 ; Delay register I2CBUF EQU 0x27 ; Used for I2C data I2CCNT EQU 0x28 ; Used for I2C bitbanger FRINDX EQU 0x29 ; Frequency Index SCANCTR EQU 0x2A ; Scan speed counter EEBUF EQU 0x2B ; Used for writing a byte to EEPROM R26 EQU 0x2C ; Register 26 R27 EQU 0x2D ; Register 27 R29 EQU 0x2E ; Register 29 R30 EQU 0x2F ; Register 30 R32 EQU 0x32 ; Register 32 R33 EQU 0x33 ; Register 33 R44 EQU 0x44 ; Register 44 R45 EQU 0x45 ; Register 45 FREQ9 EQU 0x34 ; FRINDX+0x3A (58) FREQLO EQU 0x35 ; Actual frequency low byte FREQHI EQU 0x36 ; Actual frequency high byte FREQ0 EQU 0x37 ; units BCD value for frequency display FREQ1 EQU 0x38 ; tens BCD value for frequency display FREQ2 EQU 0x39 ; hundreds BCD value for frequency display FREQ3 EQU 0x3A ; thousands BCD value for frequency display WAVELO EQU 0x3B ; Wavelength units and tens (meters) WAVEHI EQU 0x3C ; Wavelength hundreds (meters) ; Defines #define SCL PORTB,0 ; I2C Clock #define SDA PORTB,1 ; I2C Data #DEFINE LCD_EN PORTB,2 #DEFINE LCD_RS PORTB,3 #DEFINE LCD_D4 PORTB,4 #DEFINE LCD_D5 PORTB,5 #DEFINE LCD_D6 PORTB,6 #DEFINE LCD_D7 PORTB,7 #DEFINE UP PORTA,3 ; Up button (active LOW) #DEFINE DN PORTA,4 ; Down button (active LOW) #define NAK FLAGS,1 ; Not Acknowledge after I2C byte #define SYSINIT FLAGS,2 ; Clear when system init of Si5351A has completed ;Macros BANK1: MACRO BSF STATUS,RP0 ENDM BANK0: MACRO BCF STATUS,RP0 ENDM ORG 0 GOTO START ORG 4 ; Interrupts ; Timer0 Interrupt Handler BCF INTCON,TMR0IF ; Clear TMR0 interrupt (every 58 ms) BTFSS DN ; DN pressed? GOTO WriteDN ; Yes BTFSS UP ; UP pressed? GOTO WriteUP ; Yes RETFIE WriteDN CALL LONGDLY ; Extra delay to catch short keypress MOVLW 0x0A MOVWF SCANCTR ; Preload Scan Speed Counter DNScanFast INCF SCANCTR,F ; Ensure scan test passes DNScanSlow DECF FRINDX,F MOVLW 0x79 ; Test for invalid index (>0x78) SUBWF FRINDX,W BTFSS STATUS,C ; Invalid value? GOTO $+3 ; No MOVLW 0x78 ; Handle rollover MOVWF FRINDX MOVFW FRINDX ; Get correct value for display CALL LOADPLL CALL FREQDISPLAY BTFSC DN ; DN still pressed? GOTO BTNExit ; Yes DNCont DECFSZ SCANCTR,F ; Scan speed fast? GOTO $+2 ; No GOTO DNScanFast DNSlow ; Slow scan speed in case of Autoscan to provide time for correct STOP operation CALL LONGDLY CALL LONGDLY GOTO DNScanSlow WriteUP CALL LONGDLY ; Extra delay to catch short keypress MOVLW 0x0A MOVWF SCANCTR ; Preload Scan Speed Counter UPScanFast INCF SCANCTR,F ; Ensure scan zero test passes UPScanSlow INCF FRINDX,F MOVLW 0x79 ; Test for index rollover SUBWF FRINDX,W BTFSC STATUS,C ; Invalid value? CLRF FRINDX ; Yes MOVFW FRINDX ; No CALL LOADPLL CALL FREQDISPLAY BTFSC UP ; UP pressed again? GOTO BTNExit ; Yes UPCont DECFSZ SCANCTR,F ; Scan speed fast? GOTO $+2 ; No GOTO UPScanFast UPSlow ; Slow scan speed in case of Autoscan to provide time for correct STOP operation CALL LONGDLY CALL LONGDLY GOTO UPScanSlow BTNExit CALL LONGDLY MOVFW FRINDX ; Get current index to store in EEPROM MOVWF EEBUF CLRW ; Point to EEPROM Address 0x00 CALL EEPROMWRITE ; Save index CLRF TMR0 BCF INTCON,TMR0IF ; Clear TMR0 interrupt just in case (extra debounce delay) RETFIE ; End interrupts ; Subroutines (I2C) I2CSTART BCF SDA CALL I2CDELAY BCF SCL CALL I2CDELAY RETURN I2CBYTE ; Sends byte in W MOVWF I2CBUF MOVLW 0x08 MOVWF I2CCNT NEXTBIT BCF STATUS,C ; Clear carry RLF I2CBUF,F ; Rotate MSB into carry BTFSC STATUS,C ; Carry clear? BSF SDA ; No, set SDA BTFSS STATUS,C ; Carry set? BCF SDA ; No, clear SDA CALL I2CDELAY BSF SCL ; Send clock CALL I2CDELAY BCF SCL ; Done clock DECFSZ I2CCNT,F GOTO NEXTBIT ; ACK handler BSF STATUS,RP0 ; Select Bank 1 BSF TRISB,1 ; Set SDA as input to float SDA line BCF STATUS,RP0 ; Select Bank 0 BSF NAK CALL I2CDELAY BSF SCL ; Solicit ACK CLRF I2CCNT TESTACK BTFSC SDA ; SDA pulled low? GOTO CONTACK ; No, continue testing for ACK until timeout (~20 ms) BCF NAK ; Clear NAK GOTO EXITACK ; Exit loop CONTACK DECFSZ I2CCNT,F GOTO TESTACK EXITACK BSF STATUS,RP0 ; Select Bank 1 BCF TRISB,1 ; Set SDA as output BCF STATUS,RP0 ; Select Bank 0 BTFSC NAK ; NAK handler GOTO START ; Timeout, no ACK, force reset BCF SCL CALL I2CDELAY RETURN I2CSTOP BCF SDA CALL I2CDELAY BSF SCL CALL I2CDELAY BSF SDA RETURN I2CDELAY NOP ; 8 us delay NOP NOP NOP RETURN LOADPLL MOVLW high R2627 ; PCLATH to first entry of table MOVWF PCLATH BCF STATUS,C RLF FRINDX,W ; Multiply FRINDX by 2 CALL R2627 MOVWF R26 BSF STATUS,C RLF FRINDX,W ; Multiply FRINDX by 2 and add 1 CALL R2627 MOVWF R27 MOVLW high R2930 ; PCLATH to first entry of table MOVWF PCLATH BCF STATUS,C RLF FRINDX,W ; Multiply FRINDX by 2 CALL R2930 MOVWF R29 BSF STATUS,C RLF FRINDX,W ; Multiply FRINDX by 2 and add 1 CALL R2930 MOVWF R30 MOVLW high R3233 ; PCLATH to first entry of table MOVWF PCLATH BCF STATUS,C RLF FRINDX,W ; Multiply FRINDX by 2 CALL R3233 MOVWF R32 BSF STATUS,C RLF FRINDX,W ; Multiply FRINDX by 2 and add 1 CALL R3233 MOVWF R33 MOVLW high R4445 ; PCLATH to first entry of table MOVWF PCLATH BCF STATUS,C RLF FRINDX,W ; Multiply FRINDX by 2 CALL R4445 MOVWF R44 BSF STATUS,C RLF FRINDX,W ; Multiply FRINDX by 2 and add 1 CALL R4445 MOVWF R45 MOVLW high wave ; PCLATH to first entry of table MOVWF PCLATH BCF STATUS,C RLF FRINDX,W ; Multiply FRINDX by 2 CALL wave MOVWF WAVEHI BSF STATUS,C RLF FRINDX,W ; Multiply FRINDX by 2 and add 1 CALL wave MOVWF WAVELO CALL I2CSTART MOVLW 0xC0 ; Address CALL I2CBYTE MOVLW 0x1A ; Register 26 CALL I2CBYTE MOVFW R26 ; Get Register 26 data CALL I2CBYTE MOVFW R27 ; Get Register 27 data CALL I2CBYTE CLRW ; Register 28 data is zero CALL I2CBYTE MOVFW R29 ; Get Register 29 data CALL I2CBYTE MOVFW R30 ; Get Register 30 data CALL I2CBYTE CLRW ; Register 31 data is zero CALL I2CBYTE MOVFW R32 ; Get Register 32 data CALL I2CBYTE MOVFW R33 ; Get Register 33 data CALL I2CBYTE CALL I2CSTOP CALL I2CSTART MOVLW 0xC0 ; Address CALL I2CBYTE MOVLW 0x2C ; Register 44 CALL I2CBYTE MOVFW R44 ; Get Register 44 data CALL I2CBYTE MOVFW R45 ; Get Register 45 data CALL I2CBYTE CALL I2CSTOP CALL I2CSTART MOVLW 0xC0 ; Address CALL I2CBYTE MOVLW 0xB1 ; Register 177 CALL I2CBYTE MOVLW 0x20 ; Register 177 data (Reset PLLA) CALL I2CBYTE CALL I2CSTOP RETURN ; Subroutines (EEPROM) EEPROMREAD ; W contains address to read, at return contains read data BANK1 ; Select Bank 1 MOVWF EEADR ; Data Memory Address to read from W BSF EECON1, RD ; EE Read MOVFW EEDATA ; W = EEDATA BANK0 ; Select Bank 0 RETURN EEPROMWRITE ; W contains address to write, data is in EEBUF BANK1 ; Select Bank 1 BSF EECON1, WREN ; Enable write BANKSEL EEADR ; Select Bank of EEADR MOVWF EEADR ; Data Memory Address to write BANKSEL EEBUF MOVFW EEBUF ; Data to write from buffer BANKSEL EEDATA MOVWF EEDATA ; Data Memory Value to write BANKSEL EECON2 ; Select Bank of EECON2 MOVLW 0x55 MOVWF EECON2 ; Write 55h MOVLW 0xAA MOVWF EECON2 ; Write AAh BSF EECON1, WR ; Set WR bit to begin write BCF EECON1, WREN ; Disable writes BANK0 ; Select BANK0 RETURN ; Subroutines (LCD) LCDPOS ; makes WREG the current LCD position BCF LCD_RS MOVWF LCDByte ; Valid values 0x80-0x8F, 0xC0-0xCF CALL LCDBYTE BSF LCD_RS CALL LONGDLY ; Needed for the LCD to process the command RETURN LCDCLR ; clears the entire display BCF LCD_RS ; Instruction mode MOVLW 0x01 MOVWF LCDByte CALL LCDBYTE BSF LCD_RS ; Character mode CALL LONGDLY ; Clearing the LCD takes ages, so a larger delay is needed RETURN LCDBYTE ; sends the byte in WREG to the LCD in 4bit fashion. Set LCD_RS as appropriate (0: instruction, 1: character) MOVWF LCDByte BCF LCD_D7 ; Clear data bits BCF LCD_D6 BCF LCD_D5 BCF LCD_D4 BTFSC LCDByte,7 ; Load high nibble BSF LCD_D7 BTFSC LCDByte,6 BSF LCD_D6 BTFSC LCDByte,5 BSF LCD_D5 BTFSC LCDByte,4 BSF LCD_D4 BSF LCD_EN ; Strobe EN NOP BCF LCD_EN BCF LCD_D7 ; Clear data bits BCF LCD_D6 BCF LCD_D5 BCF LCD_D4 BTFSC LCDByte,3 ; Load low nibble BSF LCD_D7 BTFSC LCDByte,2 BSF LCD_D6 BTFSC LCDByte,1 BSF LCD_D5 BTFSC LCDByte,0 BSF LCD_D4 BSF LCD_EN ; Strobe EN NOP BCF LCD_EN CALL SHORTDLY ; blocks until most instructions are done RETURN SHORTDLY ; around 221us, 217 cycles MOVLW 0x48 MOVWF d1 SHORTDLY_0 DECFSZ d1,F GOTO SHORTDLY_0 ;4 cycles (including call) RETURN LONGDLY ; 92ms delay, 92153 cycles MOVLW 0xFE MOVWF d1 MOVLW 0x48 MOVWF d2 LONGDLY_0 DECFSZ d1,F GOTO $+2 DECFSZ d2,F GOTO LONGDLY_0 ;3 cycles NOP NOP ;4 cycles (including call) RETURN ; Frequency handler FREQDISPLAY ; Decodes index to frequency and wavelength display MOVLW 0x80 CALL LCDPOS ; Set display leftmost corner top line MOVFW FRINDX ADDLW 0x3A MOVWF FREQ9 ; Add offset to get freq/9 CLRF FREQHI ; Multiply by 8 BCF STATUS,C RLF FREQ9,F RLF FREQHI,F BCF STATUS,C RLF FREQ9,F RLF FREQHI,F BCF STATUS,C RLF FREQ9,F RLF FREQHI,F ADDWF FREQ9,W ; Add once to get multiply by 9 MOVWF FREQLO BTFSC STATUS,C ; Carry from addition? INCF FREQHI,F ; Yes ; Convert frequency to BCD 4 digits ; See http://www.piclist.com/techref/microchip/math/radix/b2bu-10b4d-eag.htm movf FREQHI,w iorlw 0xF0 ;w=H2-16 movwf FREQ1 ;S1=H2-16 addwf FREQ1,f ;S1=H2*2-32 addwf FREQ1,f ;S1=H2*3-48 movwf FREQ2 ;S2=H2-16 addlw -D'5' ;w=H2-21 addwf FREQ2,f ;S2=H2*2-37 Done! addlw D'41' ;w=H2+20 movwf FREQ0 ;S0=H2+20 swapf FREQLO,w iorlw 0xF0 ;w=H1-16 addwf FREQ1,f ;S1=H2*3+H1-64 addwf FREQ0,f ;S0=H2+H1+4, C=1 rlf FREQ0,f ;S0=(H2+H1)*2+9, C=0 comf FREQ0,f ;S0=-(H2+H1)*2-10 rlf FREQ0,f ;S0=-(H2+H1)*4-20 movf FREQLO,w andlw 0x0F ;w=H0 addwf FREQ0,f ;S0=H0-(H2+H1)*4-20 Done! rlf FREQ1,f ;C=0, S1=H2*6+H1*2-128 Done! movlw D'5' movwf FREQ3 movlw D'10' mod0t addwf FREQ0,f ;D(X)=D(X)mod10 decf FREQ1,f ;D(X+1)=D(X+1)+D(X)div10 skpc goto mod0t mod1t addwf FREQ1,f decf FREQ2,f skpc goto mod1t mod2t addwf FREQ2,f decf FREQ3,f skpc goto mod2t MOVLW 0x30 ADDWF FREQ0,F ; Add 0x30 to get ASCII value for number ADDWF FREQ1,F ADDWF FREQ2,F ADDWF FREQ3,F SUBWF FREQ3,W ; Test for leading zero BTFSS STATUS,Z GOTO $+3 MOVLW 0x20 MOVWF FREQ3 MOVLW 0x80 ; Leftmost position upper line CALL LCDPOS MOVFW FREQ3 CALL LCDBYTE MOVFW FREQ2 CALL LCDBYTE MOVFW FREQ1 CALL LCDBYTE MOVFW FREQ0 CALL LCDBYTE MOVLW 0x20 ; space CALL LCDBYTE MOVLW 0x6B ; k CALL LCDBYTE MOVLW 0x48 ; H CALL LCDBYTE MOVLW 0x7A ; z CALL LCDBYTE MOVLW 0xC0 ; Leftmost position lower line CALL LCDPOS MOVFW WAVEHI ADDLW 0x30 CALL LCDBYTE MOVFW WAVELO MOVWF TEMP2 RRF TEMP2,F RRF TEMP2,F RRF TEMP2,F RRF TEMP2,W ANDLW 0x0F ; Convert to ASCII ADDLW 0x30 CALL LCDBYTE MOVFW WAVELO ANDLW 0x0F ; Convert to ASCII ADDLW 0x30 CALL LCDBYTE MOVLW 0x20 ; space CALL LCDBYTE MOVLW 0x6D ; m CALL LCDBYTE MOVLW 0x65 ; e CALL LCDBYTE MOVLW 0x74 ; t CALL LCDBYTE MOVLW 0x65 ; e CALL LCDBYTE MOVLW 0x72 ; r CALL LCDBYTE RETURN START ; Init stuff CLRF STATUS ; Do initialization, select Bank 0 CLRF INTCON ; Clear int-flags, disable interrupts MOVLW 0x07 ; Disable comparators MOVWF CMCON BANK1 MOVLW B'11111001' MOVWF TRISA ; RA7-3 Inputs, RA2,1 Outputs, AN0 Input CLRF TRISB ; RB7-0 Outputs MOVLW B'00000110' ; Timer0, prescaler 1:128 MOVWF OPTION_REG BANK0 CLRF PORTB ; Make all PORT B outputs low CLRF FLAGS BSF SCL BSF SDA ; Init LCD CALL LONGDLY ; Set LCD to 4-bit mode MOVLW B'00110011' ; 2x 8bit resets CALL LCDBYTE CALL SHORTDLY MOVLW B'00110011' ; 2x 8bit resets CALL LCDBYTE CALL SHORTDLY MOVLW B'00110010' ; 8bit reset then 4bit reset CALL LCDBYTE CALL SHORTDLY MOVLW B'00101100' ; Function Set - 4bit, 2 lines CALL LCDBYTE CALL SHORTDLY MOVLW B'00000110' ; Set entry mode (move cursor to right after each write) CALL LCDBYTE CALL SHORTDLY MOVLW B'00001100' ; turn display on and cursor off CALL LCDBYTE CALL SHORTDLY MOVLW B'00000001' ; Display Clear CALL LCDBYTE CALL LONGDLY ; Should wait for BUSY flag to clear but we cannot read it... MOVLW B'00000010' ; Cursor Home CALL LCDBYTE CALL LONGDLY ; Done init LCD ; Show banner MOVLW 0x80 ; 1st position top line CALL LCDPOS MOVLW 0x4D ; M CALL LCDBYTE MOVLW 0x57 ; W CALL LCDBYTE MOVLW 0x20 ; space CALL LCDBYTE MOVLW 0x50 ; P CALL LCDBYTE MOVLW 0x4C ; L CALL LCDBYTE MOVLW 0x4C ; L CALL LCDBYTE MOVLW 0x20 ; space CALL LCDBYTE MOVLW 0x4D ; M CALL LCDBYTE MOVLW 0x6F ; o CALL LCDBYTE MOVLW 0x64 ; d CALL LCDBYTE MOVLW 0x75 ; u CALL LCDBYTE MOVLW 0x6C ; l CALL LCDBYTE MOVLW 0x61 ; a CALL LCDBYTE MOVLW 0x74 ; t CALL LCDBYTE MOVLW 0x6F ; o CALL LCDBYTE MOVLW 0x72 ; r CALL LCDBYTE MOVLW 0xC0 ; 1st postition bottom line CALL LCDPOS MOVLW 0x53 ; S CALL LCDBYTE MOVLW 0x69 ; i CALL LCDBYTE MOVLW 0x35 ; 5 CALL LCDBYTE MOVLW 0x33 ; 3 CALL LCDBYTE MOVLW 0x35 ; 5 CALL LCDBYTE MOVLW 0x31 ; 1 CALL LCDBYTE MOVLW 0x20 ; space CALL LCDBYTE MOVLW 0x43 ; C CALL LCDBYTE MOVLW 0x6C ; l CALL LCDBYTE MOVLW 0x6F ; o CALL LCDBYTE MOVLW 0x63 ; c CALL LCDBYTE MOVLW 0x6B ; k CALL LCDBYTE MOVLW 0x20 ; space CALL LCDBYTE MOVLW 0x47 ; G CALL LCDBYTE MOVLW 0x65 ; e CALL LCDBYTE MOVLW 0x6E ; n CALL LCDBYTE ; Restore index from EEPROM CLRW CALL EEPROMREAD BANK0 MOVWF FRINDX ; Restored Frequency Index ; Init Si5351A CALL I2CSTART MOVLW 0xC0 ; Address CALL I2CBYTE CLRW ; Prepare register 0 for reading CALL I2CBYTE CALL I2CSTOP Readsysinit CALL I2CSTART MOVLW 0xC1 ; Read address CALL I2CBYTE CLRF I2CCNT ; Used for ACK timeout BANK1 ; Select Bank 1 BSF TRISB,1 ; Set SDA as input to float SDA line BANK0 ; Select Bank 0 CALL I2CDELAY BSF SCL ; Read SYS_INIT bit CALL I2CDELAY BTFSS SDA BCF SYSINIT BCF SCL MOVLW 0x07 MOVWF I2CCNT DUMMYREAD CALL I2CDELAY BSF SCL CALL I2CDELAY BCF SCL DECFSZ I2CCNT,F GOTO DUMMYREAD BANK1 ; Select Bank 1 BCF TRISB,1 ; Set SDA as output to assert SDA line BANK0 ; Select Bank 0 BCF SDA ; Present NAK CALL I2CDELAY BSF SCL CALL I2CDELAY BCF SCL CALL I2CSTOP BTFSC SYSINIT ; System init done? GOTO Readsysinit ; No ; Start configure CALL I2CSTART MOVLW 0xC0 ; Address CALL I2CBYTE MOVLW 0x03 ; Register 3 CALL I2CBYTE MOVLW 0xFF ; Register 3 data (Output Enable Control) CALL I2CBYTE CALL I2CSTOP CALL I2CSTART MOVLW 0xC0 ; Address CALL I2CBYTE MOVLW 0x09 ; Register 9 CALL I2CBYTE MOVLW 0xFF ; Register 9 data (OEB Pin Enable Control Mask) CALL I2CBYTE CALL I2CSTOP CALL I2CSTART MOVLW 0xC0 ; Address CALL I2CBYTE MOVLW 0x10 ; Register 16 CALL I2CBYTE MOVLW 0x4F ; Register 16 data CALL I2CBYTE MOVLW 0x80 ; Register 17 data CALL I2CBYTE MOVLW 0x80 ; Register 18 data CALL I2CBYTE MOVLW 0x80 ; Register 19 data CALL I2CBYTE MOVLW 0x80 ; Register 20 data CALL I2CBYTE MOVLW 0x80 ; Register 21 data CALL I2CBYTE MOVLW 0x80 ; Register 22 data CALL I2CBYTE MOVLW 0x80 ; Register 23 data CALL I2CBYTE CLRW ; Register 24 data (CLK30 Disable State) CALL I2CBYTE CLRW ; Register 25 data (CLK74 Disable State) CALL I2CBYTE CALL I2CSTOP CALL I2CSTART MOVLW 0xC0 ; Address CALL I2CBYTE MOVLW 0x3B ; Register 43 CALL I2CBYTE MOVLW 0x01 ; Register 43 data (always 1) CALL I2CBYTE CALL I2CSTOP CALL LOADPLL CALL I2CSTART MOVLW 0xC0 ; Address CALL I2CBYTE MOVLW 0xB7 ; Register 183 CALL I2CBYTE MOVLW 0x92 ; 8 pF load capacitance for XTAL used on Adafruit board and mandatory bit pattern CALL I2CBYTE CALL I2CSTOP CALL I2CSTART MOVLW 0xC0 ; Address CALL I2CBYTE MOVLW 0x03 ; Register 3 CALL I2CBYTE MOVLW 0xFE ; Register 3 data: enable OSC0 CALL I2CBYTE CALL I2CSTOP ; Done init Si5351A MOVLW 0x10 ; Show banner for about one second MOVWF TEMP1 CALL LONGDLY DECFSZ TEMP1,F GOTO $-2 CALL LCDCLR ; Clear display CALL LONGDLY CALL FREQDISPLAY MOVLW B'10100000' ; Enable global (GIE), Timer0 (T0IE) interrupts MOVWF INTCON GOTO $ ; Loop forever ORG 0x300 ; Wavelength table wave ADDWF PCL,F dt 0x05,0x74,0x05,0x65,0x05,0x56,0x05,0x46 dt 0x05,0x37,0x05,0x28,0x05,0x20,0x05,0x12 dt 0x05,0x04,0x04,0x97,0x04,0x89,0x04,0x82 dt 0x04,0x75,0x04,0x69,0x04,0x62,0x04,0x56 dt 0x04,0x50,0x04,0x44,0x04,0x38,0x04,0x32 dt 0x04,0x27,0x04,0x21,0x04,0x16,0x04,0x11 dt 0x04,0x06,0x04,0x01,0x03,0x96,0x03,0x91 dt 0x03,0x87,0x03,0x82,0x03,0x78,0x03,0x74 dt 0x03,0x70,0x03,0x66,0x03,0x62,0x03,0x58 dt 0x03,0x54,0x03,0x50,0x03,0x46,0x03,0x43 dt 0x03,0x39,0x03,0x36,0x03,0x33,0x03,0x29 dt 0x03,0x26,0x03,0x23,0x03,0x20,0x03,0x17 dt 0x03,0x14,0x03,0x11,0x03,0x08,0x03,0x05 dt 0x03,0x02,0x03,0x00,0x02,0x97,0x02,0x94 dt 0x02,0x92,0x02,0x89,0x02,0x87,0x02,0x84 dt 0x02,0x82,0x02,0x79,0x02,0x77,0x02,0x75 dt 0x02,0x73,0x02,0x70,0x02,0x68,0x02,0x66 dt 0x02,0x64,0x02,0x62,0x02,0x60,0x02,0x58 dt 0x02,0x56,0x02,0x54,0x02,0x52,0x02,0x50 dt 0x02,0x48,0x02,0x46,0x02,0x44,0x02,0x43 dt 0x02,0x41,0x02,0x39,0x02,0x37,0x02,0x36 dt 0x02,0x34,0x02,0x32,0x02,0x31,0x02,0x29 dt 0x02,0x28,0x02,0x26,0x02,0x25,0x02,0x23 dt 0x02,0x22,0x02,0x20,0x02,0x19,0x02,0x17 dt 0x02,0x16,0x02,0x14,0x02,0x13,0x02,0x12 dt 0x02,0x10,0x02,0x09,0x02,0x08,0x02,0x06 dt 0x02,0x05,0x02,0x04,0x02,0x03,0x02,0x01 dt 0x02,0x00,0x01,0x99,0x01,0x98,0x01,0x97 dt 0x01,0x95,0x01,0x94,0x01,0x93,0x01,0x92 dt 0x01,0x91,0x01,0x90,0x01,0x89,0x01,0x88 dt 0x01,0x87 ORG 0x400 ; Registers 26,27 R2627 ADDWF PCL,F dt 0x18,0x6A,0x30,0xD4,0x00,0x01,0x30,0xD4 dt 0x18,0x6A,0x18,0x6A,0x0C,0x35,0x04,0xE2 dt 0x18,0x6A,0x02,0x71,0x0C,0x35,0x30,0xD4 dt 0x02,0x71,0x0C,0x35,0x02,0x71,0x0C,0x35 dt 0x00,0xFA,0x00,0x01,0x0C,0x35,0x0C,0x35 dt 0x0C,0x35,0x30,0xD4,0x00,0x01,0x02,0x71 dt 0x0C,0x35,0x0C,0x35,0x0C,0x35,0x09,0xC4 dt 0x0C,0x35,0x30,0xD4,0x0C,0x35,0x30,0xD4 dt 0x02,0x71,0x30,0xD4,0x0C,0x35,0x18,0x6A dt 0x18,0x6A,0x09,0xC4,0x02,0x71,0x30,0xD4 dt 0x0C,0x35,0x30,0xD4,0x00,0x01,0x09,0xC4 dt 0x18,0x6A,0x18,0x6A,0x0C,0x35,0x00,0xFA dt 0x0C,0x35,0x30,0xD4,0x02,0x71,0x0C,0x35 dt 0x04,0xE2,0x00,0xFA,0x0C,0x35,0x30,0xD4 dt 0x18,0x6A,0x09,0xC4,0x02,0x71,0x0C,0x35 dt 0x18,0x6A,0x30,0xD4,0x02,0x71,0x18,0x6A dt 0x18,0x6A,0x0C,0x35,0x0C,0x35,0x00,0x01 dt 0x0C,0x35,0x18,0x6A,0x0C,0x35,0x30,0xD4 dt 0x04,0xE2,0x30,0xD4,0x02,0x71,0x0C,0x35 dt 0x02,0x71,0x02,0x71,0x0C,0x35,0x0C,0x35 dt 0x0C,0x35,0x02,0x71,0x02,0x71,0x0C,0x35 dt 0x0C,0x35,0x0C,0x35,0x02,0x71,0x02,0x71 dt 0x18,0x6A,0x09,0xC4,0x0C,0x35,0x30,0xD4 dt 0x00,0x01,0x18,0x6A,0x0C,0x35,0x18,0x6A dt 0x18,0x6A,0x02,0x71,0x00,0x19,0x30,0xD4 dt 0x18,0x6A,0x09,0xC4,0x02,0x71,0x18,0x6A dt 0x02,0x71,0x30,0xD4,0x0C,0x35,0x02,0x71 dt 0x0C,0x35,0x30,0xD4,0x0C,0x35,0x30,0xD4 dt 0x00,0x7D,0x0C,0x35,0x0C,0x35,0x01,0xF4 dt 0x0C,0x35,0x00,0xFA,0x0C,0x35,0x02,0x71 dt 0x0C,0x35 ORG 0x500 ; Registers 29,30 R2930 ADDWF PCL,F dt 0x0C,0x02,0x0B,0xFF,0x0B,0x80,0x0B,0xFD dt 0x0B,0xFE,0x0C,0x04,0x0B,0xFC,0x0B,0xFE dt 0x0B,0xFE,0x0B,0xFD,0x0B,0xFA,0x0B,0xFC dt 0x0C,0x02,0x0C,0x01,0x0B,0xFF,0x0B,0xFB dt 0x0B,0xFC,0x0B,0x80,0x0B,0xFB,0x0B,0xF8 dt 0x0B,0xFB,0x0B,0xF6,0x10,0x00,0x0B,0xFF dt 0x0B,0xFE,0x0B,0xFB,0x0B,0xF8,0x0B,0xFB dt 0x0B,0xFE,0x0C,0x00,0x0C,0x00,0x0C,0x00 dt 0x0B,0xFF,0x0B,0xFD,0x0B,0xFA,0x0B,0xFE dt 0x0B,0xF9,0x0B,0xFC,0x0B,0xFF,0x0C,0x00 dt 0x0C,0x0A,0x0C,0x01,0x0B,0x80,0x0B,0xFF dt 0x0B,0xFD,0x0C,0x04,0x0C,0x00,0x0B,0xFC dt 0x0B,0xF7,0x0B,0xFB,0x0B,0xFF,0x0B,0xF8 dt 0x0B,0xFA,0x0B,0xFC,0x0B,0xF3,0x0B,0xF4 dt 0x0B,0xFE,0x0B,0xF3,0x0B,0xFD,0x0B,0xFB dt 0x0B,0xF9,0x0C,0x02,0x0B,0xFF,0x0C,0x06 dt 0x0C,0x02,0x0B,0xFE,0x0B,0xF8,0x0B,0x80 dt 0x0B,0xF8,0x0B,0xFD,0x0C,0x02,0x0B,0xFA dt 0x0B,0xFE,0x0C,0x01,0x0C,0x04,0x0B,0xFB dt 0x0B,0xFD,0x0B,0xFF,0x0C,0x0D,0x0C,0x01 dt 0x0C,0x02,0x0C,0x02,0x0C,0x02,0x0C,0x02 dt 0x0C,0x01,0x0C,0x00,0x0B,0xFF,0x0B,0xFD dt 0x0C,0x08,0x0C,0x06,0x0C,0x03,0x0C,0x00 dt 0x0B,0x80,0x0C,0x06,0x0C,0x02,0x0B,0xFD dt 0x0C,0x06,0x0C,0x0F,0x0C,0x0A,0x0C,0x12 dt 0x0C,0x0C,0x0C,0x06,0x0C,0x0D,0x0C,0x06 dt 0x0B,0xFF,0x0C,0x06,0x0B,0xFE,0x0C,0x04 dt 0x0B,0xFB,0x0C,0x02,0x0C,0x08,0x0C,0x0D dt 0x0C,0x13,0x0C,0x09,0x0B,0xFE,0x0C,0x03 dt 0x0C,0x08,0x0B,0xFC,0x0C,0x00,0x0C,0x04 dt 0x0B,0xF8 ORG 0x600 ; Registers 32,33 R3233 ADDWF PCL,F dt 0x10,0xAC,0x0D,0x54,0x00,0x00,0x02,0xFC dt 0x0F,0x54,0x03,0xD8,0x02,0xD4,0x01,0x44 dt 0x0F,0x54,0x00,0xD3,0x04,0xBE,0x06,0xD0 dt 0x02,0x1E,0x09,0xB4,0x00,0x71,0x01,0x89 dt 0x00,0x68,0x00,0x00,0x01,0x89,0x06,0xA8 dt 0x0A,0x89,0x26,0xC8,0x00,0x00,0x00,0x71 dt 0x00,0xEA,0x0A,0x89,0x06,0xA8,0x09,0x54 dt 0x05,0x6A,0x00,0x80,0x08,0x00,0x12,0x80 dt 0x00,0x71,0x02,0xFC,0x00,0x3E,0x0F,0x54 dt 0x14,0x66,0x08,0x90,0x00,0x71,0x24,0x80 dt 0x07,0x6E,0x20,0xAC,0x00,0x00,0x06,0x44 dt 0x0C,0xBE,0x03,0xD8,0x08,0x00,0x00,0x68 dt 0x05,0x5D,0x1C,0xA4,0x00,0x71,0x02,0x28 dt 0x02,0xCC,0x00,0x68,0x04,0xB1,0x01,0x70 dt 0x0F,0x54,0x06,0x74,0x00,0xD3,0x0A,0x89 dt 0x14,0x66,0x0A,0xD8,0x00,0x71,0x12,0x04 dt 0x10,0xAC,0x00,0xEA,0x0B,0x28,0x00,0x00 dt 0x06,0xA8,0x0C,0xBE,0x01,0x96,0x17,0x78 dt 0x01,0x44,0x20,0xAC,0x01,0xBC,0x01,0x89 dt 0x00,0xD3,0x00,0x71,0x02,0x4F,0x09,0x4B dt 0x06,0x16,0x02,0x1E,0x02,0x1E,0x06,0x16 dt 0x09,0x4B,0x08,0x00,0x00,0x71,0x00,0xD3 dt 0x0E,0x30,0x00,0xE8,0x02,0xE1,0x00,0x80 dt 0x00,0x00,0x09,0x04,0x01,0x96,0x0C,0xBE dt 0x12,0x04,0x01,0xE1,0x00,0x06,0x27,0x98 dt 0x0F,0x88,0x00,0xE8,0x02,0x43,0x12,0x04 dt 0x00,0x71,0x0D,0x88,0x00,0xEA,0x01,0xBC dt 0x0A,0x89,0x01,0xD8,0x00,0x58,0x28,0xBD dt 0x00,0x39,0x01,0xA3,0x05,0x6A,0x00,0xA4 dt 0x00,0x58,0x00,0x68,0x08,0x00,0x01,0xBC dt 0x02,0x28 ORG 0x700 ; Registers 44.45 R4445 ADDWF PCL,F dt 0x02,0x9D,0x02,0x91,0x02,0x6F,0x02,0x7B dt 0x02,0x71,0x02,0x68,0x02,0x5D,0x02,0x54 dt 0x02,0x4B,0x02,0x42,0x02,0x39,0x02,0x31 dt 0x02,0x2A,0x02,0x22,0x02,0x1A,0x02,0x12 dt 0x02,0x0B,0x01,0xF2,0x01,0xFD,0x01,0xF6 dt 0x01,0xF0,0x01,0xE9,0x02,0x6F,0x01,0xDE dt 0x01,0xD8,0x01,0xD2,0x01,0xCC,0x01,0xC7 dt 0x01,0xC2,0x01,0xBD,0x01,0xB8,0x01,0xB3 dt 0x01,0xAE,0x01,0xA9,0x01,0xA4,0x01,0xA0 dt 0x01,0x9B,0x01,0x97,0x01,0x93,0x01,0x8F dt 0x01,0x8C,0x01,0x87,0x01,0x75,0x01,0x7F dt 0x01,0x7B,0x01,0x78,0x01,0x74,0x01,0x70 dt 0x01,0x6C,0x01,0x69,0x01,0x66,0x01,0x62 dt 0x01,0x5F,0x01,0x5C,0x01,0x58,0x01,0x55 dt 0x01,0x53,0x01,0x4F,0x01,0x4D,0x01,0x4A dt 0x01,0x47,0x01,0x45,0x01,0x42,0x01,0x40 dt 0x01,0x3D,0x01,0X3A,0x01,0x37,0x01,0x2A dt 0x01,0x32,0x01,0x30,0x01,0x2E,0x01,0x2B dt 0x01,0x29,0x01,0x27,0x01,0x25,0x01,0x22 dt 0x01,0x20,0x01,0x1E,0x01,0x1D,0x01,0x1A dt 0x01,0x18,0x01,0x16,0x01,0x14,0x01,0x12 dt 0x01,0x10,0x01,0x0E,0x01,0x0C,0x01,0x0A dt 0x01,0x09,0x01,0x07,0x01,0x05,0x01,0x03 dt 0x00,0xF8,0x01,0x00,0x00,0xFE,0x00,0xFC dt 0x00,0xFB,0x00,0xFA,0x00,0xF8,0x00,0xF7 dt 0x00,0xF5,0x00,0xF3,0x00,0xF2,0x00,0xF0 dt 0x00,0xEE,0x00,0xED,0x00,0xEB,0x00,0xEA dt 0x00,0xE8,0x00,0xE7,0x00,0xE6,0x00,0xE5 dt 0x00,0xE4,0x00,0xE2,0x00,0xE0,0x00,0xDF dt 0x00,0xDE,0x00,0xDC,0x00,0xDB,0x00,0xDA dt 0x00,0xD8 ORG 0x2100 ; EEPROM Data DE 0x35 ; FRINDX (999 kHz) END