Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[Atmega8] Sterownik urządzeń (klawiatura + podczerwień)

lukasz_16 25 Jul 2008 21:09 3704 11
Altium Designer Computer Controls
  • #1
    lukasz_16
    Level 11  
    Witam,
    Zaprojektowałem sterownik, który docelowo ma służyć do włączania różnych urządzeń elektrycznych.
    Włączanie ma odbywać się za pomocą klawiatury matrycowej 4x4 oraz/lub pilota (RC5).

    - Zasilanie układu to +5V z zasilacza stabilizowanego (dlatego w projekcie nie ma stabilizacji napięcia zasilającego).
    - Dioda podłączona do mikrokontrolera ma spełniać rolę "diody diagnostycznej" np. zamigać kilka razy po zmianie stanu któregoś z wyjść uC.
    - Odbiornik podczerwieni do TSOP1736.
    - Wyjścia ULN'a będę podłączone do przekaźników z cewką 5V

    Zwracam się z prośbą o zweryfikowanie mojego projektu (czy nie ma jakiś "wad konstrukcyjnych") oraz o pomysły na jego usprawnienie (głównie chodzi o kod programu).
    Proszę o wyrozumiałość, gdyż dopiero zaczynam swoją przygodę z mikrokontrolerami :)

    [Atmega8] Sterownik urządzeń (klawiatura + podczerwień)

    Code:
    ' --- Schemat polaczen ---
    
    ' TSOP1736              ( input )  -> D.2 (INT0)
    ' Dioda diagnostyczna   ( output ) -> D.7
    ' Klawiatura 4x4        ( input )  -> B.0 - B.7
    ' ULN2803               ( output ) -> C.0 , C.1 , C.2 , C.3 , C.4 , C.5 , D.5 , D.6

    $regfile "m8def.dat"
    $crystal = 1000000

    Config Rc5 = Pind.2

    ' klawiatura matrycowa
    Config Kbd = Portb , Debounce = 500 , Delay = 100

    Config Portc.0 = Output
    Config Portc.1 = Output
    Config Portc.2 = Output
    Config Portc.3 = Output
    Config Portc.4 = Output
    Config Portc.5 = Output
    Config Portd.5 = Output
    Config Portd.6 = Output

    Out1 Alias Portc.0
    Out2 Alias Portc.1
    Out3 Alias Portc.2
    Out4 Alias Portc.3
    Out5 Alias Portc.4
    Out6 Alias Portc.5
    Out7 Alias Portd.5
    Out8 Alias Portd.6

    Config Portd.7 = Output

    Diagled Alias Portd.7

    Enable Interrupts

    ' Zmienne
    Dim Address As Byte
    Dim Command As Byte
    Dim Key As Byte

    Dim Dled As Bit
    Dim Dledcount As Integer
    Dim Temp As Integer

    ' Deklaracje procedur
    Declare Sub Allon
    Declare Sub Alloff
    Declare Sub Diag


    ' Glowny program

    Gosub Alloff
    Do
       Key = Getkbd()
          If Key <> 16 Then
             Gosub Diag

             Select Case Key
                Case 1 : Out1 = Not Out1
                Case 2 : Out2 = Not Out2
                Case 3 : Out3 = Not Out3
                Case 4 : Out4 = Not Out4
                Case 5 : Out5 = Not Out5
                Case 6 : Out6 = Not Out6
                Case 7 : Out7 = Not Out7
                Case 8 : Out8 = Not Out8
                Case 10 : Gosub Allon
                Case 12 : Gosub Alloff
             End Select

          End If

       Getrc5(address , Command)
          If Address = 1 Then
             Command = Command And &B01111111
             Gosub Diag

             Select Case Command
                Case 1 : Out1 = Not Out1
                Case 2 : Out2 = Not Out2
                Case 3 : Out3 = Not Out3
                Case 4 : Out4 = Not Out4
                Case 5 : Out5 = Not Out5
                Case 6 : Out6 = Not Out6
                Case 7 : Out7 = Not Out7
                Case 8 : Out8 = Not Out8
                Case 9 : Gosub Allon
                Case 10 : Gosub Alloff
             End Select

          End If
    Loop
    End
    'KONIEC GLOWNEGO PROGRAMU

    'dioda diagnostyczna
    ' zmiana stanu diody w co 25 wywolaniu procedury
    Sub Diag
       If Dledcount = 0 Then
          If Dled = 0 Then
             Dledcount = 1000
          End If
          Dled = Not Dled
       End If

       If Dled = 1 Then
          Temp = Dledcount Mod 25
          If Temp = 0 Then
             Diagled = Not Diagled
          End If
       End If

       Decr Dledcount
    End Sub

    'wszystkie wlaczone
    Sub Allon
       Reset Out1 : Reset Out2 : Reset Out3 : Reset Out4 : Reset Out5 : Reset Out6 : Reset Out7 : Reset Out8
    End Sub

    'wszystkie wylaczone
    Sub Alloff
       Set Out1 : Set Out2 : Set Out3 : Set Out4 : Set Out5 : Set Out6 : Set Out7 : Set Out8
    End Sub
  • Altium Designer Computer Controls
  • #2
    mirekk36
    Level 42  
    hmm wydaje się, że koniecznie powinieneś dać także VCC do nóżki procka AVCC oraz GND do nóżki AGND. Poza tym wejście AVREF można dla spokoju przetwornika podłączyć kondensatorkiem 100nF do masy.

    kondensator 100uF, który mam nadzieję umieszczasz blisko nóżek procka możesz spokojnie zmniejszyć do wartości 47uF albo nawet 22uF - ale za to nie powinieneś nigdy zapominać, że zawsze ale to zawsze prawie do każdego aktywnego scalaka że tak powiem powinno się dawać jeszcze na nóżkach zasilania także kondensatorek 100nF (tego nigdy przy procku nie powinno zabraknąć)

    to tyle tak na gorąco odnośnie schematu, który jak na początkującego b.fajnie narysowałeś w eagle a nie tak jak niektórzy, połączenia puszczają na ukos :)

    Dodano po 3 [minuty]:

    odnośnie programu tak na początek bez wielkiego wgłębiania się to warto chyba abyś dał obsługę Getrc5 w przerwaniu a w pętli głównej tylko sprawdzał flagę i w zależności od niej odczytywał jaki kod klawisza nadleciał z pilota. Samo polecenie Getrc5 w pętli głównej będzie wprowadzało małe opóźnienie i twoja klawiaturka czasem może być "narowista", jakby klawisze od razu nie reagowały
  • #3
    Dr.Vee
    VIP Meritorious for electroda.pl
    Witam,

    Koniecznie 100nF pomiędzy VCC i GND procesora.
    Możesz dodać złącze ISP, do programowania procesora bez usuwania go z układu.

    Pozdrawiam,
    Dr.Vee
  • Altium Designer Computer Controls
  • #5
    mirekk36
    Level 42  
    popełniłem swego czasu taką obsługę Getrc5 w przerwaniu z wykorzystaniem bitu Toggle, który przydaje się do sprawdzenia czy mamy wciąż wciśnięty klawisz - wtedy zmienna Repeat = 1 a gdy tylko raz to Repeat = 0. To się czasem przydaje i fajnie można wykorzystać, oto przykładzk - hmmm może troszkę rozbudowany bo z wstawkami asemblerowymi ale można je pominąć jak coś i zastąpić czystym bascomem, który jest w komentarzach wstawek asemblerowych :)

    Code:
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    
    '''''''''''''''''  konfiguracja przerwania i  zmiennych  ''''''''''''''
    '''''''''''''''''  do obsługi kodów z pilota IR - RC5    ''''''''''''''
    '''''''''''''''''''------------------------------------''''''''''''''''
    Config Rc5 = Pind.3 , Timer = 2
    Dim Address As Byte , Command As Byte                       ' zmienne przechowujące ostatnio odebrany adres i kod z pilota
    Dim Ir_flag As Byte                                         ' FLAGA - ustawiana w przerwaniu po odebraniu sygnału z pilota
    Dim Toggle_bit As Byte , Last_toggle_bit As Byte            ' zmienne pomocnicze dla ustalenia REPEAT klawisza
    Last_toggle_bit = 2                                         ' na początku trzeba ustawić wartość inną niż ZERO lub JEDEN
    Dim Repeat As Byte                                          ' zmienna przyjmuje wartość 1 gdy klawisz jest w trybie REPEAT (cały czas wciśnięty)
    Repeat = 0                                                  '
    Ir_flag = 0                                                 ' zerowanie zmiennych

    On Int1 Int1_rc5                                            ' obsługa odbioru kodów z pilota Getrc5
    Config Int1 = Low Level                                     ' wyzwalanie przerwania niskim poziomem
    Enable Int1                                                 ' aktywacja przerwania INT1

    Enable interrupts
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''


    tu akurat używałem do obsługi Getrc5 timera2 ale można dać bez tego parametru i będzie działał domyślnie na timerze0

    potem obsługa przerwania:
    Code:
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ''''''''''''                                     '''''''''''''''''''''''''''
    ''''''''''''   Obsługa przerwania PILOTA IR RC5  '''''''''''''''''''''''''''
    ''''''''''''                                     '''''''''''''''''''''''''''
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Int1_rc5:
       Disable Int1
       Enable Interrupts
       If Ir_flag = 0 Then
          Getrc5(address , Command)
          Ir_flag = 1
       End If
    Return
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''


    a potem gdzieś w pętli głównej:

    Code:
       '''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    
       '''''''''''''''''''''''''''''''''''''''''''''''''''''''''
       ' obsługa odebranego kodu z pilota IR
       '''''''''''''''''''''''''''''''''''''''''''''''''''''''''
       '''''''''''''''''''''''''''''''''''''''''''''''''''''''''
       If Ir_flag = 1 Then
          If Address <> 255 Then

             ' dzięki asemblerowi oszczędzamy tu prawie 100 bajtów pamięci
             ' i optymalizujemy program pod kątem szybkości
             ' - ustawienie zmiennej REPEAT
             ' - rozdzielenie komendy z pilota (Command) i bitu Toggle (Toggle_bit)
             $asm
                'Toggle_bit = Command.7
                lds   r16, {Command}
                ldi   r17, 1
                sbrs  r16, 7
                clr   r17
                sts   {Toggle_bit}, r17
                'Command = Command And &B01111111
                andi  r16, &b01111111
                sts   {Command}, R16
                'If Last_toggle_bit = Toggle_bit Then Repeat = 1 Else Repeat = 0 End If
                lds   r16, {Last_toggle_bit}
                clr   r18
                cp    r16, r17
                brne  not_set_tg_bit
                ldi   r18, 1
             Not_set_tg_bit:
                sts   {Repeat}, r18
                'Last_toggle_bit = Toggle_bit
                sts   {Last_toggle_bit}, r17
             $end Asm

             '---------------------------------------------------
             '---------------------------------------------------
             '       Tu --> własna obsługa  kodów z pilota
             '---------------------------------------------------
             Cls
             Lcd "adr: " ; Address ; " kod: " ; Command ;
             Lowerline
             Lcd "Toggle: " ; Toggle_bit ; "  R:" ; Repeat
             '---------------------------------------------------
             '---------------------------------------------------
          End If


          Ir_flag = 0                                           ' wyzerowanie flagi aby możliwy był kolejny odbiór danych z pilota
          Enable Int1                                           ' odblokowanie przerwania do obsługi odczytu pilota
       End If
       '''''''''''''''''''''''''''''''''''''''''''''''''''''''''
       ''''''''''''''''''''''''''''''''''''''''''''''''' koniec obsługi IR
       '''''''''''''''''''''''''''''''''''''''''''''''''''''''''


    Dodano po 1 [minuty]:

    taaak i kolega Balu ma rację - nie zauważyłem, koniecznie musisz podciągnąć linię sygnałową z czujnika IR do VCC za pomocą jakiegoś rezystorka

    Dodano po 4 [minuty]:

    aha - i jeszcze jedno ten kondensatorek 100uF przy odbiorniku IR też jest zbyt gigantyczny wg mnie, wystarczy nawet 4,7uF ale musisz go dać za rezystorkiem 220R, bezpośrednio przy nóżce VCC odbiornika bo tak to ten rezystorek troszkę nie ma sensu
  • #6
    dawid512
    Level 32  
    Quote:
    aha - i jeszcze jedno ten kondensatorek 100uF przy odbiorniku IR też jest zbyt gigantyczny wg mnie, wystarczy nawet 4,7uF ale musisz go dać za rezystorkiem 220R, bezpośrednio przy nóżce VCC odbiornika bo tak to ten rezystorek troszkę nie ma sensu


    Ma sens, z kondensatorem 100uF działa pięknie i nie ma zakłóceń.
  • #7
    mirekk36
    Level 42  
    sorki kolego dawid512 ale chyba nie do końca rozumiesz pewnej różnicy pomiędzy takim podłączeniem rezystora i kondensatora jakie pokazał autor - a pomiędzy tym jak należy to zrobić aby zniwelować wpływ zakłóceń na linii zasilania - które zostało przedstawione w nocie aplikacyjnej. Proponuję ci przyjrzeć się temu rozwiązaniu, przemyśleć i wtedy zrozumiesz dlaczego może być mniejszy kondensator ale przy nóżce scalaka IR - TFMS, przed rezystorem. I dlaczego w schemacie autora sam rezystor nie ma sensu.


    [Atmega8] Sterownik urządzeń (klawiatura + podczerwień)
  • #8
    lukasz_16
    Level 11  
    mirekk36 wrote:
    sorki kolego dawid512 ale chyba nie do końca rozumiesz pewnej różnicy pomiędzy takim podłączeniem rezystora i kondensatora jakie pokazał autor - a pomiędzy tym jak należy to zrobić aby zniwelować wpływ zakłóceń na linii zasilania - które zostało przedstawione w nocie aplikacyjnej. Proponuję ci przyjrzeć się temu rozwiązaniu, przemyśleć i wtedy zrozumiesz dlaczego może być mniejszy kondensator ale przy nóżce scalaka IR - TFMS, przed rezystorem. I dlaczego w schemacie autora sam rezystor nie ma sensu.


    Koledze dawidowi512 chyba nie chodziło o umiejscowienie kondensatora, ale o jego pojemność. Niby w nocie katalogowej TSOP1736 zalecają kondensator 4.7µF, ale znalazłem w necie, opisy przypadków że ludziom wszystko zaczynało działać dopiero po zamontowaniu kondensatora o większej pojemności np. 100µF.
  • #10
    lukasz_16
    Level 11  
    Zamieszczam poprawiony schemat. Mam nadzieję, że już wszystko jest poprawnie.

    Za Waszą radą dodałem także złącze do programowania.

    [Atmega8] Sterownik urządzeń (klawiatura + podczerwień)
  • #11
    Dr.Vee
    VIP Meritorious for electroda.pl
    Witam,

    Zgodnie z dokumentacją atmela na pinie 3 złącza ISP w wersji 10-pinowej powinieneś mieć GND, a u Ciebie ten pin "wisi".

    Pozdrawiam,
    Dr.Vee
  • #12
    ZbeeGin
    Level 39  
    Dr.Vee wrote:
    Zgodnie z dokumentacją atmela na pinie 3 złącza ISP w wersji 10-pinowej powinieneś mieć GND, a u Ciebie ten pin "wisi".

    W różnych programatorach ten pin jest różnie wykorzysytywany. Dlatego zostawiłbym go w spokoju tak jak jest.