logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

ATmega16 UART i BASCOM-AVR – błędne znaki klawiatury, złe odczyty na LCD

xŁolesxxx 05 Maj 2008 19:19 3811 31
Najlepsze odpowiedzi

Dlaczego ATmega16 w BASCOM-AVR odczytuje z UART-u błędne znaki z klawiatury z komputera i jak to naprawić?

Najczęściej problem wynika z nieprawidłowej transmisji RS232: między portem COM komputera a ATmegą trzeba zastosować MAX232 albo inny inwerter, bo sygnały z COM są odwrócone, a opcja `inverted` w BASCOM nie zastępuje prawdziwego inwertera [#5113724][#5112604] Jeśli używasz software UART, otwieraj kanał przez `Open "comd.x:baud,8,n,1" For Output As #n` i potem wysyłaj/odbieraj przez `Print #n` oraz `Inkey(#n)`, bo bez numeru kanału BASCOM użyje domyślnego sprzętowego COM1 [#5110489][#5110406] Warto też sprawdzić zgodność `$crystal`, `$baud` i ustawień terminala; przy 4 MHz i 1200 bps łatwo o rozjazd, więc ustaw poprawną częstotliwość i baud zgodnie z rzeczywistym taktowaniem oraz fuse bitami [#5120100][#5110646] Najpierw możesz zrobić prosty test echa, zwierając 11 i 12 na MAX232; jeśli echo wraca, tor sprzętowy jest OK, a błąd zostaje po stronie programu [#5119795] Jeżeli wysyłasz tekst typu `141`, nie deklaruj zmiennej jako `Byte`, tylko jako `String * 3`, bo `Byte` mieści wyłącznie wartość liczbową 0..255 [#5120803]
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA
  • #1 5108756
    xŁolesxxx
    Poziom 14  
    Posty: 163
    Ocena: 2
    Witam mam pewien problem probuje komunikować się z uC wysyłam mu kody klawiszy a on odczytuje je błędnie np wciskam Q a na wyświetlaczu widzę G. Co morze być tego przyczyną? Z uC komunikuje się za pomocą terminala w BASCOM-AVR, uC jest bezpośrednio połączony do komputera.
    Kod programu
    
    
    
    Dim B As Byte
    Cls                                                         
    Lcd "Napisy z peceta"                                       'Napis w górnej linijce LCD
    Lowerline                                                   ' przenieś kursor na LCD do dolnej linii
    
    Do                                                          '  pętla
       B = Inkey()                                              '  sprawdza, czy został odebrany znak (bajt)
       If B > 0 Then                                            '  jeśli jakiś znak odebrany
          Print Chr(b);                                         'odsyła odebraną literę na ekran komputera
          Lcd Chr(b)                                            'wyświetla też tę literę (znak) na LCD
       End If
    Loop Until B = 27                                           'pętla czynna do naciśnięcia klawisza ESC
    Cls
    Lcd "Koniec zabawy!"                                        'napis końcowy
    End        
    
  • REKLAMA
  • Pomocny post
    #2 5108797
    Freddy
    Poziom 43  
    Posty: 19997
    Pomógł: 1394
    Ocena: 2818
    A jak skofigurowałeś UART ?
  • #3 5108894
    xŁolesxxx
    Poziom 14  
    Posty: 163
    Ocena: 2
    Chodzi ci ile bajtów na sekundę, jeśli oto to 2400
  • #4 5109227
    grysek
    Poziom 19  
    Posty: 424
    Pomógł: 37
    Ocena: 10
    A jaka literę odsyła na terminal?? Bo ja tak wogóle to uzyłbym polecenia INPUT
    A z portu COM komputera bodajże idzie sygnał odwrócony tak więc powinieneś na koncówce TxD komputera dać inwerter (najlepiej kostke 1489 lub tez MAX232 tą osobiscie polecam bo potrzebuje zasilanie zaledwie +5V) a jak chcesz wysyłac do kompa to tez odwrócony

    mam nadzieję że okazałem się pomocny :D
  • #5 5109261
    xŁolesxxx
    Poziom 14  
    Posty: 163
    Ocena: 2
    Terminal odsyła krzaczki ale różniące się od siebie, to znaczy dla jednego klawisza za każdym jego naciśnięciem pokazuje różne krzaczki.
  • #6 5109356
    grysek
    Poziom 19  
    Posty: 424
    Pomógł: 37
    Ocena: 10
    Spróbuj zamiast INKEY uzyć INPUTBIN
    a zamiast PRINT uzyć PRINTBIN
    u mnie to zawsze działało

    i nie zapomnij otworzyc portu za pomocą instrukcji OPEN bo tego brakuje w progamie- otwórz sobie helpa i wyszukaj "OPEN" tam jest dokładnie opisane

    A co do INPUTBIN i PRINTBIN to uart programowy
  • #7 5110171
    xŁolesxxx
    Poziom 14  
    Posty: 163
    Ocena: 2
    A jak wysłać z UARTa programowego tak ustawionego

    
    Open "comd.2:2400,8,n,1" For Output As #1 
    

    Bo gdy pisze output to uC wysyła przez sprzętowy.
  • #8 5110406
    grysek
    Poziom 19  
    Posty: 424
    Pomógł: 37
    Ocena: 10
    No bo przy instrukcji PRINT, czy też PRINTBIN muszisz dodać numer kanału w tym wypadku #1
    w przeciwnym razie mikroprocesor będzie wysyłał przez domyślny COM1 a to jest UART sprzętowy

    czyli będzie to wyglądało mniej więcej tak :D

    Printbin #1; dane 
    Print #1; dane
  • REKLAMA
  • Pomocny post
    #9 5110489
    Freddy
    Poziom 43  
    Posty: 19997
    Pomógł: 1394
    Ocena: 2818
    xŁolesxxx napisał:
    A jak wysłać z UARTa programowego tak ustawionego

    
    Open "comd.2:2400,8,n,1" For Output As #1 
    

    Bo gdy pisze output to uC wysyła przez sprzętowy.


    Przepisałeś program z helpa Bascoma, ale nie dokładnie.
    Sprawdź jeszcze raz ale dokładnie zamieszczony przykład. Powinno się wszystko wyjaśnić.
    '-----------------------------------------------------------------------------------------
    
    'name                     : open.bas
    
    'copyright                : (c) 1995-2005, MCS Electronics
    
    'purpose                  : demonstrates software UART
    
    'micro                    : Mega48
    
    'suited for demo          : yes
    
    'commercial addon needed  : no
    
    '-----------------------------------------------------------------------------------------
    
     
    
    $regfile = "m48def.dat"                                     ' specify the used micro
    
    $crystal = 10000000                                         ' used crystal frequency
    
    $baud = 19200                                               ' use baud rate
    
    $hwstack = 32                                               ' default use 32 for the hardware stack
    
    $swstack = 10                                               ' default use 10 for the SW stack
    
    $framesize = 40                                             ' default use 40 for the frame space
    
     
    
     
    
    Dim B As Byte
    
     
    
    'Optional you can fine tune the calculated bit delay
    
    'Why would you want to do that?
    
    'Because chips that have an internal oscillator may not
    
    'run at the speed specified. This depends on the voltage, temp etc.
    
    'You can either change $CRYSTAL or you can use
    
    'BAUD #1,9610
    
     
    
    'In this example file we use the DT006 from www.simmstick.com
    
    'This allows easy testing with the existing serial port
    
    'The MAX232 is fitted for this example.
    
    'Because we use the hardware UART pins we MAY NOT use the hardware UART
    
    'The hardware UART is used when you use PRINT, INPUT or other related statements
    
    'We will use the software UART.
    
    Waitms 100
    
     
    
    'open channel for output
    
    Open "comd.1:19200,8,n,1" For Output As #1
    
    Print #1 , "serial output"
    
     
    
     
    
    'Now open a pin for input
    
    Open "comd.0:19200,8,n,1" For Input As #2
    
    'since there is no relation between the input and output pin
    
    'there is NO ECHO while keys are typed
    
    Print #1 , "Number"
    
    'get a number
    
    Input #2 , B
    
    'print the number
    
    Print #1 , B
    
     
    
    'now loop until ESC is pressed
    
    'With INKEY() we can check if there is data available
    
    'To use it with the software UART you must provide the channel
    
    Do
    
      'store in byte
    
      B = Inkey(#2)
    
      'when the value > 0 we got something
    
      If B > 0 Then
    
         Print #1 , Chr(b)                                     'print the character
    
      End If
    
    Loop Until B = 27
    
     
    
     
    
    Close #2
    
    Close #1
    
     
    
     
    
    'OPTIONAL you may use the HARDWARE UART
    
    'The software UART will not work on the hardware UART pins
    
    'so you must choose other pins
    
    'use normal hardware UART for printing
    
    'Print B
    
     
    
     
    
    'When you dont want to use a level inverter such as the MAX-232
    
    'You can specify ,INVERTED :
    
    'Open "comd.0:300,8,n,1,inverted" For Input As #2
    
    'Now the logic is inverted and there is no need for a level converter
    
    'But the distance of the wires must be shorter with this
    
    End
    
  • #10 5110493
    xŁolesxxx
    Poziom 14  
    Posty: 163
    Ocena: 2
    Włączyłem uart programowy ale gdy z mikro kontrolera wysyłam 111 to w terminalu pokazuje sie na przykład same Ł.
    Ponirzej kot tego programu.
    
    Dim B() As Byte
    
    Cls
    Lcd "Napisy z peceta"                                       'Napis w górnej linijce LCD
    Lowerline                                                   ' przenieś kursor na LCD do dolnej linii
        B = "111"
    Open "comd.6:300,8,n,1" For Output As #5
    Enable Interrupts
    Do                                                          '  pętla
    
    Printbin #5 , B
    
     Loop                                                       'napis końcowy
    End
    
    
    
  • #11 5110613
    Freddy
    Poziom 43  
    Posty: 19997
    Pomógł: 1394
    Ocena: 2818
    A czy tak samo ustawiłeś dane transmisji w terminalu ?
  • REKLAMA
  • #12 5110619
    xŁolesxxx
    Poziom 14  
    Posty: 163
    Ocena: 2
    Tak nawet probowałem je podczas pracy zmieniać ale to nic nie dało.
  • #13 5110646
    Freddy
    Poziom 43  
    Posty: 19997
    Pomógł: 1394
    Ocena: 2818
    A dałeś instrukcję
    $baud = 300  
  • #14 5110661
    xŁolesxxx
    Poziom 14  
    Posty: 163
    Ocena: 2
    Po dodaniu tego to się nic sie zmieniło.

    Dodano po 5 [minuty]:

    Morze ten pin trzeba jakoś wyzerować ?
  • #15 5111499
    grysek
    Poziom 19  
    Posty: 424
    Pomógł: 37
    Ocena: 10
    Dałeś kostke MAX232?? Lub jakiegokolwiek inwertera
  • #16 5111658
    xŁolesxxx
    Poziom 14  
    Posty: 163
    Ocena: 2
    Nie, nic takiego nie dawałem.
  • #17 5111755
    grysek
    Poziom 19  
    Posty: 424
    Pomógł: 37
    Ocena: 10
    Bo ja tez miałem ten problem... i okazało się że układ nie chciał działac ponieważ transmisja danych przebiegała w nieprawidłowy sposób (bity były odwrócone 1 - 0 i 0 - 1)

    A to wszystko dlatego że port COM komputera wysyła sygnał odwrócony bo na wyjsciu ma inveretra i ty tez musisz takiego dać żeby transmisja była prawidłowa... Pamietaj że na wyjsciu portu COM:
    1 logiczna - ok 10V
    0 logiczne - ok -10V
  • REKLAMA
  • #20 5112200
    xŁolesxxx
    Poziom 14  
    Posty: 163
    Ocena: 2
    Przedtem nie miałem zbytnio czasu aby to zrobić. A wracając do tematu to nic nie dało.
  • #21 5112368
    mirekk36
    Poziom 42  
    Posty: 9195
    Pomógł: 964
    Ocena: 2289
    tak w skrócie - nie jedna osoba już w podobny sposób wałkowała i męczyła transmisję z PCtem bez kostki MAX232 (to podstawa) albo chociaż bez prostych inwerterków na tranzystorach - i zawsze ta nie-jedna osoba borykała się z tym samym co ty.

    ... a później okazywało się, że ...
    Cytat:
    EUREKA !!! - gdy dałem układ MAX232 to wszystko mi działa

    wspominał ci już kolega grysek powyżej o tym a ty nadal swoje....

    po co więc wyważać głową drzwi? ale cóż może prawie każdy musi odkrywać amerykę na nowo hmm?
  • #22 5112604
    grysek
    Poziom 19  
    Posty: 424
    Pomógł: 37
    Ocena: 10
    xŁolesxxx napisał:
    To co mam zrobić, w helpie było coś takiego (chodzi o "inverted")
    
    comd.0:300,8,n,1,inverted
    


    No niby jest cos takiego lecz z praktyki wiem że to nie działa tak jak inwerter... poniewaz:

    polecenie inverted odwraca tylko bity danych,
    a prawdziwy inwerter odwraca wszystko czyli bity danych, bit startu i stopu oraz stan spoczynku
  • #23 5113530
    xŁolesxxx
    Poziom 14  
    Posty: 163
    Ocena: 2
    Znalazłem pewien schemat MAX'a232 czy nie powinno być tak że wyjścia 14 i 13 miały by być zamienione?
    Załączniki:
    • ATmega16 UART i BASCOM-AVR – błędne znaki klawiatury, złe odczyty na LCD Max232.jpg (35.61 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • Pomocny post
    #24 5113724
    mirekk36
    Poziom 42  
    Posty: 9195
    Pomógł: 964
    Ocena: 2289
    ten schemat może być prawidłowy przy założeniu, że kabel do transmisji RS232 ma zrobione przekrosowanie pomiędzy nóżkami 2 i 3 jeśli chodzi o jego bydwa końce.

    ... jeśli jednak stosuje się taki typowy kabel RS232, jaki można kupić w dowolnym sklepie, gdzie wewnątrz wszystkie nóżki są połączone jeden do jednego, to oczywiście masz rację, że trzeba wtedy na tym schemacie dokonać skrosowania czyli w tym konkretnym przypadku nóżkę nr.2 złącza DB9 podłączyć do nóżki nr.14 układu MAX232, natomiast nóżkę nr.3 złącza DB9 do nóżki nr.13 układu MAX232

    jedna tylko uwaga zamiast kondensatorów 10uF daj mniejsze 1uF lub max 4,7uF

    poza tym ten schemat jest o tyle dziwolągowaty, że widać na nim zasilanie VCC doprowadzone do układu na jego nóżkę nr.16 ale już nie ma nic na temat podłączenia masy (GND) a powinno się nóżkę nr.15 tegoż scalaczka podłączyć do GND bo bez tego nic byś nie zobaczył i byłbyś znowu bardzo zdziwiony , że nie działa.

    polecam ci na przyszłość zawsze jak masz do czynienia z jakimś scalakiem czy dowolną częścią elektroniczną to zassać sobie z netu jego notę aplikacyjną PDF. Taka nota nigdy nie kłamie i masz zawsze najbardziej wiarygodne dane i podstawowe schematy aplikacyjne. Noty PDF do wielu części można pobrać stąd:

    http://www.datasheetarchive.com/

    a jak wpiszesz tam MAX232 to zassiesz jego notę i na jednej ze stron będziesz miał jak na dłoni jego schemat aplikacyjny.

    oczywiście nie będzie tam np takiej ważnej informacji, która z kolei tu wpadła ci w ręce niechcąco a której może wcześniej nie zastosowałeś to skrosowania zrobione we wtyczce DB9, gdzie widać połączone nóżki 6 i 4 oraz 7 i 8. To bardzo istotne i zrób to u siebie. Wtedy na "końcu" uzyskasz upragniony efekt prawidłowej transmisji i już zawsze będziesz wiedział jak do tego się zabierać

    pozdrawiam
  • Pomocny post
    #25 5113750
    dawid512
    Poziom 32  
    Posty: 1439
    Pomógł: 229
    Ocena: 6
    Masz tutaj schemat który stosuje osobiscie i jest sprawdzony.
    Załączniki:
    • ATmega16 UART i BASCOM-AVR – błędne znaki klawiatury, złe odczyty na LCD max232.JPG (14.6 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #26 5119747
    xŁolesxxx
    Poziom 14  
    Posty: 163
    Ocena: 2
    Kupiłem i podłączyłem tego Max'a 232 według schematu powyżej i wysyłanie od uC działa ale z pc do uC już nie. Wiecie co morze być tego powodem? Kabel od pc na pewno nadaje ale max tego już nie przetwarza bo na nóżce 12 niema żadnych zmian.
  • Pomocny post
    #27 5119795
    mirekk36
    Poziom 42  
    Posty: 9195
    Pomógł: 964
    Ocena: 2289
    najpierw zewrzyj sobie nóżki 11 i 12 i zobacz czy to co wpisujesz w terminalu wraca do niego - powinno być echo - czyli piszesz literkę np A i powinna ona polecieć do MAX232 i wrócić do terminala i się wyświetlić - jak to będzie dobrze to możesz być pewien, że ten tor masz OK , a jeśli nie będzie tak? to sprawdź kabel i połączenia - nie ma bata, musi wtedy coś być źle przez ciebie połączone

    aha no i czy zrobiłeś na kablu te połączenia nóżek 7 i 8 oraz 6 i 4 ??????? tak jak miałeś to na tym swoim schemacie (na złączce oczywiście DB9) - sprawdź to

    jeśli echo będzie wracało to wtedy musisz szukać błędu w oprogramowaniu odbieranych znaków w uC

    tak się to po kolei sprawdza
  • #28 5119861
    xŁolesxxx
    Poziom 14  
    Posty: 163
    Ocena: 2
    Próbowałem również zwierać końcówki 11 i 12 ale nie było żadnego odzewu. I gdy wysyłam coś z uC np liczbe 141 tak jak poniżej w programie to w terminalu widzę tylko pierwszą cyfrę. 7 i 8 oraz 6 i 4 mam zwarte.
    
    $crystal = 4000000
     $baud = 1200
    Dim B() As Byte
    Dim X As Byte
    
    Cls
    Lcd "Napisy z peceta"                                       'Napis w górnej linijce LCD
    Lowerline                                                   ' przenieś kursor na LCD do dolnej linii
    
    
    Open "comd.6:1200,8,n,1" For Output As #5
    Enable Interrupts
    
    
    
        X = "141"
    
    
    
    
    
    
    
    
    
    
    
     Printbin #5 , X
    
    
    Do                                                          '  pętla
    
     B = Inkey()                                              '  sprawdza, czy został odebrany znak (bajt)
       If B > 0 Then
                                                           '  jeśli jakiś znak odebrany
          Printbin #5 Chr(b);                                   'odsyła odebraną literę na ekran komputera
           Cls
          Lcd Chr(b)
          Lowerline
          Lcd B                                                 'wyświetla też tę literę (znak) na LCD
       End If
    
    
    
    
    
    
    
    
    
     Loop                                                       'napis końcowy
    End
    
    
    
    
  • Pomocny post
    #29 5120100
    dawid512
    Poziom 32  
    Posty: 1439
    Pomógł: 229
    Ocena: 6
    Wydaje mi się że masz bład w transmisji ze względu na to że masz kwarc 4Mhz i baud 1200. Tak przy okazji zegar masz przestawiony na wewnetrzne 4MHz czy zewnetrzny kwarc? Jesli na zewnetrzny to ustawiles prawidlowo fuse bity?? Podam Ci prosty program który u mnie dziala bez zarzutu przy kwarcu 8MHz i predkosci transmisji 9600:



    
    $regfile = "m32def.dat"
    $crystal = 8000000
    $baud = 9600
    
    Dim I As Byte
    Dim Znak As String * 1
    
    Do
    
    Input "podaj wartosc I:" , I
    
    Print "wartosc I wynosi:" ; I
    
    If I = 1 Then
    Do
    Znak = Waitkey()
    
    Print "odebrano znak:" ; Znak
    
    Loop Until Znak = "k"
    
    End If
    
    If I = 2 Then
    Do
    I = Ischarwaiting()
    
    Print "flaga zawartosci bufora:" ; I
    
    Znak = Inkey()
    
    Print "w zmiennej Znak jest:" ; Znak
    
    Waitms 500
    
    Loop Until Znak = "k"
    
    End If
    
    Loop
    End
  • #30 5120147
    xŁolesxxx
    Poziom 14  
    Posty: 163
    Ocena: 2
    Program działa dzięki.

Podsumowanie tematu

✨ Problem dotyczy błędnego odczytu znaków przesyłanych z komputera do mikrokontrolera ATmega16 przez UART w BASCOM-AVR, gdzie naciśnięcie klawisza (np. "Q") skutkuje wyświetleniem innego znaku (np. "G") na LCD. Dyskusja wskazuje, że przyczyną mogą być nieprawidłowe ustawienia UART, brak odpowiedniego inwertera sygnału między portem COM a mikrokontrolerem oraz błędy w konfiguracji transmisji szeregowej. Zalecane jest stosowanie układu MAX232 lub innego inwertera (np. układ 1489) do konwersji poziomów sygnału RS232 na TTL, ponieważ port COM komputera generuje sygnał odwrócony i o napięciach ±10 V, które nie są kompatybilne bezpośrednio z mikrokontrolerem. Wskazano również na konieczność poprawnego ustawienia prędkości transmisji (baud rate), częstotliwości kwarcu, fuse bitów oraz użycia odpowiednich instrukcji BASCOM-AVR, takich jak OPEN do otwarcia portu, a także PRINTBIN i INPUTBIN dla transmisji programowej UART. Problemy z transmisją mogą wynikać z nieprawidłowego typu zmiennych w kodzie (np. przypisywanie tekstu do zmiennej typu Byte zamiast String) oraz braku odpowiedniego skrosowania linii w kablu RS232. Testy z podłączonym MAX232 wykazały, że wysyłanie danych z mikrokontrolera do PC działa, natomiast odbiór z PC do mikrokontrolera nie, co może wskazywać na błędy w połączeniach lub konfiguracji sprzętowej. Podsumowując, kluczowe jest zastosowanie układu MAX232 z poprawnym okablowaniem, właściwa konfiguracja UART w BASCOM-AVR oraz odpowiednie typy zmiennych i instrukcje do obsługi transmisji.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA