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

Jak wysłać znak z ATmega16 do komputera przez RS232? Początki w C i WinAVR

tom163 15 Maj 2008 16:32 6891 14
REKLAMA
  • #1 5143589
    tom163
    Poziom 10  
    Posty: 7
    Witam wszystkich,

    chciałbym na początku zaznaczyć, że jestem zielony w tych sprawach i dopiero zaczynam wszystko poznawać.

    Kupiłem sobie zestaw edukacyjny z atemega16 na którym znajdują się różne peryferia takie jak diody, klawiatura itp. Jest także interfejs RS232 połączony do MAX232 i z tego wyprowadzone są piny.

    Chciałbym prosić o pomoc jak wysłać do komputera jakiś znak za pomomocą tego interfejsu? Poprzednie proste programy takie jak miganie diodą itp pisałem w C pod WinAVR.

    Wiem, że na elektrodzie jest sporo tematów odnośnie komunikacji poprzez RS232, ale żaden który znalazłem nie tłumaczy tematu od podstaw.

    Dowiedziałem się, że muszę wpierw zainicjować komunikacje, następnie napisać funkcję do wysyłania znaku. Ale czy muszę inicjować też jakieś porty żeby coś wysyłać??

    Proszę o pomoc, ewentualnie linka gdzie mogę znaleźć podstawowe informacje.
  • REKLAMA
  • REKLAMA
  • #3 5144157
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    tom163 napisał:
    Proszę o pomoc, ewentualnie linka gdzie mogę znaleźć podstawowe informacje.


    nawet dwa:
    http://www.google.pl/
    https://www.elektroda.pl/rtvforum/search.php

    brak konkretnego pytania = brak konkretnej odpowiedzi. nikt nie bedzie ci robil wykladu, skoro nie wiadomo co wiesz, a czego nie.

    0x41 0x56 0x45!!
  • #4 5144215
    Balu
    Poziom 38  
    Posty: 4397
    Pomógł: 323
    Ocena: 48
    Koledze pewnie chodziło o ustawienie DDRx... ja myślę,że już bym to ze 3 razy sprawdził, był na piwie i na randce nim by mi ktoś odpisał (tudzież nim bym to sprawdził w datasheecie) ale skoro kolega lubi czekac...
  • REKLAMA
  • #5 5145971
    tom163
    Poziom 10  
    Posty: 7
    Witam, macie racje. Nie zadałem konkretnego pytania.
    Posiedziałem sobie jeszcze trche z tym wszystkim i znalazłem taki fragment programu:

    #define CPU_Hz 8000000 // częstotliwość zegara w Hz
    #define OSC 8 // częstotliwość zegara w MHz
    
    #define BAUD 9600 // prędkość transmisji po RS232
    #define MYUBRR CPU_Hz/8/BAUD-1
    
    
    // **** fukcje dla RS232 ****
    void UART_init(unsigned int ubrr) // inicjalizacja
    {
    UBRRH = (unsigned char) (ubrr>>8); // ustawienie prędkości
    UBRRL = (unsigned char) ubrr;
    UCSRB = (1<<RXEN)|(1<<TXEN); // transmisja dwukierunkowa, odbieranie/nadawanie
    UCSRC = (1<<URSEL)|(3<<UCSZ0); // ustawienie 8 bitów danych i 1 bity stopu
    }
    
    
    void USART_out (unsigned char data) // wysłanie znaku
    {
    while (!(UCSRA & (1<<UDRE)));
    UDR = data;
    }
    
    
    unsigned char USART_in (void) // odebranie znaku
    {
    while (!(UCSRA & (1<<RXC)));
    return UDR;
    }
    
    int main(void)
    {
    unsigned char Zm = 0;
    USART_out(Zm);
    }


    Nie wiem dokładnie co robie źle. Ale mam brak komunikacji. Pewnie chodzi tu o te porty, ale ja za bardzo nie wiem jak je zainicjować.
    Jeszcze raz proszę o wszelkie porady.
    Pozdrawiam

    Proszę umieszczać listingi programów w znacznikach "Code". [c_p]
  • #6 5145989
    snow
    Poziom 31  
    Posty: 1825
    Pomógł: 178
    Ocena: 201
    Musisz ustawić rejestr DDR dla portu na którym jest RS. Wpisując na odpowiednią pozycję 1 albo 0 ustawisz czy ma być odpowiednio wyjściem czy wejściem dany pin
  • #7 5146278
    zerpo
    Poziom 22  
    Posty: 463
    Pomógł: 50
    Ocena: 134
    tom163 napisał:
    Nie wiem dokładnie co robie źle. Ale mam brak komunikacji. Pewnie chodzi tu o te porty, ale ja za bardzo nie wiem jak je zainicjować.
    Jeszcze raz proszę o wszelkie porady.
    Pozdrawiam


    Chyba zapomniałeś wywołać w MAIN funkcji UART_init(). Odpowiednią wartość argumentu, jaką trzeba podać funkcji znajdziesz w Datasheecie ATmegi, w dziale przykładowych ustawień UBR dla różnych częstot. taktowania.

    O ile mi wiadomo nie ma konieczności ustawiania kierunków portu, USART robi to sam przejmując kontrolę nad odpowiednimi pinami.
  • #8 5149645
    tom163
    Poziom 10  
    Posty: 7
    Dziękuje za wszystkie podpowiedzi.
    Poprawiłem kod, ale dalej nie mam komunikacji.
    Może ja źle mam skonfigurowany hyperterminal??
    Słyszałem, że realterm jest lepszy do takich rzeczy.

    
    #include <avr/io.h>
    #define CPU_Hz 8000000 // częstotliwość zegara w Hz
    #define OSC 8 // częstotliwość zegara w MHz
    
    #define BAUD 9600 // prędkość transmisji po RS232
    #define MYUBRR CPU_Hz/8/BAUD-1
    
    
    /// **** fukcje dla RS232 ****
    void UART_init(unsigned int ubrr) // inicjalizacja
    {
    UBRRH = (unsigned char) (ubrr>>8); // ustawienie prędkości
    UBRRL = (unsigned char) ubrr;
    UCSRB = (1<<RXEN)|(1<<TXEN); // transmisja dwukierunkowa, odbieranie/nadawanie
    UCSRC = (1<<URSEL)|(3<<UCSZ0); // ustawienie 8 bitów danych i 1 bity stopu
    }
    
    
    void USART_out (unsigned char data) // wysłanie znaku
    {
    while (!(UCSRA & (1<<UDRE)));
    UDR = data;
    }
    
    
    unsigned char USART_in (void) // odebranie znaku
    {
    while (!(UCSRA & (1<<RXC)));
    return UDR;
    }
    
    void Inicjalizacja(void)
    {	
    	DDRD=0xFF; // Ustawiam port D jako wyjścia
    }
    
    int main(void)
    {
    Inicjalizacja();
    UART_init(MYUBRR);
    unsigned char Zm = 0;
    USART_out(Zm);
    }
    


    Męczę się już z tym od 2 dni i ciągle brak komunikacji.
    Pewnie okaże się, że jest to bardzo proste ale jak ktoś robi coś pierwszy raz to nie zawsze to wychodzi.
  • #9 5149725
    snow
    Poziom 31  
    Posty: 1825
    Pomógł: 178
    Ocena: 201
    Kabel na pewno dobry? Pamiętaj że musi Rx procka trafiać na Tx komputera i Tx procka na Rx komputera.

    Poza tym jeżeli wysyłasz "0" to wysyłasz NUL czyli pusty znak. Wyślij coś innego, np. 82 co odpowiada literze "R" w kodzie ASCII.
  • #10 5149763
    tom163
    Poziom 10  
    Posty: 7
    Tracę powoli nadzieję, że uda mi się to zrobić.
    Sprawdzałem podłączenie. Pin R2OUT z MAX232N mam połączony z pinem PD0 (RXD) oraz T2IN z PD1 (TXD). Kabel wydaje się być dobry bo dostałem go razem z całym zestawem.
    Wpisałem tam ta liczbę 82 i dalej nic. Nie wiem może w kodzie coś jest nie tak. Albo źle coś ustawiam pod tym Hyperterminalem. Może ktoś mi objaśni jak to powinno być skonfigurowane.
  • #11 5149865
    snow
    Poziom 31  
    Posty: 1825
    Pomógł: 178
    Ocena: 201
    Może MAX uszkodzony? W Terminalu musisz ustawić 9600 8 N 1. Ja używam Tera Term Pro ale nie wiem czy to problem terminala - raczej wątpie. Może spróbuj uruchomić atmege z kwarcem 1.8432 MHz, 3.6864 MHz albo jakimś innym z tabeli na stronie 169 przy którym są błędy 0%, chociaż tak też powinno coś się przesyłać. Spróbuj może zewrzeć Tx z RX i zobaczyć czy odbierzesz w Terminalu to co nadasz. Tylko najlepiej od strony Atmegi - wtedy będzie wiadomo że problem leży w procku.
  • #12 5150034
    tom163
    Poziom 10  
    Posty: 7
    Opiszę dokładnie co zrobiłem do tej pory. W załączniku umieściłem dokumentację mojej płytki. Podłączyłem interfejs RS232 następująco:
    Pin R2OUT z MAX232N z pinem PD0 (RXD) mikrokontrolera oraz T2IN z PD1 (TXD).

    Następnie wrzuciłem ten programik do procka:
    
    #include <avr/io.h>
    #define CPU_Hz 8000000 // częstotliwość zegara w Hz
    #define OSC 8 // częstotliwość zegara w MHz
    
    #define BAUD 9600 // prędkość transmisji po RS232
    #define MYUBRR CPU_Hz/8/BAUD-1
    
    
    /// **** fukcje dla RS232 ****
    void UART_init(unsigned int ubrr) // inicjalizacja
    {
    UBRRH = (unsigned char) (ubrr>>8); // ustawienie prędkości
    UBRRL = (unsigned char) ubrr;
    UCSRB = (1<<RXEN)|(1<<TXEN); // transmisja dwukierunkowa, odbieranie/nadawanie
    UCSRC = (1<<URSEL)|(3<<UCSZ0); // ustawienie 8 bitów danych i 1 bity stopu
    }
    
    
    void USART_out (unsigned char data) // wysłanie znaku
    {
    while (!(UCSRA & (1<<UDRE)));
    UDR = data;
    }
    
    
    unsigned char USART_in (void) // odebranie znaku
    {
    while (!(UCSRA & (1<<RXC)));
    return UDR;
    }
    
    void Inicjalizacja(void)
    {   
       DDRD=0xFF; // Ustawiam port D jako wyjścia
    }
    
    int main(void)
    {
    Inicjalizacja();
    UART_init(MYUBRR);
    unsigned char Zm = 86;
    USART_out(Zm);
    } 
    


    Oczywiście płytka jest podłączona z komputerem kablem RS.
    Kompiluje program i wysyłam do mikroprocesora.
    Otwieram Hyperterminal i tam nic.... zero reakcji.
    Nadal nie potrafię odebrać żadnego znaku...........
    Załączniki:
    • ARE0021.pdf (341.86 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #13 5150221
    Mikemtb
    Poziom 12  
    Posty: 128
    Ocena: 22
    Widze Freddie, że odpowiedzi to Ty bardzo rzeczowych udzielasz, jeżeli wszystkie Twoje posty tak wyglądają, to nie chcę widzieć pozostałych 924 :).

    Tom info o zmianie częstotliwości AtMegi masz tutaj:
    http://www.tkdami.net/~voytek/programy/fusebity/intro_p_o.html

    Jak ja zmieniam częstotliwość, to potem mi się nie chce programować, ale jak zrestartuje kompa to problem znika( zainicjowanie LPT od nowa nic nie daje :P )
  • REKLAMA
  • #14 5156722
    Fyszo
    Poziom 37  
    Posty: 3987
    Pomógł: 223
    Ocena: 115
    W terminalu musisz wybrać odpowiednie opcje. Czyli numer portu, prędkość, sterowanie przepływem (Xon/Xoff).
  • #15 7201527
    vadis0781
    Poziom 11  
    Posty: 35
    Pomógł: 1
    Ocena: 7
    Witam.
    Wgrałem do zestawu uruchomieniowego ATMega16 następujący kod:
    
    #include <avr/io.h>
    #define CPU_Hz 16000000 // częstotliwość zegara w Hz
    #define OSC 16 // częstotliwość zegara w MHz
    
    #define BAUD 9600 // prędkość transmisji po RS232
    #define MYUBRR CPU_Hz/8/BAUD-1
    
    
    /// **** fukcje dla RS232 ****
    void UART_init(unsigned int ubrr) // inicjalizacja
    {
    UBRRH = (unsigned char) (ubrr>>8); // ustawienie prędkości
    UBRRL = (unsigned char) ubrr;
    UCSRB = (1<<RXEN)|(1<<TXEN); // transmisja dwukierunkowa, odbieranie/nadawanie
    UCSRC = (1<<URSEL)|(3<<UCSZ0); // ustawienie 8 bitów danych i 1 bity stopu
    }
    
    
    void USART_out (unsigned char data) // wysłanie znaku
    {
    while (!(UCSRA & (1<<UDRE)));
    UDR = data;
    }
    
    
    unsigned char USART_in (void) // odebranie znaku
    {
    while (!(UCSRA & (1<<RXC)));
    return UDR;
    }
    
    void Inicjalizacja(void)
    {   
       DDRD=0xFF; // Ustawiam port D jako wyjścia
    }
    
    int main(void)
    {
    Inicjalizacja();
    UART_init(MYUBRR);
    unsigned char Zm = 41;
    USART_out(Zm);
    } 
    


    sytuacja jest taka , że na Real Term widze co nadaję - jednak sa przekłamania.
    Nie mam pewności czy prawidłowo ustawiam kwarc zewn 16MHz.
    Pracuję na AVR Studio.
    transmisja na porcie na 9600 , i w terminalu rowniez 9600. definicja parametrów - ustawienia portu prawidłowe. No i jak nadam :41 to na terminalu mam 8686 .
    Jak wysłać znak z ATmega16 do komputera przez RS232? Początki w C i WinAVR

    Co może być powodem - co przeoczyłem. Domyślam się że coś z prędkością.
    Jak zewrę na stałe rx i tx to odbieram to co nadaję . Więc port działa ok.

    Proszę o podpowiedź - dopiero zaczynam przygodę z AVR Studio i Atmelkami.

Podsumowanie tematu

✨ Dyskusja dotyczy wysyłania znaków z mikrokontrolera ATmega16 do komputera przez interfejs RS232 z wykorzystaniem konwertera poziomów MAX232 oraz programowania w języku C pod środowiskiem WinAVR. Poruszono kwestie inicjalizacji UART, ustawienia rejestrów UBRR, UCSRB i UCSRC dla transmisji szeregowej z prędkością 9600 baud, 8 bitów danych i 1 bitem stopu. Podkreślono, że nie jest konieczne ręczne ustawianie kierunku pinów portu (DDR), ponieważ USART sam kontroluje piny RXD i TXD. Zwrócono uwagę na poprawne podłączenie linii Tx i Rx między mikrokontrolerem a komputerem (Tx do Rx i odwrotnie) oraz na konfigurację terminala (np. HyperTerminal, RealTerm, Tera Term Pro) z parametrami 9600 8N1 bez kontroli przepływu. Wskazano na możliwość testu sprzętowego przez zwarcie Tx i Rx na mikrokontrolerze w celu weryfikacji transmisji. Poruszono także problem doboru częstotliwości taktowania (np. 8 MHz, 16 MHz) i wpływu na ustawienia UBRR. Przykładowy kod inicjalizacji UART i funkcji wysyłania znaku został udostępniony, jednak użytkownik miał trudności z uzyskaniem komunikacji, co mogło wynikać z błędów w konfiguracji terminala, połączenia kabli lub uszkodzenia MAX232. Wskazano na dokumentację Atmegi oraz fora elektroda.pl jako źródła wiedzy.
Podsumowanie wygenerowane przez AI na podstawie treści dyskusji.
REKLAMA