$regfile = "m8def.dat" $crystal = 4000000 '20060822 v00 skeleton test lcd and i2c led flash '20060823 v01 fi1216 test single frequency, found out that floating point does not fit in at90s2313 '20060825 v02 all integer frequency calculations '20060827 v03 test buttons on pcf8574 '20060828 v04 test eeprom usage for setup '20060901 v05 program does not fit anymore in at90s2313, bummer!, changed to atmega8, 'xx note that lcd pinning changed from the default! '20060903 v06 changed lcd layout Config Sda = Portc.5 Config Scl = Portc.4 Config I2cdelay = 10 Config Pind.2 = Input Config Pind.6 = Output Config Int0 = Falling Config Lcd = 16 * 2 Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portb.4 , Rs = Portb.5 'I2C addresses 'pcf8574 with A2, A1, A0 tied to gnd Const Pcf8574write = &H40 Const Pcf8574read = &H41 'fi1216 with MA1 and MA0 tied to gnd Const Fi1216write = &HC0 Const Fi1216read = &HC1 'FI1216 vco frequency info 'A fixed step size of 50kHz is used 'Note: all frequencies are expressed in integers as a multiple 'of 50kHz 'example: 240.15MHz is expressed as (240.15)/0.05=4803 'example: 240.2 MHz is expressed as (240.2 )/0.05=4804 'The resulting number can directly be used as divisor, 'avoiding the need for floating-point calculations 'FI1216 vco band limits 'low limit of low band VCO : 48.25 MHz + 38.9 MHz IF Const Lowband = 1743 'low limit of mid band VCO : 170 Mhz + 38.9 MHz IF Const Midband = 4178 'low limit of high band VCO : 450 MHz + 38.9 MHz IF Const Hilband = 9778 'high limit of high band VCO : 855.25 MHz + 38.9 IF Const Hihband = 17883 'bit 7 plus bit 5= 128+32 Const Loband = &B10100000 'bit 7 plus bit 4= 128+16 Const Miband = &B10010000 'bit 5 plus bit 4= 32+16 Const Hiband = &B00110000 'Frequency up button is on bit0 of pcf8574 Const Frequp = &B11111110 'Frequency down button is on bit1 of pcf8574 Const Freqdn = &B11111101 'Step up button is on bit2 of pcf8574 Const Stepup = &B11111011 'Step down button is on bit3 of pcf8574 Const Stepdn = &B11110111 'Memory button is on bit4 of pcf8574 Const Mem = &B11101111 'Memory store button is on bit5 of pcf8574 Const Memstr = &B11011111 'Memory recall button is on bit6 of pcf8574 Const Memrcl = &B10111111 'number of vco frequency memories Const Freqmemmax = 3 'number of tries to read locked pll 'this number is rather high, but necessary at a band change Const Locktries = 250 'Maximum index of Fsteps data table Const Fstepsnum = 7 'Default Fsteps data table index Const Fstepsdefault = 0 'Fixed fi1216 frequency step value in kHz Const Fstepreal = 50 Dim Tmp As Word 'pcf8574 input port value read Dim Pcf8574port As Byte 'vco frequency Dim Vcofreq As Word Dim Tmpvcofreq As Long Dim Tmpvco As Long Dim Vcofreqstring As String * 8 Dim Tmpvcofreqstring As String * 8 'fi1216 divisor control bytes Dim Divbyte1 As Byte Dim Divbyte2 As Byte 'fi1216 control byte Dim Controlbyte As Byte 'fi1216 band byte Dim Bandbyte As Byte 'fi1216 status byte (has a.o. lock bit Dim Statusbyte As Byte '16-bit divisor bits Dim Divisor As Long Dim Tmpdivisor As Word 'counts number of pll lock tries Dim Lockcnt As Byte 'fi1216 lock bit Dim Lockbit As Byte 'actual frequency step value Dim Freqstep As Word 'frequency step as displayed on lcd Dim Freqstepdisp As String * 6 'points to the frequency step string to be used from data block Dim Freqstepindex As Byte 'frequency step in kHz Dim Freqstepreal As Long '1 if there is work to do in main loop Dim Doflag As Byte 'last memory place used Dim Lastmemnum As Byte 'flag to display mem frequency Dim Memdispflag As Byte 'do not use first eeprom byte, could be trashed during a reset Dim Eedummy As Eram Byte 'last frequency saved Dim Eelastmemnum As Eram Byte 'three frequency memories Dim Eefrequencies(Freqmemmax) As Eram Word 'sub to handle buttons Declare Sub Updfreqvalue ' sub to do the fi1216 programming Declare Sub Progfi1216 'Make all Pcf8574 pins high -> input I2cstart I2cwbyte Pcf8574write I2cwbyte 255 I2cstop 'pull up the int0 line Set Portd.2 'clear lcd, cursor off Cls Cursor Off 'If any of the buttons is pressed at power-up, restore memory defaults I2cstart I2cwbyte Pcf8574read I2crbyte Pcf8574port , Nack I2cstop If Pcf8574port <> 255 Then 'Write Default Data To Eeprom Eelastmemnum = 1 Eefrequencies(1) = 4000 Eefrequencies(2) = 5000 Eefrequencies(3) = 6000 Lcd "mem restored" Wait 2 End If On Int0 Pcfint Enable Interrupts 'int0 is used to catch pcf8474 change of input (i.e. button pressed) Enable Int0 Cls Lastmemnum = Eelastmemnum Vcofreq = Eefrequencies(lastmemnum) Freqstepindex = Fstepsdefault Freqstep = Lookup(freqstepindex , Fsteps) Freqstepdisp = Lookupstr(freqstepindex , Fstepsdisp) Freqstepreal = Freqstep * Fstepreal Doflag = 1 Memdispflag = 0 'main loop starts here Do If Doflag = 1 Then Doflag = 0 Call Updfreqvalue 'program fi1216 Call Progfi1216 End If Loop '#############################interrupt routines follow######################### 'PCF8574 interrupt routine Pcfint: 'debounce wait time Waitms 20 'read the input pins I2cstart I2cwbyte Pcf8574read I2crbyte Pcf8574port , Nack I2cstop 'Determine state of port bits If Pcf8574port <> 255 Then Doflag = 1 End If Gifr = 64 Return End '#############################subroutines follow################################ Sub Updfreqvalue 'Frequency up button If Pcf8574port = Frequp Then Tmpvcofreq = Vcofreq + Freqstep If Tmpvcofreq <= Hihband Then Vcofreq = Tmpvcofreq End If End If 'Frequency down button If Pcf8574port = Freqdn Then Tmpvcofreq = Vcofreq - Freqstep If Tmpvcofreq >= Lowband Then Vcofreq = Tmpvcofreq End If End If 'Frequency step up button If Pcf8574port = Stepup Then If Freqstepindex < Fstepsnum Then Freqstepindex = Freqstepindex + 1 Freqstep = Lookup(freqstepindex , Fsteps) Freqstepdisp = Lookupstr(freqstepindex , Fstepsdisp) End If End If 'Frequency step down button If Pcf8574port = Stepdn Then If Freqstepindex > 0 Then Freqstepindex = Freqstepindex - 1 Freqstep = Lookup(freqstepindex , Fsteps) Freqstepdisp = Lookupstr(freqstepindex , Fstepsdisp) End If End If 'Memory button If Pcf8574port = Mem Then If Lastmemnum = Freqmemmax Then Lastmemnum = 1 Else Lastmemnum = Lastmemnum + 1 End If Set Memdispflag End If 'Store button If Pcf8574port = Memstr Then Eelastmemnum = Lastmemnum Eefrequencies(lastmemnum) = Vcofreq Cls Locate 1 , 1 Lcd "Stored" Wait 1 End If 'Recall button If Pcf8574port = Memrcl Then Eelastmemnum = Lastmemnum Vcofreq = Eefrequencies(lastmemnum) Cls Locate 1 , 1 Lcd "Recalled" Wait 1 End If End Sub Sub Progfi1216 'determine divisor bytes Divisor = Vcofreq Tmpdivisor = Divisor And &B0111111100000000 'take bits 14,13,12,11,10,9,8 Shift Tmpdivisor , Right , 8 Divbyte1 = Tmpdivisor 'and shift to the right eight places Tmpdivisor = Divisor And &B0000000011111111 'take bits 7,6,5,4,3,2,1,0 Divbyte2 = Tmpdivisor 'and shift to the left eight places 'determine control byte Controlbyte = &B10001100 ' |||||||| ' |||||||OS=0 is normal operation (1 switches charge pump to high impedance state) ' ||||||| ' |||||RSA & RSB: x0 = 50kHz step; 01 = 31.25kHz step (search mode); 11 = 61.25kHz step (normal search) ' ||||| ' ||T2, T1, T0 is 001 for normal operation ' || ' |CP is 1 for fast tuning, 0 for moderate speed tuning with better residual osc FM ' | ' is always 1 'controlbyte=&B10001010 'same, except 31.25kHz step 'determine band control byte If Vcofreq < Midband Then Bandbyte = Loband Else If Vcofreq < Hilband Then Bandbyte = Miband Else Bandbyte = Hiband End If End If 'write the five control bytes to the fi1216 I2cstart I2cwbyte Fi1216write I2cwbyte Divbyte1 I2cwbyte Divbyte2 I2cwbyte Controlbyte I2cwbyte Bandbyte I2cstop 'wait some time Waitms 10 ''wait for pll lock For Lockcnt = 1 To Locktries I2cstart I2cwbyte Fi1216read I2crbyte Statusbyte , Nack I2cstop Lockbit = Statusbyte And &B01000000 If Lockbit = &B01000000 Then Locate 1 , 16 Lcd "L" Goto Plllocked End If Next Lockcnt Locate 1 , 16 Lcd "N" Wait 5 Plllocked: ' If Memdispflag <> 0 Then ' Memdispflag = 0 ' Tmp = Eefrequencies(lastmemnum) ' Tmpvco = Tmp * Freqstepreal ' Tmpvcofreqstring = Str(tmpvco) ' Vcofreqstring = Format(tmpvcofreqstring , "000.000") ' Locate 1 , 1 ' Lcd Vcofreqstring ; " MHz" ' Locate 1 , 15 ' Lcd "M" ; Lastmemnum ' Wait 1 ' End If Locate 1 , 1 Tmpvco = Vcofreq * Freqstepreal Tmpvcofreqstring = Str(tmpvco) Vcofreqstring = Format(tmpvcofreqstring , "000.000") Locate 1 , 1 Lcd Vcofreqstring ; " " ; Freqstepdisp Tmp = Eefrequencies(lastmemnum) Tmpvco = Tmp * Freqstepreal Tmpvcofreqstring = Str(tmpvco) Vcofreqstring = Format(tmpvcofreqstring , "000.000") Locate 2 , 1 Lcd Vcofreqstring Locate 2 , 15 Lcd "M" ; Lastmemnum End Sub End 'Note: when Fsteps, Fstepsdisp changes, Fstepsnum constant must be updated accordingly! 'Frequency step values available Fsteps: Data 1% , 2% , 4% , 10% , 20% , 40% , 100% , 200% 'Frequency step value in display Fstepsdisp: Data " 0.050" , " 0.100" , " 0.200" , " 0.500" , " 1.000" , " 2.000" , " 5.000" , "10.000"