![[Rozmiar: 10329 bajtów]](naglowek.gif)
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ę.
![[Rozmiar: 37989 bajtów]](TEA5767resize.jpg)
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
![[Rozmiar: 37989 bajtów]](TEA debug_resize.jpg)