• Email
  • Forum

Include file for TEA5767

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]

Obliczenie wartości dla PLL

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

Szukanie i dostrajanie się do fali

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

Plik załącznika

$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

Przykładowy kod radyjka do testów

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]

Na koniec, chciałbym przekazać taką ciekawostkę techniczną lub można by to nazwać wskazówką. Otóż mój moduł od początku zachowywał się chimerycznie. Kosztował tylko 8zł50gr więc nie spodziewałem się rewelacji. Kiedy już moja cierpliwość się skończyła przelutowałem moduł gorącym powietrzem ze stacji lutowniczej. Od tej pory moduł spisuje się znakomicie! Jeśli więc masz też lutowany przez Chińczyków bezołowiową cyną wadliwy moduł to nie czekaj tylko łap HotAir :D

Email

Jeśli mogę w czymś pomóc, napisz.