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

transmisja UART AVR > PC, w terminalu 00 C0 C0 00 itd

Adam_Z 19 Lis 2006 18:19 5828 23
REKLAMA
  • #1 3241211
    Adam_Z
    Poziom 11  
    Posty: 25
    Zgłaszam problem, ponieważ mimo przeszukania forum nie znalazłem odpowiedzi. Chodzi o to, że wysyłam z mikroprocesora ATMega48 jakiś dowolny znak. Jednak w terminalu zamiast tego czego oczekuje (cały czas tej samej wartości) pojawia się ciąg znaków 00 C0 C0 00 C0 C0 00 C0 C0 itd. Nawet jeśli wpiszę inny znak do wysłania to cały czas odbieram ten sam ciąg. Sprawdziłem już 10 razy MAX232 czy dobrze podłączyłem kondensatorki, zasilanie, masę. Przez jakiś czas na początku miałem kondensator C2 w odwrotnej polaryzacji czy mógł on uszkodzić MAX-a 232. Wtyczka COM do komputera skonfigurowana jak null-modem (4-6 zwarte, 7-8 zwarte, Tx Rx naprzemiennie z prockiem, i masa na 5 pinie). Program pisze w asemblerze, ale żeby sprawdzić napisałem program w BASCOM, który umieszczam poniżej (dla informacji). W obu przypadkach dostaję to samo.
    Dim A As Byte ,
    A = $24
    Do
    Print A
    Wait 1
    Loop
    End

    Dodam, że oscylator to 7,3728 MHz. 8 bitów danych, brak parzystości, 1 bit stopu, BAUD ustawiony na 9600.
    Liczę na Waszą pomoc.
  • REKLAMA
  • #2 3241515
    adasb
    Poziom 14  
    Posty: 150
    Pomógł: 2
    Ocena: 4
    Aby sprawdzić poprawność dzialania MAXa musisz odpiąc linie TxD i RxD od mikroprocesora i wtedy zewrzyj R1out z T1in (wyprowadzenie 11 i 12 układu MAX232). Takie coś pomoże ci sprawdzić ci czy MAX poprawnie odbiera i nadaje dane. Wtedy wysyłając coś z terminala otrzymujesz spowrotem to samo co wysłałeś. Wtedy bedziesz wiedział że komunikacja z MAXem działa prawidłowo i musisz szukać błędu w programie (to znaczy masz żle skonfigurowany Uart lub żle ustawione porty mikroprocesora).
    Mam nadzieje że coś ci pomogłem.
    Pozdrawiam.
  • REKLAMA
  • #4 3241904
    Adam_Z
    Poziom 11  
    Posty: 25
    Dziękuję za podpowiedź. Przeprowadziłem zasugerowany test i wygląda jakby układ MAX232 działał prawidłowo. Niestety małe to pocieszenie dla mnie bo ostatnia rzecz którą podejrzewałem o nieprawidłowe działanie jest sprawna. Proszę zatem o podpowiedzi odnośnie programu, chociaż uważam, że niewiele da się tu pokombinować. Może zna ktoś receptę na mój problem?
  • #5 3242053
    _Robak_
    Poziom 33  
    Posty: 2208
    Pomógł: 231
    Ocena: 29
    A terminala masz dobrze ustawionego?
  • REKLAMA
  • #6 3242086
    Adam_Z
    Poziom 11  
    Posty: 25
    TAK, terminal mam ustawiony zgodnie z tym co wpisuje na procku (jeśli chodzi o program asemblerowy). Nie do końca wiem jak to jest w BASCOM, czy tez trzeba wszystko definiować (baud rate, ramke).
  • #7 3242101
    _Robak_
    Poziom 33  
    Posty: 2208
    Pomógł: 231
    Ocena: 29
    A mozesz pokazac program w asm?
  • #8 3242195
    Adam_Z
    Poziom 11  
    Posty: 25
    
    .include "m48def.inc"
    		
    .def temp = r16
    .def dane = r23
    
    
    .org $000 rjmp INIT
    
    START_T:  lds temp,UCSR0A; sprawdzenie UDREn
    		andi temp,0x20
    		breq START_T
    
    		sts UDR0,dane
    
    TEST:	    lds temp,UCSR0A; czekaj aż zostanie wysłany znak
    		andi temp,0x40  
    		breq TEST
    
    		ldi temp,0x40; wyzerowanie TXCn przez ustawianie
    		sts UCSR0A,temp
    		ret
    
    INIT:        ldi temp,high(RAMEND)
    		out SPH,temp
    		ldi temp,low(RAMEND)
    		out SPL,temp
    
    		ldi temp,0x01; sygnalizacja diodą
    		out DDRB,temp
    		out PORTB,temp
    		
    	
    		ldi temp,0x00	; poczatkowe wartosci rejestru
    		sts UBRR0H,temp; 	ustawienie BAUD na 9600
    		ldi temp,0x2F
    		sts UBRR0L,temp
    		
    		ldi temp,0x06; ustawienie ramki 
    		sts UCSR0C,temp
    
    		ldi temp,0x08; rozpoczecie transmisji
    		sts UCSR0B,temp
    		 
    		ldi dane,5
    		
    SKOK: 	   cbi PORTB,0
    		
    		rcall START_T
    
    		rjmp SKOK
  • #9 3242525
    _Robak_
    Poziom 33  
    Posty: 2208
    Pomógł: 231
    Ocena: 29
    Zamiast wpisywac wartosci do rejestrow lepiej pisac tak:
    Cytat:

    ldi r16,(1<<RXEN)|(1<<TXEN)
    out UCSRB,r16

    przynajmniej za 2 tygodnie bedziesz wiedzial o co chodzi w programie;)

    a w petli nie powinno byc? :
    
    START_T:  lds temp,UCSR0A; sprawdzenie UDREn 
          andi temp,0x20 
          cmpi temp,0x20/***/
          bne START_T /***/
    
          sts UDR0,dane
    
  • #10 3242560
    Adam_Z
    Poziom 11  
    Posty: 25
    Znam ten sposób wpisu, z przyzwyczajenia używam wpisów do rejestru (rzeczywiście po czasie można zapomnieć ale po to są komentarze). Co do tej pętli to wystarcza andi temp,0x20 bo to ustawia lub nie znacznik zera. Ale spróbuje to zmienić.
  • #11 3242609
    _Robak_
    Poziom 33  
    Posty: 2208
    Pomógł: 231
    Ocena: 29
    i jeszcze powinno byc chyba bne zamiast breq, wysylac mozna jesli UDRE jest 1, a w twojej petli jesli sie nie myle czeka az bedzie 0
  • #12 3242637
    Adam_Z
    Poziom 11  
    Posty: 25
    Pętla jest prawidłowo, ale o tej porze mogę się mylić :).
    
    START_T:  lds temp,UCSR0A; sprawdzenie UDREn
                    andi temp,0x20; maskowanie bitu UDRE
                                          ;jeśli jest 0 po maskowaniu to znaczy ze UDRE=0
                                          ;więc sprawdza dalej (skok do START_T)
                    breq START_T; jeśli było by brne to przy UDRE=0 przeszedł by   
                                            dalej
    
    
  • #13 3242649
    _Robak_
    Poziom 33  
    Posty: 2208
    Pomógł: 231
    Ocena: 29
    Tez juz troche zmeczony jestem;) ale przeanalizujmy;) Jesli UDRE jest 1 to mozna wyslac znak, po zmaskowaniu jesli zostanie 0x20 to w twojej petli wroci do START_T, bo jest breq START_T, i nie wpisuje sie nic do UDR, jesli byloby brne to jesli po zmaskowaniu zostanie 0x20(czyli mozna slac) nie idzie do START_T bo jest brne, UDR zostaje zapisany i ramka jesy wysylana:) Wiec wydaje mi sie ze tutaj jest poblem;)
  • #14 3242687
    Adam_Z
    Poziom 11  
    Posty: 25
    breq jest skok dla znacznika Z=1, wtedy gdy w temp jest 0 po maskowaniu
    brne jest skok dla Z=0, wtedy gdy w temp jest 0x20 po maskowaniu

    andi ustawia lub zeruje znacznik zera

    Pętlę tą już wypróbowałem w AVR STudio i funkcjonuje jak powinna, przed chwilą jeszcze raz sprawdziłem i jest ok.
  • #15 3243514
    Adam_Z
    Poziom 11  
    Posty: 25
    Po kolejnych testach z różnymi rodzajami kwarców wydaje mi się, że błąd wynika z procka. Wygląda na to, że nie jest to część programowa więc trzeba będzie wymienić układ i wtedy spróbować. Będę informował o swoich "postępach".
  • #16 3244748
    _Robak_
    Poziom 33  
    Posty: 2208
    Pomógł: 231
    Ocena: 29
    Sprawdzilem te petle i obie wersje sa poprawne:)
  • #17 3244834
    kaczepa
    Poziom 20  
    Posty: 238
    Pomógł: 32
    Ocena: 5
    Zmień jak poniżej

    START_T:

    sbis UCSR0A,UDRE0
    rjmp START_T
    out udr0,dane

    TEST:
    .........

    Pozdrawiam
  • #18 3244941
    mirekk36
    Poziom 42  
    Posty: 9195
    Pomógł: 964
    Ocena: 2289
    proponuję ci sprawdź to:

    clr R16
    out UCSR0A, R16

    ldi R16, 0x00
    out UBRR0H, R16
    ldi R16, 0x2F
    out UBRR0L, R16
    ldi R16, (1<<UCSZ01)|(1<<UCSZ11)
    out UCSR0C, R16
    ldi R16, (1<<TXEN)
    out UCSR0B, R16

    to jest inicjalizacja RSa, piszę o tym dlatego bo może zapomniałeś o rejestrze UCSR0A - przy inicjalizacji - a kto wie co w nim siedzi po włączeniu zasilania ;) - może jest np bit U2X0 ustawiony na 1 . Wątpię żeby trzeba było zaraz kupować nowy procek ;) - posprawdzaj jeszcze

    pozdrówka
  • #20 3245374
    Adam_Z
    Poziom 11  
    Posty: 25
    To stwierdzenie Samuraj-a może być prawdziwe. Przyczyną może być kwarc wewnętrzny. Tylko jak zmienić fuse bity w ATMega48. Spróbowałem za pomocą ISP Programmer i procek kompletnie mi nie odpowiada (wpisałem na fuse-y 0110 i nacisnąłem program). Na szczęście mam dwa jeszcze. Pytanie moje jest o zmianę fuse bitów, jak to zrobić. Jakie ustawienie zastosować? Czy da się w jakiś sposób uratować ten zaprogramowany procek?
    Dziękuje za bieżące odpowiedzi.
  • #21 3245413
    mirekk36
    Poziom 42  
    Posty: 9195
    Pomógł: 964
    Ocena: 2289
    jeśli poprzez złe zaprogramowanie fuse bitów ustawiłeś go na generator zewnętrzny to żaden problem żeby go ożywić ;) ja tak raz zrobiłem sobie z ATTiny2313. Później dołączyłem prosty generatorek kilkadziesiąt KHz na kilku bramkach TTL i znowu mogłem go przeprogramować - więc spokojnie ;) - a jak zaczynałem z RSem to też właśnie miałem ten sam problem co ty - tzn nie działał mi RS bo uC chodził na wewn oscylatorze ;) i przy pierwszej w życiu próbie zmiany fusebitów go załatwiłem ;)

    ale po reanimacji wszystko ruszyło i o dziwo wszystkie procedury do komunikacji RS też ruszyły odrazu ;)
  • #22 3245417
    Samuraj
    Poziom 35  
    Posty: 2792
    Pomógł: 286
    Ocena: 616
    Dla sprawdzenia mogłeś napisać program migacza diodą i odłączyć kwarc zewnętrzny. Wtedy byś wiedział czy chodzi na wewnętrznym generatorze czy na kwarcu.
    Nie wiem jak go ustawiłeś ale poczytaj o zablokowanych prockach,wiele o tym było.
    Rozwiązanie pewne i sprawdzone programator równoległy, tymczasowe i doraźne generator na TTL'ach (czasami pomaga - to zależy od tego jak bardzo namieszamy).
    Ja choć sam nie programuje w Bascomie (bo mam na jego temat swoje zdanie) to ustawiam nim fusebity, chyba nie widziałem narzędzia co łatwiej było by napisane co zmieniamy.
  • REKLAMA
  • #23 3247599
    kaczepa
    Poziom 20  
    Posty: 238
    Pomógł: 32
    Ocena: 5
    "Odpaliłem" Twój program na Atmega32 (nie mam pod ręką Atmega48).Oczywiście pozmieniałem niektóre ustawienia (USART).Program zaczął pracować dopiero po wprowadzeniu zmiany opisanej w moim poprzednim poście i wysyła 5-teczki przez RS.
    Pozdrawiam
  • #24 3247785
    Adam_Z
    Poziom 11  
    Posty: 25
    Dziękuje wszystkim, którzy pomagali w rozwiązaniu problemu. W szczególności Samurajowi i kaczepie. W końcu transmisja zaczęła działać prawidłowo. Główny problem tkwił w zmianie fuse bitów. Po przestawieniu na zewnętrzny rezonator kwarcowy i wyłączeniu dzielnika zegara przez 8 mikrokontroler zaczął funkcjonować. Okazało się także że po pierwszej zmianie fuse bitów mikrokontroler był ok, jedynie kwarc został źle przylutowany. Ostatnia zmiana jaką wprowadziłem (naprowadzony przez kaczepę) to zlikwidowanie dwóch linijek.
    
    ldi temp,0x40
    sts UCSR0A,temp
    

    Temat uważam za rozwiązany. Chyba że ktoś ma jeszcze jakieś pytania.
    Pozdrawiam.
    Adam_Z

Podsumowanie tematu

✨ Problem dotyczył transmisji UART między mikrokontrolerem ATMega48 a komputerem PC, gdzie w terminalu pojawiał się powtarzający się ciąg znaków 00 C0 C0 00 zamiast oczekiwanego znaku. Sprawdzono poprawność podłączenia układu MAX232, który okazał się sprawny po teście pętli zwrotnej (echo). Dyskusja skupiła się na poprawnej konfiguracji UART, w tym ustawieniach rejestrów UCSR0A, UBRR0H/L, UCSR0B, UCSR0C oraz prawidłowej obsłudze bitu UDRE w pętli wysyłania danych. Zwrócono uwagę na możliwe błędy w programie asemblerowym, a także na konieczność prawidłowego ustawienia fuse bitów mikrokontrolera, aby korzystał z zewnętrznego rezonatora kwarcowego 7,3728 MHz zamiast generatora wewnętrznego. Po poprawnym ustawieniu fuse bitów i wyłączeniu dzielnika zegara przez 8, transmisja UART zaczęła działać prawidłowo. Usunięto także zbędne linie kodu manipulujące rejestrem UCSR0A. Wskazano, że błędne ustawienia fuse bitów mogą spowodować brak komunikacji, ale można je skorygować za pomocą programatora ISP lub generatora TTL do reanimacji mikrokontrolera. Ostatecznie problem rozwiązano poprzez korektę fuse bitów i poprawne lutowanie kwarcu.
Wygenerowane przez model językowy.
REKLAMA