Ten plik możesz dołączyć do swojego projektu i w łatwy sposób mieć w nim radyjko ;)
Postanowiłem pokazać ten plik bo może komuś się przyda, albo go poprawi. Pewnie nie jedno da się zrobić lepiej. Być może sam go przepiszę, ale do tego musze znaleźć wolną chwilę.
Zacząć trzeba od tego że radyjko się dostraja do żądanej częstotliwości. Nie wpisuje się żądanej częstotliwości bezpośrednio. Jeśli chcemy dostroić radio do stacji na wybranej częstotliwości to obliczenia należy wykonać dla odpowiednio mniejszej bądź większej częstotliwości. Zależne to jest od tego z której strony podchodzimy. Dla częstotliwości 100MHz odejmujemy od niej 225kHz i dopiero kalkulujemy wartość dla PLL i każemy radyjku dostroić się "w górę". Radio samo będzie pięło się do góry aż znajdzie stację. Możemy tez do 100MHz dodać 225kHz i kazać radiu szukać w dół. Tez powinno natrafić na stację ;) Tak więc Sub obliczający wartość początkowa dla PLL wywołuję wpisując żądaną częstotliwość i określając stronę dla której maja być przeprowadzone obliczenia Przykładowo Call Calc_freq(1000 , Up)
Żeby nie używać przecinków obliczenie nieco zoptymalizowałem i podaję częstotliwość pomnożoną przez 10
Wyjaśnienia może wymagać Shift, Right, 15 - jest to nic innego jak "podziel wynik przez 32768" bo w tylu bitach zawiera się ta wartość a przy okazji jest to częstotliwość rezonatora ;)
'#----------------------------------- Sub Calc_freq(byval Freq As Word , Byval Up_down As Byte) Local Pll As Dword , Tmp_w As Integer Pll = Freq : Pll = Pll * 100 If Up_down = 1 Then Pll = Pll - 225 Else Pll = Pll + 225 Pll = Pll * 4000 Shift Pll , Right , 15 Tmp_w = Pll #if Show_debug = 1 Locate 3 , 3 : Lcd "Pll=" ; Hex(tmp_w) #endif Control(1) = High(tmp_w) Control(2) = Low(tmp_w) End Sub
Funkcja która szuka ma dodatkowy parametr czułości. Można próbować szukać stacji najmocniejszych, średnich i tych najsłabszych nawet. Wtedy jednak podczas szukania mamy więcej klikania. Funkcja która szuka potrafi się też dostroić bezpośrednio do fali którą jej podamy. Wywołanie Sub Search(1000 ,Tune , 2) Spowoduje dostrojenie się do częstotliwości 100MHz. Podanie zamiast parametru Tune parametru Up albo Down spowoduje szukanie kolejnej stacji.
Kolejne suby to Set_radio i Get_info. Set_radio wyłącza Mute - wyciszenie włączone na czas szukania stacji, a Get_info można uruchomić by co jakiś czas sprawdzić siłę sygnału i czy radio odbiera Stereo czy Mono. Nie jestem przekonany co do procedury która wybiera mocniejszy sygnał, ale nie bardzo mam jak sprawdzić bo jeszcze nie zrobiłem wersji przenośnej w plener :D
$nocompile '################################ '# TEA5767 include file by EDC # '# BARTek niveasoft(at)tlen.pl # '################################ '---[ Variables]----------------------- Dim Control(5) As Byte , Up_down As Byte , Freq As Word , Ready As Byte '---[ Constants]--------------------------------------------------------------- Const Tea5767w = &HC0 'Address TEA5767 Const Tea5767r = &HC1 Const Freq_min = 875 'The lower limit of the range 87,5 Const Freq_max = 1080 'The upper limit of the range 108,0 Const Up = 1 Const Down = 0 Const Tune = 3 'NOTE Debug is for 20x4 LCD Const Show_debug = 0 Mute Alias Control(1).7 Found Alias Control(1).7 Searching Alias Control(1).6 Direction Alias Control(3).7 Inj_side Alias Control(3).4 Stereo Alias Control(3).7 '#------------------------------------- Sub Get_info I2creceive Tea5767r , Control(1) , 0 , 5 End Sub '#------------------------------------ Sub Set_radio(byval Up_down As Byte) Control(3) = &B00000000 Control(4) = &B00010010 ' stereo ON, noise cancelling ON Control(5) = 0 Reset Searching Reset Mute I2csend Tea5767w , Control(1) , 5 End Sub '#----------------------------------- Sub Calc_freq(byval Freq As Word , Byval Up_down As Byte) Local Pll As Dword , Tmp_w As Integer Pll = Freq : Pll = Pll * 100 If Up_down = 1 Then Pll = Pll - 225 Else Pll = Pll + 225 Pll = Pll * 4000 Shift Pll , Right , 15 Tmp_w = Pll #if Show_debug = 1 Locate 3 , 3 : Lcd "Pll=" ; Hex(tmp_w) #endif Control(1) = High(tmp_w) Control(2) = Low(tmp_w) End Sub '#---------------------------------- Sub Search(byref Freq As Word , Byval Up_down As Byte , Byval Sense As Byte) Local Sensitivity As Byte , Stage As Byte , Strenght As Byte , Value As Integer Local Better_side As Byte If Up_down = Up Then Better_side = Down Else Better_side = Up Sensitivity = Sense Ready = 0 '------------------- While Ready = 0 Select Case Up_down Case Down To Up 'for direct tune changes are frozen too If Stage = 0 Then 'if station is foud freq is froozen for inject from other side If Up_down = Up Then If Freq < Freq_max Then Incr Freq Else Freq = Freq_min Decr Sensitivity End If Else If Freq > Freq_min Then Decr Freq Else Freq = Freq_max Decr Sensitivity End If End If End If End Select If Sensitivity = 0 Then Exit While If Stage = 0 Then Call Calc_freq(freq , Up_down) Else Call Calc_freq(freq , Better_side) End If Set Searching Set Mute Select Case Sensitivity 'Causes STOP Case 3 : Control(3) = &B11100000 'B011 HIGH SIGNAL Case 2 : Control(3) = &B11000000 'B010 MID Case 1 : Control(3) = &B10100000 'B001 WEAK SIGNAL End Select Control(4) = &B00010010 Control(5) = 0 If Stage = 0 Then Direction = Up_down If Up_down = 1 Then Inj_side = 0 Else Inj_side = 1 Else Direction = Better_side If Up_down = 1 Then Inj_side = 1 Else Inj_side = 0 End If I2csend Tea5767w , Control(1) , 5 Waitms 100 I2creceive Tea5767r , Control(1) , 0 , 5 If Stage = 0 Then If Found = 1 Or Up_down = Tune Then Stage = 1 Shift Control(4) , Right , 4 Strenght = Control(4) #if Show_debug = 1 Locate 2 , 19 : Lcd Strenght ; Spc(1) #endif End If Else Stage = 0 Shift Control(4) , Right , 4 Value = Strenght - Control(4) #if Show_debug = 1 Locate 3 , 19 : Lcd Control(4) ; Spc(1) #endif Value = Abs(value) #if Show_debug = 1 Locate 4 , 10 : Lcd "Diff=" ; Value ; Spc(1) #endif If Value <= 2 Then Stereo = 0 #if Show_debug = 1 Locate 4 , 2 : Lcd "IF=" ; Hex(control(3)) #endif If Control(3) > &H31 Then If Control(3) < &H3E Then Ready = 1 End If End If If Up_down = Tune Then Ready = 1 End If Wend '----------------- If Strenght > Control(4) Then Better_side = Up_down #if Show_debug = 1 Locate 4 , 19 : Lcd Better_side #endif Call Calc_freq(freq , Better_side) Call Set_radio(better_side) End Sub '======= WRITE MODE ======== '#1st Byte 'Bit7=1 MUTE ON, Bit6=1 SEARCH ON ,Rest Bits PLL (HIGH) '#2nd Byte 'All Bits PLL (LOW BYTE) '#3rd Byte 'Bit7=1 SEARCH UP,Bit6-5 SENSITIVITY STOP,Bit4=1 HIGH SIDE 'Bit3=1 Force MONO, Bit2-1=0 L&R NOT MUTE, Bit0 SWP1 '#4th Byte 'Bit7 SWP2, Bit6=1 STBY ON,Bit5=0 EURO,Bit4 XTAL 'Bit3=1 Soft Mute On,Bit2=1 HI CUT,Bit1=1 Stereo Noise ON 'Bit0 Search Indicator =1 Search On '#5th Byte 'Bit7=1 6,5MHz is ON, Bit6=1 de-emphasis Time75us/50us '====== READ MODE ============= '1st Byte ' Bit7=1 Station founded/band limit reached ' Bit6=1 Band limit reached ' Bit5-7 PLL High '3rd Byte ' Bit7=1 Stereo reception '4th Byte ' Bit7-4 ADC output '5th Byte is for Future function
Kod normalnie może pracować na wyświetlaczu 16x2 lub innym, albo nawet bez . Ten jest do testów. Mierzy siłę sygnału dla dwóch opcji dostrajania się do żądanej częstotliwości. Bada też IF Counter jak oryginalna aplikacja i sprawdza czy znajduje się on w zakresie
Kod testowany był na zestawie w którym był enkoder. Nie jest to konieczne. Wystarczą zwykłe przyciski.
$regfile = "m8adef.dat" $crystal = 8000000 $hwstack = 64 $swstack = 40 $framesize = 64 $lib "i2c_twi.lbx" ' hardware TWI Config Submode = New Config Sda = Portc.4 Config Scl = Portc.5 I2cinit Config Twi = 100000 ' 100KHz Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portc.0 , Rs = Portc.1 Config Lcd = 20 * 4 Deflcdchar 0 , 21 , 21 , 14 , 4 , 4 , 4 , 4 , 32 ' antena sign '- arrow to the right Chr(126) '- arrow to the left Chr(127) Cursor Off Cls 'timer Config Timer1 = Timer , Prescale = 256 , Compare_a = Disconnect , Compare_b = Disconnect , Clear Timer = 1 Enable Compare1a : On Compare1a Timer1_isr : Compare1a = 31249 '1s @8MHz ' config for encoder Portd.2 = 1 : Encoder_a Alias Pind.2 Portd.3 = 1 : Encoder_b Alias Pind.3 'also pin INTx Enable Int1 : On Int1 Encoder_isr : Config Int1 = Falling Dim Encoder_turn_left As Byte , Encoder_turn_right As Byte Dim Freq_str As String * 10 Dim Radio_nr As Byte , 1s As Byte , I As Byte Dim Radio_freq(5) As Word , Radio_memory(5) As Eram Word Dim Action As Byte $include "TEA5767control_2.bas" ' For I = 1 To 5 ' Radio_freq(i) = Radio_memory(i) ' If Radio_freq(i) > Freq_max Then Radio_freq(i) = Freq_min ' Next Radio_freq(1) = 880 '88,0MHz przyklad Freq = Radio_freq(1) Call Search(freq , Tune , 2) Enable Interrupts '*** MAIN LOOP *** Do 'encoder turns If 0 < Encoder_turn_left Then Decr Encoder_turn_left ' code - Up_down = Down Action = 1 Locate 1 , 15 : Lcd Chr(127) End If If 0 < Encoder_turn_right Then Decr Encoder_turn_right 'code + Up_down = Up Action = 1 Locate 1 , 15 : Lcd Chr(126) End If If Action = 1 Then Action = 0 Locate 1 , 3 : Lcd "Wait..." ; Spc(5) Lowerline : Lcd Spc(14) Call Search(freq , Up_down , 2) End If If 1s = 1 Then 1s = 0 Call Get_info Freq_str = Str(freq) Freq_str = Format(freq_str , "00.0") Locate 1 , 3 : Lcd Freq_str ; " MHz " Locate 2 , 2 If Stereo = 1 Then Lcd "STEREO" Else Lcd "MONO " Shift Control(4) , Right , 4 Locate 2 , 13 : Lcd Control(4) ; Chr(0) ; Spc(1) End If Loop End '*** END *** Encoder_isr: If Encoder_a = 0 Then Incr Encoder_turn_right Else Incr Encoder_turn_left End If Return Timer1_isr: 1s = 1 Return
Poniżej zdjęcie jak wygląda ekranik jeśli włączy się tryb informacji dodatkowych