Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

ATmega32 + USART + max232 = KLOPOTY

p_romm 12 Wrz 2005 23:11 3433 5
  • #1 12 Wrz 2005 23:11
    p_romm
    Poziom 10  

    Witam

    Sprobuje po krotce opisac moj problem z Atmega32:

    Mam uklad z Atmega32 i max232 podlaczonymi do komputera za pomoca RS232, schemat w zalaczniku (con5 sie nie przejmujcie, na roznych schemtach raz VC+ bylo podpiete do masy a raz do VCC wiec dalem zworke).
    Chcialem z atmegi wyslac do PC-eta jakies dane.

    1. Pisze prosty programik, atmega pracuje na wew. oscylatorze (4MHz)

    .include "m32def.inc"
    .device atmega32
    .cseg
    .org 0x0000

    ldi r16,25 ; dla transmisji 9600, zegar 4MHz
    out UBRRL, r16
    ; UBRRH domyslnie jest 0, dla pewnosci probowalem wersje z zerowaniem UBRRH oczywiscie biorac pod uwage wspolna przestrzen adresowa z UCSRC

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

    ldi r16, 65 ; znak A
    transmit:
    sbis UCSRA, UDRE
    rjmp transmit
    out UDR, r16
    jmp transmit

    No i dostaje smieci, smieci, smieci ...

    2. Wyciagnalem atmege i zwarlem w maxie odpowiadajace linie RxD i TxD, no i od strony PC
    sprzezenie dziala dobrze. Wiec to raczej nie max

    3. Wyprobowalem wszystkie mozliwe predkosci transmisji, taktowania zegara(1,4,8MHz) i
    monitory com-a na PC. Nadal nic

    4. Jako ze atmega pracuje na wew. oscylatorze ktorego nie kalibrowalem (bo nie wiem jak) to mozliwe ze sa smieci ze wzgledu na jego niedokladnosc. Moj kolega mial ten sam problem (ten sam scalak - pozyczylem od niego) ale jak zmniejszyl napiecie to zaczelo dzialac. No wiec ja mam zasilanie z PC (wtyk do HDD), tam jest okolo 5,12V (wachania +/- 0,04) lub z USB niecale 5, dodalem potencjometr i zaczalem sobie krecic. W pewnych momentach odbieral dobre dane,
    ale po rozlaczeniu z portem i ponownym polaczeniu znowu byly smieci !!

    6. Kolejna proba to zewn. kwarc 14,7456. Ustawilem odpowiednie fuse bits, co ciekawe na zewn. kwarcu nie umialem zaprogramowac atmegi (korzystam z PonyProg2000, blad: Veryfication Faild), wszystko inne dziala poza programowaniem, wiec programuje na wewnetrznym oscylatorze a nastepnie zmieniam na kwarc. Zgadnijcie co ?? SMIECI, SMIECI, SMIECI... albo nic !!

    7. Powrot do pkt.4 tym razem z zewn. kwarc., efekt oczywiscie taki sam jak w pkt.4.

    Czy ktos wie co sie dzieje?? O co chodzi ??

    ZA POMOC BEDE BARDZO, BARDZO, BARDZO WDZIECZNY !!!

    0 5
  • #2 13 Wrz 2005 00:29
    adammadrzak
    Poziom 10  

    Witam,

    Na moj "gust", to moze to byc przyczyna braku kalibracji wewnetrznego oscylatora RC. Jego czestotliwosc bez kalibracji moze odbiegac od nominalnej nawet o kilkanascie procent. Proponuje wiec doczytac w dokumentacji sposob kalibrowania.

    W skrocie: za pomoca softu do programowania procka odczytujemy wartosc Calibration Byte (oczywiscie dla wlasciwej f, tutaj 4MHz), po czym w programie jako jedne z pierwszych linijek dodajemy

    ldi r16,(Wartosc odczytana z Calibration Byte)
    out OSCCAL,r16

    I tyle, teraz po kazdym restarcie procek bedzie wpisywal do rejestru OSCCAL wartosc, ktora umozliwi prace na 4MHz+/-1%.

    Jesli to mialaby byc przyczyna, to zastanawia mnie tylko dlaczego nie chcialo zadzialac przy 1MHz, bo dla tej f procek sam sobie laduje wlaciwa wartosc do OSCCAL. Pytanie tylko czy przy 1MHz (i przy innych probach)nie zapominiales zmienic wartosci wpisywanej do UBRRL?

    Jak to nie pomoze, to pozostaje upewnic sie, ze dograne sa ustawienia predkosci transmisji, bo nie posadzalbym o generowanie takich smieci ukladu polaczen czy MAXa.

    Fakt, ze u kolegi tez byl taki problem, a znikal po obnizeniu zasilania tylko potwierdza to, o czym napisalem, bo wraz ze zmianami napiecia zasilajacego zmienia sie tez f osc wewnetrznego (nominalnie dla 5V -> 4.0MHz, ale dla 3V juz tylko 3.8MHz, czyli zmiana az o 5%).

    Wszystkie moje wywody burzy jednak test z zewnetrznym kwarcem. Ale sprobowac kalibracji nie zaszkodzi...

    Pozdrawiam!

    0
  • #3 13 Wrz 2005 01:26
    LordBlick
    VIP Zasłużony dla elektroda

    No to może zaproponuję własne podejście do USART w AVRasm2 (AVRStudio) :
    - Inicjalizacja (Częstotliwość zegara ustawiasz gdzieś wcześniej w kodzie #define F_CPU=14745600 - czy jakakolwiek inna, jaka jest, oraz #define USART_BAUD=19200 - mozna zmieniać do woli na odpowiednie ustawienia w terminalu, a zaglądanie do tabelek można sobie podarować) :

    Code:
    #define USART_BAUD   115200
    
    #include <USART.inc>
    USARTInit:
    ;-----------------------------------------------
    .ifdef UBRRH
       ldi DataAcc, HIGH(_UBBR_(F_CPU,USART_BAUD))
       #message "Setup UBRRH"
       out UBRRH, DataAcc
    .endif
       ldi DataAcc, LOW(_UBBR_(F_CPU,USART_BAUD))
    .ifdef UBRRL
       #message "Setup UBRRL"
       out UBRRL, DataAcc
    .else
       .ifdef UBRR
          #message "Setup UBRR"
          out UBRR, DataAcc
       .else
          #error "Althroght UBRRL And UBRR NOT Defined"
       .endif
    .endif
    ; - - - - - - - - - - - - - - - -
    .ifdef UCSRC
       .ifdef URSEL
       #message "Using 1<<URSEL - UCSRC selecting bit"
          ldi DataAcc, 1<<URSEL|DATA_BITS_8|PARITY_NONE|STOP_BITS_1
       .else
       #message "Skipping 1<<URSEL - undefined in this device"
          ldi DataAcc, DATA_BITS_8|PARITY_NONE|STOP_BITS_1
       .endif
       #message "Setup UCSRC"
          out UCSRC, DataAcc
    .endif
    ; - - - - - - - - - - - - - - - -
       ldi DataAcc, 1<<RXCIE|1<<RXEN|1<<TXEN
    .ifdef UCSRB
       #message "Setup UCSRB"
       out UCSRB, DataAcc   ; enable RXint and enable tx/rx
    .else
       .ifdef UCR
          #message "Setup UCR"
          out UCR, DataAcc   ; enable RXint and enable tx/rx
       .else
          #error "Altrhoght UCSRB And UCR NOT Defined"
       .endif
    .endif
    ; - - - - - - - - - - - - - - - -
       ret
    USART.inc :
    Code:
    #ifndef __USART_HEAD
    
    #define __USART_HEAD

    .ifdef UBRR
    #define _UBRR
    .endif

    .ifdef UBRRH
    #define _UBRRH
    .endif

    .ifdef UBRR0H
    #define _UBRR0H
    .endif

    .ifdef UBRR1H
    #define _UBRR1H
    .endif

    #ifdef F_CPU
       #if (defined(USART_BAUD) && defined(_UBRRH)) || (defined(USART0_BAUD)\




         && defined(_UBRR0H))|| (defined(USART1_BAUD) && defined(_UBRR1H))
          #define PARITY_NONE 0
          #define PARITY_EVEN (1<<UPM1)
          #define PARITY_ODD ((1<<UPM1)|(1<<UPM0))
          #define STOP_BITS_1 0
          #define STOP_BITS_2 (1<<USBS)
          #define DATA_BITS_5 0
          #define DATA_BITS_6 (1<<UCSZ0)
          #define DATA_BITS_7 (1<<UCSZ1)
          #define DATA_BITS_8 ((1<<UCSZ1)|(1<<UCSZ0))
          #define DATA_BITS_9 ((1<<UCSZ2)|(1<<UCSZ1)|(1<<UCSZ0))
       #elif ~(defined(DATA_BITS_9)) && (defined(UART_BAUD) || defined(USART_BAUD)) && defined(_UBRR)
          #define DATA_BITS_8 0
          #define DATA_BITS_9 (1<<CHR9)
       #endif
       #if defined(UART_BAUD) || defined(USART_BAUD) || defined(USART1_BAUD) || defined(USART1_BAUD)
          #define _UBBR_(_F_X, _X_BAUD) ((_F_X/(16*_X_BAUD))-1)
          //#define _UBBR_ERROR_RATE_ 100*((16*USART_BAUD*INT(F_CPU/(16*USART_BAUD)))/F_CPU-1)
          #if ~(defined(UART_BAUD)) && (defined(_UBRRH) || defined(_UBRR0H) || defined(_UBRR1H))
             #define _UBBR2X_(_F_2X, _2X_BAUD) ((_F_2X/(8*_2X_BAUD))-1)
             //#define _UBBR_ERROR_RATE_2X_ 100*((8*USART_BAUD*INT(F_CPU/(8*USART_BAUD)))/F_CPU-1)
          #endif
          #ifdef USART_BAUD
             #message "_UBBR_ == " _UBBR_(F_CPU,USART_BAUD)
          #elif defined(UART_BAUD)
             #message "_UBBR_ == " _UBBR_(F_CPU,UART_BAUD)
          #endif
          #if defined(USART_BAUD) && defined(_UBRRH)
             #message "_UBBR2X_ == " _UBBR2X_(F_CPU,USART_BAUD)
          #endif
          #if defined(USART0_BAUD) && defined(_UBRR0H)
             #message "_UBBR2X_0 ==" _UBRR2X_(F_CPU,USART0_BAUD)
          #endif
       #else
          #error "Undefined Baudrate"
       #endif
    #else
       #error "Undefined F_CPU"
    #endif

    #endif // ifndef __USART_HEAD
    Potem tylko rcall USARTInit i USART jest ustawiony.
    Oczywiście wszelkie przeróbki na swoją modłę wskazane ;)
    P.S. Starałem się, aby powyższe procedurki działały bez modyfikacji na jak najwiekszej ilości odmian AVR, nie tylko ATmega32... ;)
    --
    Pozdrawiam, Daniel

    0
  • #4 13 Wrz 2005 10:23
    p_romm
    Poziom 10  

    1. Przy kolejnych probach UBBRL oczywiscie wpisywalem, zrobilem nawet taki program w ktorym probowalem dostroic nadawanie za pomoca UBBRL, zmienialem jego wartosci, wysylalem na PC, nastepepnie wracalo z PC i jesli odebrany znak bylby dobry to wtedy znalazlem wartosc UBBRL, no ale oczywiscie nie zadzialalo

    2. Dzieki za progs, ale probowalem juz kilku programow, no i of course ciagle to samo.

    3. Tak sie zastanawiam czy moze nie jest zepsuty UART w PC (w co watpie), bede musial to sprawdzic.

    4. Skoro u kumpla ten problem znikl przy zmianie napiecia to czemu nie chce u mnie zniknac, moze mam za malo czuly potencjometr ??:P

    5. Zastanawiam sie czy moze tez na to nie wplywaja te maly wahania napiecie zasilania, no bo ciekawym jest to ze czasami zaczyna odbierac dobre dane, a po rozlaczeniu z portem i ponownym polaczeniu w PC (lub odcieciu zasilania w Atmedze) znowu ida smieci.

    6. Oczywiscie kalibracji sprobuje i program tez wgram :)

    0
  • #5 13 Wrz 2005 14:18
    LordBlick
    VIP Zasłużony dla elektroda

    A może problem tkwi w zakłóceniach w zasilaniu ? Można spróbować na innym stabilizowanym zasilaczu ? Nieobciażony lub przeciążony zasilacz PC może być czasem problematyczny... ;)

    0
  • #6 15 Wrz 2005 10:32
    p_romm
    Poziom 10  

    Z kumplem udalo sie nam to wykminic !! :) :) :)

    First: Nie mialem kondensatra przy zasilaniu Max-a,oraz ogolnie przy zasilananiu nie mialem kondensatora, wobec czego cala transmisja byla niestabilna

    Second: Pisalem ze czasami przy ustaleniu napiecia przychodza dobre dane a nastepinie po rozlaczeniu z portem i ponownym polaczeniu zle. Otoz to nie byl blad, do transmisji nie uzywalem zadnych lini sterujacych, tylko RxD i TxD, wobec czego jak Atmega ciagle wysylala dane do PC i ja wlaczalem port to zalezy jak trafialo UART (PC ) zaczynal interpretowac znaki od polowy, no bo tak naprawde nie wiedzial gdzie jest poczatek i dlatego byly smieci. Jak port mam ciagle wlaczony i rozlaczam wylaczam atmege to wszytko jest git

    No to tera mnie czeka walka z transmisja w druga strone (PC->Atmega) :P

    Tenks all za pomoc !

    0