;********************************************************************** ; * ; Filename: pll.asm * ; Date: 11-Apr-1999 * ; File Version: 0.1 * ; * ; Author: Deti Fliegl, deti.gmx.de * ; Company: * ; * ; * ;********************************************************************** ; * ; Files required: * ; * ; * ; * ;********************************************************************** ; * ; Notes: * ; * ; * ; * ; * ;********************************************************************** ;#define DEBUG 1 list p=16F84 ; list directive to define processor #include ; processor specific variable definitions __CONFIG _CP_ON & _WDT_OFF & _PWRTE_ON & _XT_OSC ; '__CONFIG' directive is used to embed configuration data within .asm file. ; The lables following the directive are located in the respective .inc file. ; See respective data sheet for additional information on configuration word. ;---------------- macro definitions -------------------- get_data macro addr movlw addr & 0xff call _get_data endm rbank macro n if n == 1 BSF STATUS, RP0 else BCF STATUS, RP0 endif endm eeprom_read macro addr MOVLW addr ; call _eerd endm eeprom_write macro addr, val movlw val movwf EEDATA MOVLW addr call _eewr endm lcdclk macro call _lcdclk endm lcdpos macro val movlw val call _lcdddaddr endm pllser macro val, len movlw len movwf cnt movlw val call _pllser endm pllset macro call _pllset endm print macro addr movlw addr & 0xff call _print endm printn macro addr movlw addr & 0xff call _printn endm printn100 macro addr movlw addr & 0xff call _printn100 endm delay macro val movlw val & 0xff call _delay0 endm delay1 macro val movlw val & 0xff call _delay1 endm delay2 macro val movlw val & 0xff call _delay2 endm rotl4 macro call _rotl4 endm sub24 macro val movlw val & 0xff call _sub24 endm div24 macro val movlw val & 0xff call _div24 endm printfreq macro val movlw val & 0xff call _printfreq endm ; Gerechnet wird an folgenden Stellen: ; PLL Teiler zu RX-Frequenz = n * 256 - 479500 ; ASCII Darstellung ; geteilt durch 1000, 100 und 10 _IFOFFSET2 EQU 0x07 _IFOFFSET1 EQU 0x51 _IFOFFSET0 EQU 0x0c ; 479.5Mhz IF offset for tuner module _DIV1000000_2 EQU 0x0f _DIV1000000_1 EQU 0x42 _DIV1000000_0 EQU 0x40 _DIV100000_2 EQU 0x01 _DIV100000_1 EQU 0x86 _DIV100000_0 EQU 0xa0 _DIV10000 EQU 0x2710 ; 10000 _DIV1000 EQU 0x3e8 ; 1000 _DIV100 EQU 0x64 ; 100 _DIV10 EQU 0xa ; 10 ; Port bit # RA0 EQU 0x0 RA1 EQU 0x1 RA2 EQU 0x2 RA3 EQU 0x3 RA4 EQU 0x4 RB0 EQU 0x0 RB1 EQU 0x1 RB2 EQU 0x2 RB3 EQU 0x3 RB4 EQU 0x4 RB5 EQU 0x5 RB6 EQU 0x6 RB7 EQU 0x7 ;PLL/LCD Interface DATAPORT EQU PORTA LCD_D0 EQU RA0 PLL_DATA EQU RA0 LCD_D1 EQU RA1 PLL_CLOCK EQU RA1 LCD_D2 EQU RA2 LCD_D3 EQU RA3 LCD_RS EQU RA4 CTRLPORT EQU PORTB LCD_WR EQU RB1 LCD_E EQU RB2 PLL_CE EQU RB3 ;PLL Constants PLL_LOWER EQU 0x150c ;5388 =900Mhz+479.5Mhz PLL_UPPER EQU 0x2699 ;9881 =2.050Mhz+479.5Mhz ;Memory Constants MEM_MAX EQU 0x1f MEM_MIN EQU 0x01 ;LCD Commands LCD_CLEAR EQU 0x01 LCD_HOME EQU 0x02 LCD_DIRECTION EQU 0x04 LCD_DISPLAY EQU 0x08 LCD_SHIFT EQU 0x10 LCD_FUNCTION EQU 0x20 LCD_CGADDR EQU 0x40 LCD_DDADDR EQU 0x80 LCD_BF EQU 0x80 ;EEPROM Structure EEPROM_VFO0 EQU 0x00 EEPROM_VFO1 EQU 0x01 EEPROM_MEM EQU 0x02 ;MODE States MODE_VFO EQU 0x00 MODE_RECALL EQU 0x01 MODE_STORE EQU 0x02 MODE_MAX EQU 0x03 ;BUTTONS BUTTON_PORT EQU PORTB BUTTON_MODE EQU RB4 BUTTON_ENTER EQU RB5 BUTTON_PLUS EQU RB6 BUTTON_MINUS EQU RB7 ;IR IRSYNC_LOWER EQU 9 IRSYNC_UPPER EQU 11 IRHIGH_LOWER EQU 7 IRHIGH_UPPER EQU 8 IRLOW_LOWER EQU 4 IRLOW_UPPER EQU 5 user EQU 0x10 ;***** VARIABLE DEFINITIONS w_temp EQU user+0x00 ; variable used for context saving status_temp EQU user+0x01 ; variable used for context saving cnt EQU user+0x02 ; universal counter dly0 EQU user+0x03 ; delay0 counter dly1 EQU user+0x04 ; delay1 counter dly2 EQU user+0x05 ; delay2 counter tmp EQU user+0x06 ; temporary value mode EQU user+0x07 mem EQU user+0x08 saveb EQU user+0x09 charptr EQU user+0x0A tmp_n0 EQU user+0x0B tmp_n1 EQU user+0x0C subcarry EQU user+0x0D ; PLL N-Teiler 14-Bit n0 EQU user+0x10 ; n bits 0-7 n1 EQU user+0x11 ; n bits 8-15 ; Differenzergebnis max. 24-Bit d0 EQU user+0x12 ; d bits 0-7 d1 EQU user+0x13 ; d bits 8-15 d2 EQU user+0x14 ; d bits 16-23 subptr EQU user+0x15 ; Pointer ; Divisionszaehler divcnt EQU user+0x16 divptr EQU user+0x17 ; Divisionsrest s0 EQU user+0x18 s1 EQU user+0x19 s2 EQU user+0x1a ; Infrared decoder sircs irstate EQU user+0x1b ; IR Decoderstatus 1 ready, 2 sync, 4 func, 8 dev irfunc EQU user+0x1c irdev EQU user+0x1d irfunc0 EQU user+0x1e irdev0 EQU user+0x1f ircnt EQU user+0x20 irtmr0 EQU user+0x21 irjob EQU user+0x22 irrxcnt EQU user+0x23 ;********************************************************************** ORG 0x000 ; processor reset vector goto main ; go to beginning of program isr ORG 0x004 ; interrupt vector location movwf w_temp ; save off current W register contents movf STATUS,w ; move status register into W register movwf status_temp ; save off contents of STATUS register rbank 0 ; Bank0 ansprechen. btfsc INTCON,INTF ; Hat sich die RB0 Leitung veraendert call _rb0int ; Handler aufrufen btfsc INTCON,T0IF ; Timerinterrupt aufgetreten call _tmr0int ; Handler aufrufen _eoi movf status_temp,w ; retrieve copy of STATUS register movwf STATUS ; restore pre-isr STATUS register contents swapf w_temp,f swapf w_temp,w ; restore pre-isr W register contents retfie ; return from interrupt _rb0int #ifdef TEST movf PORTA,w xorlw 2 movwf PORTA #endif movf TMR0, w ; timerwert movwf irtmr0 ; retten clrf TMR0 ; timer zuruecksetzen. btfss irstate,0 ; warten wir auf sync? goto _rb0int0 ; also nicht, dann weiter rbank 1 bsf OPTION_REG,INTEDG ; rising edge rbank 0 bcf STATUS,C ; Carry=0 rlf irstate,f ; nun warten wir aufs erste func-bit goto _rb0int3 ; fertig _rb0int0 btfss irstate,1 ; warten wir auf funcbits goto _rb0int1 ; also nicht, dann weiter ; lcdpos 0x4F ; printn100 irtmr0 movf irtmr0,w sublw IRSYNC_UPPER btfss STATUS,C goto _rb0int4 movlw IRSYNC_LOWER ; war high subwf irtmr0,w ; wirklich fur 2,4ms btfss STATUS,C ; wenn nicht, dann goto _rb0int4 ; fertig + reset bcf STATUS,C ; Carry=0 rlf irstate,f ; nun warten wir aufs bitende clrf irfunc ; func bits loeschen clrf ircnt ; counter auf 0 #ifdef TEST movf PORTA,w xorlw 1 movwf PORTA #endif goto _rb0int3 ; fertig _rb0int1 btfss irstate,2 ; warten wir auf funcbits goto _rb0int2 ; also nicht, dann weiter movf irtmr0,w sublw IRHIGH_UPPER btfss STATUS,C goto _rb0int4 movlw IRHIGH_LOWER ; war high subwf irtmr0,w ; wirklich fur 1,2ms btfss STATUS,C ; wenn nicht, dann goto _rb0int5 ; schauen, ob low bsf STATUS,C ; 1 Bit in Carry rlf irfunc,f ; und von unten reinschieben goto _rb0int6 _rb0int5 movf irtmr0,w sublw IRLOW_UPPER btfss STATUS,C goto _rb0int4 movlw IRLOW_LOWER ; war low subwf irtmr0,w ; wirklich fur 0,6ms btfss STATUS,C ; wenn nicht, dann goto _rb0int4 ; fertig + reset bcf STATUS,C ; 0 Bit in Carry rlf irfunc,f ; und von unten reinschieben _rb0int6 incf ircnt,f ; bitcounter erhoehen movf ircnt,w ; haben wir schon sublw 7 ; 7 bits eingelesen? btfss STATUS,Z ; wenn nein, dann goto _rb0int3 ; fertig bcf STATUS,C ; Carry=0 rlf irstate,f ; nun holen wir uns die devbits clrf ircnt ; bitcounter loeschen clrf irdev ; device bits loeschen goto _rb0int3 ; fertig _rb0int2 btfss irstate,3 ; warten wir auf devbits goto _rb0int3 ; also nicht, dann weiter movf irtmr0,w sublw IRHIGH_UPPER btfss STATUS,C goto _rb0int4 movlw IRHIGH_LOWER ; war high subwf irtmr0,w ; wirklich fur 1,2ms btfss STATUS,C ; wenn nicht, dann goto _rb0int7 ; schauen, ob low bsf STATUS,C ; 1 Bit in Carry rlf irdev,f ; und von unten reinschieben goto _rb0int8 _rb0int7 movf irtmr0,w sublw IRLOW_UPPER btfss STATUS,C goto _rb0int4 movlw IRLOW_LOWER ; war low subwf irtmr0,w ; wirklich fur 0,6ms btfss STATUS,C ; wenn nicht, dann goto _rb0int4 ; fertig + reset bcf STATUS,C ; 0 Bit in Carry rlf irdev,f ; und von unten reinschieben _rb0int8 incf ircnt,f ; bitcounter erhoehen movf ircnt,w ; haben wir schon sublw 5 ; 5 bits eingelesen? btfss STATUS,Z ; wenn nein, dann goto _rb0int3 ; fertig decf irrxcnt,f btfsc STATUS,Z goto _rb0int9 movf irfunc,w movwf irfunc0 movf irdev,w movwf irdev0 goto _rb0int4 _rb0int9 ; lcdpos 0x4F ; printn100 irstate movf irfunc,w subwf irfunc0,w btfss STATUS,Z goto _rb0int4 movf irdev,w subwf irdev0,w btfss STATUS,Z goto _rb0int4 #ifdef DEBUG lcdpos 0x4F printn100 irfunc movlw 0x20 call _lcdwrd ; und ausgeben printn100 irdev #endif movlw D'26' ; Sony Videorecorder subwf irdev,w btfss STATUS,Z goto _rb0int4 movlw D'108' ; << subwf irfunc,w btfss STATUS,Z goto _irjob0 movlw 0x80+0x20 ;BUTTON_MINUS|BUTTON_ENTER goto _irjob6 _irjob0 movlw D'028' ; << subwf irfunc,w btfss STATUS,Z goto _irjob1 movlw 0x40+0x20 ;BUTTON_PLUS|BUTTON_ENTER goto _irjob6 _irjob1 movlw D'044' ; > subwf irfunc,w btfss STATUS,Z goto _irjob2 movlw 0x20 ;BUTTON_ENTER goto _irjob6 _irjob2 movlw D'004' ; + subwf irfunc,w btfss STATUS,Z goto _irjob3 movlw 0x40 ;BUTTON_PLUS goto _irjob6 _irjob3 movlw D'068' ; - subwf irfunc,w btfss STATUS,Z goto _irjob4 movlw 0x80 ;BUTTON_MINUS goto _irjob6 _irjob4 movlw D'012' ; stop subwf irfunc,w btfss STATUS,Z goto _irjob5 movlw 0x10 ;BUTTON_MODE _irjob6 movwf irjob ;bcf INTCON,INTE _irjob5 movlw 3 movwf irrxcnt _rb0int4 ; Zustandsuebergang in rb0 war ungueltig. movlw 1 movwf irstate ; timeout - zu lange keine Flanke _rb0int10 rbank 1 bcf OPTION_REG,INTEDG ; falling edge rbank 0 _rb0int3 bcf INTCON,INTF return _tmr0int ; ; movf PORTA,w ; xorlw 2 ; movwf PORTA ; bcf INTCON,T0IF ; Interrupt flag loeschen ; clrf PORTA movlw 1 movwf irstate ; timeout - zu lange keine Flanke movlw 3 movwf irrxcnt rbank 1 bcf OPTION_REG,INTEDG ; falling edge rbank 0 return _get_data bsf PCLATH,0 ; Address some program mem at 0x300+w bsf PCLATH,1 movwf PCL _eewr MOVWF EEADR ; Address to write rbank 1 BCF INTCON, GIE ; Disable INTs. BSF EECON1, WREN ; Enable Write MOVLW 0x55 MOVWF EECON2 ; Write 55h MOVLW 0xAA MOVWF EECON2 ; Write AAh BSF EECON1,WR ; Set WR bit BSF INTCON, GIE ; Enable INTs. _eewr_loop0 btfss EECON1,EEIF goto _eewr_loop0 BCF EECON1, EEIF ; Clear EEIF Flag rbank 0 return _eerd rbank 0 MOVWF EEADR ; Address to read rbank 1 BSF EECON1, RD ; EE Read rbank 0 MOVF EEDATA, W ; W = EEDATA return _delay0 movwf dly0 _delay0_0 ;clrwdt decfsz dly0,f goto _delay0_0 return _delay1 movwf dly1 _delay1_0 delay 255 decfsz dly1,f goto _delay1_0 return _delay2 movwf dly2 _delay2_0 delay1 255 decfsz dly2,f goto _delay2_0 return _rotl1 bcf STATUS,C ; Carry loeschen btfsc tmp,7 ; Wenn Bit 7 gesetzt bsf STATUS,C ; Carry setzen rlf tmp,f ; und Bit7 in Bit 0 schieben return _rotl4 movlw 4 movwf cnt _rotl40 call _rotl1 decfsz cnt,f goto _rotl40 return _lcdclk bsf CTRLPORT,LCD_E delay 60 movf DATAPORT,w bcf CTRLPORT,LCD_E delay 60 return _lcdrdbf ;delay1 50 ;bcf STATUS,Z ;return clrf DATAPORT ; D0-D7 movlw 0xf rbank 1 movwf TRISA ; set RA0-RA3 to input rbank 0 bsf CTRLPORT,LCD_WR ; Read operation lcdclk andlw 0xf ; RA0-RA3 maskieren movwf tmp rotl4 lcdclk andlw 0xf iorwf tmp,f ; 8-Bit wert gelesen. return _lcdwrc movwf tmp rbank 1 clrf TRISA ; set RA0-RA3 to output rbank 0 bcf CTRLPORT,LCD_WR ; Write operation rotl4 ; 7-4 -> 3-0 movf tmp,w andlw 0xF movwf DATAPORT lcdclk rotl4 ; 3-0 -> 7-4 movf tmp,w andlw 0xF movwf DATAPORT lcdclk _lcdwrc0 call _lcdrdbf btfsc tmp,7 goto _lcdwrc0 return _lcdwrd movwf tmp rbank 1 clrf TRISA ; set RA0-RA3 to output rbank 0 bcf CTRLPORT,LCD_WR ; Write operation rotl4 ; 7-4 -> 3-0 movf tmp,w andlw 0xF movwf DATAPORT bsf DATAPORT,LCD_RS ; set Data register lcdclk rotl4 ; 3-0 -> 7-4 movf tmp,w andlw 0xF movwf DATAPORT bsf DATAPORT,LCD_RS ; set Data register lcdclk _lcdwrd0 call _lcdrdbf btfsc tmp,7 goto _lcdwrd0 return _lcdcld movlw LCD_CLEAR goto _lcdwrc _lcdhome movlw LCD_HOME goto _lcdwrc _lcddirection iorlw LCD_DIRECTION goto _lcdwrc _lcddisplay iorlw LCD_DISPLAY goto _lcdwrc _lcdshift iorlw LCD_SHIFT goto _lcdwrc _lcdfunction iorlw LCD_FUNCTION goto _lcdwrc _lcdcgaddr iorlw LCD_CGADDR goto _lcdwrc _lcdddaddr iorlw LCD_DDADDR goto _lcdwrc _lcdinit movlw 3 movwf cnt _lcdinit0 movlw 0x3 ;set LCD interface length to 8-bit movwf DATAPORT lcdclk delay1 15 decfsz cnt,f goto _lcdinit0 movlw 0x2 ;set LCD interface length to 4-bit movwf DATAPORT lcdclk delay 25 movlw 0x08 ;4-bit, 2-lines, 5x8 font call _lcdfunction movlw 2 ; increment on entry, no shift call _lcddirection movlw 4 ; display on, cursor off, blinking off call _lcddisplay goto _lcdcld ; Display loeschen _pllser movwf tmp ; zu serialisierendes Wort nach tmp _pllser0 movlw 0x2 rlf tmp,f ; msb nach carry schieben btfsc STATUS,C ; Falls 1 bit iorlw 0x01 ;PLL_DATA | PLL_CLOCK movwf DATAPORT ; und auf die Leitung legen delay 15 bcf DATAPORT,PLL_CLOCK delay 5 decfsz cnt,f ; cnt dekrementieren goto _pllser0 ; und wiederholen return _pllset rbank 0 clrf PORTA ;set port A to 00000 rbank 1 clrf TRISA ;set port A to output only rbank 0 bsf CTRLPORT,PLL_CE pllser B'01010000',4 movlw 8 movwf cnt movf n1,w call _pllser movlw 8 movwf cnt movf n0,w call _pllser bcf CTRLPORT,PLL_CE clrw ; n0 und n1 ins EEPROM call _storemem ; schreiben. return _print _print0 movwf charptr call _get_data iorlw 0 ;check w btfsc STATUS,Z ;if w=0 return return call _lcdwrd incf charptr,w goto _print0 _sub24 movwf subptr ; Pointer auf Subtrahend retten call _get_data ; low Byte holen bcf subcarry,0 subwf d0,f ; abziehen von Quelle btfss STATUS,C ; bei nicht carry bsf subcarry,0 sub24_1 incf subptr,w ; und Pointer auf naechsten Subtrahend movwf subptr ; setzen call _get_data ; Datum holen btfsc subcarry,0 addlw 1 bcf subcarry,0 subwf d1,f ; und abziehen btfsc STATUS,C goto sub24_2 bsf subcarry,0 sub24_2 incf subptr,w call _get_data btfsc subcarry,0 addlw 1 bcf subcarry,0 subwf d2,f btfsc STATUS,C ; Wenn Ueberlauf beim MSB dann goto _sub24_0 sub24_3 clrf d0 ; Ergebnis = 0 setzen. clrf d1 clrf d2 bsf STATUS,Z return _sub24_0 bcf STATUS,Z return _div24 movwf divptr ; Pointer auf Divisor retten clrf divcnt ; div counter auf 0 setzen movf s0,w movwf d0 movf s1,w movwf d1 movf s2,w movwf d2 _div24_0 movf divptr,w call _sub24 ; Subtrahiere divptr wert und btfsc STATUS,Z ; Falls immer noch nicht 0 erreicht wiederholen goto _div24_1 movf d0,w movwf s0 movf d1,w movwf s1 movf d2,w movwf s2 incf divcnt,f goto _div24_0 _div24_1 movf divcnt,w return _printfreq movwf FSR ; Adresse fuer n0 - n1 holen movf INDF,w ; n0 nach d1 movwf d1 incf FSR,f movf INDF,w ; n1 nach d2 movwf d2 clrf d0 ; d0 = 0 -> n1n0*256 = d2d1d0 sub24 ifoffset ; 479.5 Mhz abziehen movf d0,w movwf s0 movf d1,w movwf s1 movf d2,w movwf s2 div24 div1000000 ; Ghz btfss STATUS,Z ; wenn 0 Ghz, dann Space. goto _printfreq0 movlw 0x20 goto _printfreq1 _printfreq0 addlw 0x30 _printfreq1 call _lcdwrd div24 div100000 ; Mhz addlw 0x30 call _lcdwrd div24 div10000 ; Mhz addlw 0x30 call _lcdwrd div24 div1000 ; Mhz addlw 0x30 call _lcdwrd movlw 0x2c ; comma call _lcdwrd div24 div100 ; Khz addlw 0x30 call _lcdwrd div24 div10 ; Khz addlw 0x30 call _lcdwrd print mhz return _printn movwf FSR ; movf INDF,w ; movwf s0 clrf s1 clrf s2 ; s2 loeshcen div24 div10 ; zahl durch 10 teilen addlw 0x30 call _lcdwrd ; und ausgeben movf s0,w ; rest addlw 0x30 call _lcdwrd ; als einer ausgeben return #ifdef DEBUG _printn100 movwf FSR ; movf INDF,w ; movwf s0 clrf s1 clrf s2 ; s2 loeshcen div24 div100 ; zahl durch 10 teilen addlw 0x30 call _lcdwrd ; und ausgeben div24 div10 ; zahl durch 10 teilen addlw 0x30 call _lcdwrd ; und ausgeben movf s0,w ; rest addlw 0x30 call _lcdwrd ; als einer ausgeben return #endif _storemem movwf tmp ; Speicherplatz # 0-31 0=VFO bcf STATUS,C rlf tmp,f ; Speicherplatzadresse *2 movf n0,w ; n0 in EEPROM schreiben movwf EEDATA MOVf tmp,w call _eewr movf n1,w ; n1 in EEPROM schreiben movwf EEDATA MOVf tmp,w ; Adresse addlw 1 ; +1 call _eewr ; schreiben return _recallmem movwf tmp ; Speicherplatz #0-31 bcf STATUS,C rlf tmp,f ; *2 movf tmp,w ; tmp -> w call _eerd ; EEPROM lesen movwf tmp_n0 ; -> n0 movf tmp,w ; tmp -> w addlw 1 ; w+1 call _eerd ; EEPROM lesen btfsc STATUS,Z goto _recallmem0 movwf tmp_n1 ; -> n1 incf tmp_n1,w ; n1 !=0xff (eeprom default) btfss STATUS,Z return ; nein, dann fertig _recallmem0 movlw low PLL_LOWER ; ansonsten movwf tmp_n0 ; 900Mhz als Defaultwert rein. movlw high PLL_LOWER movwf tmp_n1 return _bigger movf n0,w movwf d0 movf n1,w movwf d1 clrf d2 sub24 pll_upper return _smaller movf n0,w movwf d0 movf n1,w movwf d1 clrf d2 sub24 pll_lower return _incn call _bigger ; wenn n-2050 btfsc STATUS,Z ; < 0 dann goto _inc0 ; erhoehen movlw low PLL_LOWER ; ansonsten movwf n0 ; 900Mhz als Defaultwert rein. movlw high PLL_LOWER movwf n1 return _inc0 movlw 1 btfsc saveb,BUTTON_ENTER movlw 40 addwf n0,f ; n0 erhoehen, btfsc STATUS,C ; falls ueberlauf =0 incf n1,f ; auch n1 erhoehen. return _decn call _smaller ; wenn 900-n btfss STATUS,Z ; > 0 dann goto _dec0 ; erniedrigen movlw low PLL_UPPER ; ansonsten movwf n0 ; 2050Mhz als Defaultwert rein. movlw high PLL_UPPER movwf n1 return _dec0 movlw 1 btfsc saveb,BUTTON_ENTER movlw 40 subwf n0,f ; n0 erhoehen, btfss STATUS,C ; falls ueberlauf =0 decf n1,f ; auch n1 erhoehen. return _incmem delay2 5 movlw MEM_MAX subwf mem,w ; maximale speichernummer abziehen btfss STATUS,Z ; wenn erreicht goto _incmem0 movlw MEM_MIN movwf mem return _incmem0 incf mem,f return _decmem delay2 5 movlw MEM_MIN subwf mem,w ; maximale speichernummer abziehen btfss STATUS,Z ; wenn erreicht goto _decmem0 movlw MEM_MAX movwf mem return _decmem0 decf mem,f return _mode_change delay2 5 bcf STATUS,C rlf mode,f btfss mode,MODE_MAX ; max_mode erreicht? goto _lcdinit bsf mode,MODE_VFO ; MODE_VFO laden goto _lcdinit _rclmem movf tmp_n0,w movwf n0 movf tmp_n1,w movwf n1 goto _pllset _stomem lcdpos 0x0A print ok movf mem,w goto _storemem _mode_vfo btfsc saveb,BUTTON_PLUS ; plus gedrueckt? call _incn btfsc saveb,BUTTON_MINUS; minus gedrueckt? call _decn lcdpos 0x00 ; LCD Cursor pos0, erste Zeile print frequency lcdpos 0x40 ; LCD Cursor pos0, zweite Zeile movlw n0 goto _printfreq ; Frequenz ausgeben _mode_rcl btfsc saveb,BUTTON_PLUS ; plus gedrueckt? call _incmem btfsc saveb,BUTTON_MINUS; minus gedrueckt? call _decmem btfsc saveb,BUTTON_ENTER; enter gedrueckt? call _rclmem movf mem,w call _recallmem lcdpos 0x00 ; LCD Cursor pos0, erste Zeile print recall printn mem lcdpos 0x40 ; LCD Cursor pos0, zweite Zeile movlw tmp_n0 goto _printfreq ; Frequenz ausgeben _mode_sto btfsc saveb,BUTTON_PLUS ; plus gedrueckt? call _incmem btfsc saveb,BUTTON_MINUS; minus gedrueckt? call _decmem btfsc saveb,BUTTON_ENTER; enter gedrueckt? call _stomem lcdpos 0x00 ; LCD Cursor pos0, erste Zeile print store printn mem lcdpos 0x40 ; LCD Cursor pos0, zweite Zeile movlw n0 goto _printfreq ; Frequenz ausgeben main movlw 0xc ;Alle general purpose register loeschen movwf FSR clrloop clrf INDF incf FSR,f btfss FSR,7 goto clrloop bsf mode, MODE_VFO ; VFO Menue nach dem Start movlw 1 movwf mem delay2 10 ; Wait for power up. ;clrf PORTA ;set port A to 00000 movlw 0xf1 ;set port B to 11110001 movwf PORTB clrf TMR0 clrwdt rbank 1 clrf TRISA ;set port A to output only movlw 0xF1 ;port port B to output 1-3 movwf TRISB movlw 0x07 ; /RBPU,INT falling edge RB0... movwf OPTION_REG rbank 0 call _lcdinit ; Ports & LCD initialisieren clrw ; Akku loeschen - Speicher 0 call _recallmem ; VFO aus EEPROM lesen call _rclmem ; Pll setzen lcdpos 0 print version0 lcdpos 0x40 print version1 delay2 50 ; ca 2 Sekunden warten. call _lcdcld ; Display loeschen lcdpos 0x0 ; LCD Cursor pos0, erste Zeile print frequency lcdpos 0x40 ; LCD Cursor pos0, zweite Zeile printfreq n0 ; Frequenz ausgeben movlw 0x80+0x20+0x10 ; GIE, INTE, T0IE movwf INTCON ; ; rbank 1 ; clrf TRISA ; set RA0-RA3 to output ; rbank 0 ; main0 #ifdef DEBUG clrwdt goto main0 #endif pllset ; Pll setzen movf BUTTON_PORT,w ; Port in tmp sichern iorlw B'00001111' xorlw 0xff btfss STATUS,Z goto main1 movf irjob,w btfsc STATUS,Z goto main0 clrf irjob main1 movwf saveb btfsc saveb,BUTTON_MODE ; mode gedrueckt? call _mode_change ; mode aendern vfo-rcl-sto btfsc mode,MODE_VFO call _mode_vfo ; vfo mode auswerten btfsc mode,MODE_RECALL call _mode_rcl ; rcl mode auswerten btfsc mode,MODE_STORE call _mode_sto ; sto mode auswerten goto main0 ORG 0x397 ; must be greater or equal 0x300 ifoffset dt _IFOFFSET0,_IFOFFSET1,_IFOFFSET2 div1000000 dt _DIV1000000_0, _DIV1000000_1, _DIV1000000_2 div100000 dt _DIV100000_0, _DIV100000_1, _DIV100000_2 div10000 dt low _DIV10000, high _DIV10000, 0 div1000 dt low _DIV1000, high _DIV1000, 0 div100 dt low _DIV100, high _DIV100, 0 div10 dt low _DIV10, high _DIV10, 0 pll_lower dt low PLL_LOWER, high PLL_LOWER,0 pll_upper dt low PLL_UPPER, high PLL_UPPER,0 ; 012345678901234567890123 version0 dt "PLL V0.1 (c)04/1999 by",0 version1 dt "D. Fliegl, deti@gmx.de",0 frequency dt "Freq: ",0 recall dt "Recall: ",0 store dt "Store: ",0 ok dt "ok",0 mhz dt " MHz",0 org 0x2100 ; Initialize EEPROM Data de low PLL_LOWER, high PLL_LOWER END