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

[Mega8][C]Problem z USART

Qcinski 01 Lip 2008 14:29 5267 30
REKLAMA
  • #1 5302363
    Qcinski
    Poziom 15  
    Witam. Podłączyłem megę8 do PC przez MAX232, jednak w HyperTerminalu nic się nie pokazuje. Za to MAX trochę się grzeje. Mój program:
    #include <avr/io.h>
    
    #define FOSC 1000000			//taktowanie procesora
    #define BAUD 9600				//szybkość transmisji
    #define MYUBRR FOSC/16/BAUD-1
    
    void USART_Init(unsigned int ubrr)
    {
    	  /* ustaw prędkość */
    	UBRRH = (unsigned char)(ubrr>>8);
    	UBRRL = (unsigned char)ubrr;
    	  /* włącz odbiór i transmisję */
    	UCSRB = (1<<RXEN)|(1<<TXEN);
    	  /* ustaw format: 8dane, 2bity stop */
    	UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
    }
    
    void wyslij_znak(unsigned int znak)
    {
    	if (znak == '\n') wyslij_znak('\r');
    	while (!(UCSRA & (1<<UDRE)));
    	UDR = znak;
    }
    
    unsigned char odbierz(void)
    {
    	while (!(UCSRA & (1<<RXC)));
    	return UDR;
    }
    
    void main(void)
    {
    	USART_Init(MYUBRR);
    	wyslij_znak(87);
    	wyslij_znak(73);
    	wyslij_znak(116);
    	wyslij_znak(97);
    	wyslij_znak(74);
    	wyslij_znak('\n');
    	if (odbierz() == '1') wyslij_znak('$');
    }


    Mógłby ktoś sprawdzić co jest nie tak i dlaczego?
  • REKLAMA
  • Pomocny post
    #2 5302408
    BoskiDialer
    Poziom 34  
    w dokumentacji jest błąd, transmisję 8-bit uzyskuje się przy ustawionych UCSZ1 i UCSZ0. funkcje wyslij_znak i odbierz wyglądają poprawnie. W main zmień "odbierz" na "odbierz()". Jeśli MAX się grzeje, to znaczy, że jest źle podłączony, podrzuć jakiś schemat.
  • #3 5302441
    Qcinski
    Poziom 15  
    Przepraszam że trochę pomazany: [Mega8][C]Problem z USART Kondensatory dałem 4,7µ (3szt 50V, 1szt 16V)
  • #5 5302586
    Qcinski
    Poziom 15  
    Tak będzie dobrze?
    #include <avr/io.h>
    
    #define FOSC 1000000			//taktowanie procesora
    #define BAUD 9600				//szybkość transmisji
    #define MYUBRR FOSC/16/BAUD-1
    
    void USART_Init(unsigned int ubrr)
    {
    	  /* ustaw prędkość */
    	UBRRH = (unsigned char)(ubrr>>8);
    	UBRRL = (unsigned char)ubrr;
    	  /* włącz odbiór i transmisję */
    	UCSRB = (1<<RXEN)|(1<<TXEN);
    	  /* ustaw format: 8dane, 2bity stop */
    	UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
    }
    
    void wyslij_znak(unsigned int znak)
    {
    	if (znak == '\n') wyslij_znak('\r');
    	while (!(UCSRA & (1<<UDRE)));
    	UDR = znak;
    }
    
    unsigned char odbierz(void)
    {
    	while (!(UCSRA & (1<<RXC)));
    	return UDR;
    }
    
    void main(void)
    {
    	USART_Init(MYUBRR);
    	for (;;)
    	{
    		wyslij_znak(87);
    		wyslij_znak(73);
    		wyslij_znak(116);
    		wyslij_znak(97);
    		wyslij_znak(74);
    		wyslij_znak('\n');
    		if (odbierz() == '1') wyslij_znak('$');
    	}
    	return(0);
    }
  • REKLAMA
  • REKLAMA
  • #7 5302602
    Qcinski
    Poziom 15  
    MAX to MAX232CPE. Czyli dać same 1u?
  • Pomocny post
    #9 5302960
    JmL(TM)
    Poziom 24  
    Tutaj widac jak na obrazku :D

    [Mega8][C]Problem z USART

    Ja zawsze wstawialem 10uF i nie bylo problemu...
  • #10 5303187
    Qcinski
    Poziom 15  
    6 łączysz z 4 i 7 z 8? Czyli jak mam podłączyć jeszcze kondensatory 1u lub 10u to może lepiej zostawię te 4,7? Będzie bardziej "pośrednio".
  • #11 5303203
    mxmxmxmxmx
    Poziom 16  
    Sterowanie przepływem w HT??
  • #12 5303434
    JmL(TM)
    Poziom 24  
    PiotrekToJa napisał:
    6 łączysz z 4 i 7 z 8? Czyli jak mam podłączyć jeszcze kondensatory 1u lub 10u to może lepiej zostawię te 4,7? Będzie bardziej "pośrednio".


    O tym polaczeniu pisal juz wczesniej Balu:
    Cytat:
    Nie zapętlone 46 78
    a ja wrzucilem schemat bo jest wiecej wart niz nie jedno slowo :D Ja osobiscie robilem dokladnie wg tego schematu i ZAWSZE dzialalo prawidlowo a co do zmiany kondensatorow to nie jestem pewien ale jak nie pojdzie na 4,7uF to zmien na 10uF i po klopocie!
  • #13 5305058
    Qcinski
    Poziom 15  
    A na schemacie nie widzę podłączeń do nóżek 15 i 16 (gnd i vcc). Nie jst to potrzebne, czy jest oczywiste? :)
  • #14 5305131
    piotrg85
    Poziom 12  
    Oczywiste... z resztą wyżej sam zamieściłeś schemat :)
  • #15 5305461
    Qcinski
    Poziom 15  
    JmL(TM), Twój schemat jest na pewno poprawny?Pin 2 we wtyczce COM to Rx, nie Tx. Mam rację?
  • #16 5305531
    JmL(TM)
    Poziom 24  
    Masz racje ale pamietaj, ze linie RX/TX musisz krzyzowac... jesli polaczyles RxD uC -> RxD PC i TxD uC -> TxD PC to pewnie to jest Twoim problemem...
    A schemat pochodzi z tej str: www.sprawdz.mnie ;) i na 100% jest poprawny!

    PS: Co do VCC i GND to myslalem, ze jest to oczywiste :D
  • #17 5305588
    Qcinski
    Poziom 15  
    Zmontowałem i chyba działa. Ale wyświetlają się dziwne literki. Nieraz takie same, nieraz inne. Co może być nie tak?
  • #18 5305614
    JmL(TM)
    Poziom 24  
    Po pierwsze proponowalbym zmienic troche ta funkcje:

    void wyslij_znak(unsigned char znak) // bylo: unsigned int
    {
       if (znak == '\n')
          znak = '\r'; // bylo: wyslij_znak('\r');
    
       while (!(UCSRA & (1<<UDRE)));
       UDR = znak;
    } 


    A tak w ogole to masz moj fragment kodu: :D [Mega16]

    typedef unsigned char  u08;
    
    #define USART_BAUDRATE	57600
    #define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
    
    #define	UART_MAX_GETSTR	100
    
    #define	BIN				 2
    #define	OCT				 8
    #define	DEC				10
    #define	HEX				16
    
    void UART_init(void);
    void UART_put_char(const char c);
    void UART_put_str(const char *string);
    void UART_put_str_P(const char *string);
    void UART_put_int(int value, u08 radix);
    
    char UART_get_char(void);
    void UART_get_str(char *string);
    
    prog_char NEW_LINE[] = {'\n','\r',0}; // tablica zawiarająca znaki nowej linii
    prog_char CLEAR[] = {27,'[','H',27,'[','2','J',0}; // j.w. ale czyszczącza ekran terminala
    prog_char HOME[] = {27,'[','H',0}; // j.w. ale przestawiająca kursor na początek
    //*========================================================*//
    
    void UART_init(void) {
    	UCSRB |= (1 << RXEN) | (1 << TXEN);
    	UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1);	// 8-bit
    
    	UBRRL = BAUD_PRESCALE;
    	UBRRH = (BAUD_PRESCALE >> 8);
    }
    //*========================================================*//
    
    void UART_put_char(const char c)
    {
    	while ((UCSRA & (1 << UDRE)) == 0) {}
    
    	UDR = c;
    }
    //*========================================================*//
    
    void UART_put_str(const char *string)						// wysyla lancuch s z SRAM na UART
    {
    	register u08 c;
    
    	while ((c = *string++))									// dopoki nie napotkasz 0
    	{
    		UART_put_char(c);									// wysylaj znak
    	}
    }
    //*========================================================*//
    
    // wysyła na port szeregowy łańcuch umieszczony w PAMIECI PROGRAMU
    // jako argument przyjmuje wskaźnik (adres pierwszego znaku) do niego
    void UART_put_str_P(const char *string) 
    {
    	register u08 c;
    
    	while ((c = pgm_read_byte(string++)))
    	{
    		UART_put_char(c);
    	}
    }
    //*========================================================*//
    
    void UART_put_int(int value, u08 radix)						// wysyła na port szeregowy tekst przedtawiający value z podstawą radix
    {
    	char string[17];										// bufor na wynik funkcji itoa
    
    	itoa(value, string, radix);								// konwersja value na ASCII
    	UART_put_str(string);									// wyślij string na port szeregowy
    }
    //*========================================================*//
    
    char UART_get_char(void)
    {
    	register u08 c;
    
    	while ((UCSRA & (1 << RXC)) == 0) {}
    	c = UDR;
    
    	return c;
    }
    //*========================================================*//
    
    void UART_get_str(char *string)
    {
    	uint8_t i = 0;
    	uint8_t ch = 0;
    
    	do
    	{
    		ch = UART_get_char();								// pobieraj znak
    		string[i] = ch;										// wstaw go do łańcucha i inkrementuj
    
    		i++;												// inkrementuj ilość znaków odebranych
    	} while ((ch != 0x0D) && (ch != 0x0A) && (i <= UART_MAX_GETSTR)); // dopóki nie napotka znaków końca linii lub nie przekroczy długości MAX_GETSTR
    
    	string[i - 1] = 0;											// wstaw 0 na koniec lancucha
    }
    //*========================================================*//
    

    Przyklad:

    char	ReceivedString[UART_MAX_GETSTR];
    
    UART_init();
    
    ...
    
    UART_get_str(ReceivedString); // odbieramy string
    
    if (!strcmp(ReceivedString, "+CLK?")) // jesli odebrany "string" to "+CLK?"
    {
       UART_put_str_P(PSTR("jakis napis...\n\r")); // odeslij odp
    }


    lub pojedyncze znaki (bajty):

    char ReceivedByte;
    
    ReceivedByte = UART_get_char();
    
    switch (ReceivedByte)
    {
       case 'a': { UART_put_str("odebrano A"); } break;
    
       case 'b': { UART_put_str("odebrano B"); } break;
    
       case 'c': { UART_put_str("odebrano C"); } break;
    
       case 'z':
       {
          for (int d=0; d<16; d++)
          {
             UART_put_int(d, BIN);
             UART_put_str_new_line();
          }
       }
       break;
    
       default: { UART_put_str("jakas domyslna funkcja..."); }
    }
  • REKLAMA
  • #19 5306115
    Qcinski
    Poziom 15  
    Dzięki, przejrzę go i wypróbuję. Jak coś będzie nie tak, to dam znać.

    Był problem, ale dodałem
    #include "avr/io.h"
    #include "string.h"
    #include "stdlib.h"
    #include "avr/pgmspace.h"
    i się skompilowało. Zobaczymy.
    -----

    No i lipa. Nie działa
  • #20 5308494
    JmL(TM)
    Poziom 24  
    Pewnie sie pomyliles tylko tu na elektrodzie ale powinno byc:

    #include <avr/io.h>
    #include <stdlib.h>
    #include <avr/pgmspace.h>


    Co do tego kodu, ktory wkleilem u mnie dziala poprawnie, ale zastanawia mnie jedno... wczesniej pisales, ze twoj kod dziala ale odbierasz rozne wartosci. Pisalem zebys zmienil ten fragment kodu:

    void wyslij_znak(unsigned char znak) // bylo: unsigned int
    {
       if (znak == '\n')
          znak = '\r'; // bylo: wyslij_znak('\r');
    
       while (!(UCSRA & (1<<UDRE)));
       UDR = znak;
    }


    zmieniles?
  • #21 5310330
    Qcinski
    Poziom 15  
    Chwilowo korzystam z Twojego kodu, ale nie działa. Wcześniej miałem takie coś (z mojego programu):
    ·©´ˇŠŤŠ¤—‰´ˇŞŤŠ·©´ˇŞŤŠ¤—‰´ˇŞŤŠ„·©´ˇŠŤŠ„·©´ˇŠŤŠ„·©´ˇŠŤŠ¤—‰´ˇŞŤŠ„—‰´ˇŞŤŠ„—‰´ˇŞŤŠ¤—                                                                                
    ‰´ˇŞŤŠ—©´ˇŞŤŠ¤—‰´ˇŞŤŠ„·©´ˇŠŤŠ—©´ˇŞŤŠ¤—‰´ˇŞŤŠ„·©´ˇŠŤŠ—©´ˇŞŤŠ„—‰´ˇŞŤŠ—©´ˇŞŤŠ„·‰´ˇŠ                                                                                
    ŤŠ„—‰´ˇŞŤŠ—©´ˇŞŤŠ—©´ˇŞŤŠ¤—‰´ˇŞŤŠ¤—©´ˇŠŤŠ„·©´ˇŠŤŠ·©´ˇŠŤŠ„—‰´ˇŞŤŠ„—‰´ˇŞŤŠ·©´ˇŠŤŠ                                                                              
    
    

    teraz nie dostaję nic (w Twoim)
  • #22 5311488
    JmL(TM)
    Poziom 24  
    A powiedz mi czy zarowno w terminalu jak i w uC ustawiles to samo Baud rate? Bo to mi wyglada wlasnie na inne wartosci dlatego otrzymywalbys wlasnie takie "smieci".

    I jeszcze do Twojego wczesniejszego postu...
    Zamiast tego:

    wyslij_znak(87);
    wyslij_znak(73);
    wyslij_znak(116);
    wyslij_znak(97);
    wyslij_znak(74); 


    zrob lepiej:

    wyslij_znak('W');
    wyslij_znak('I');
    wyslij_znak('t');
    wyslij_znak('a');
    wyslij_znak('J'); 


    lub z moim kodem: [jak u Ciebie zacznie dzialac]

    UART_put_str_P(PSTR("WItaJ"));


    o ile szybciej i latwiej :D
  • #23 5311944
    Qcinski
    Poziom 15  
    No niestety, ani jedno ani drugie nie działa. Z moim kodem mam krzaki, z Twoim nic się nie pojawia (raz pojawiło się `, a w RealTerm ciągle szły znaki NUL). Baud ten sam (9600), brak parzystości, 2 bity stopu
  • #24 5312927
    JmL(TM)
    Poziom 24  
    A jakie w koncu masz kondensatory? 4,7uF czy 10uF? I na jakie napiecie tak z ciekawosci. A co do baud rate to ja zazwyczaj ustawiam 57600 bo dokladnie taka sama tolerancja bledu co przy 9600 a szybciej to zawsze lepiej :D

    A terminal polecam: Terminal v1.9b 20040714 - by Br@y++ - chyba najlepszy jaki kiedykolwiek powstal...
  • #25 5313003
    Korazon
    Poziom 12  
    PiotrekToJa - zobacz sobie w karcie katalogowej Atmegi ile wynosi błąd transmisji dla 9600bps przy taktowaniu procesora 1MHz (takie masz zadeklarowanie w programie) - 7% - czyli nie ma szans, abyś cokolwiek poprawnie odebrał. Jeszcze powiedz, że taktujesz mikrokontroler z wewnętrznego oscylatora RC :D.
  • #26 5313043
    JmL(TM)
    Poziom 24  
    Korazon napisał:
    PiotrekToJa - zobacz sobie w karcie katalogowej Atmegi ile wynosi błąd transmisji dla 9600bps przy taktowaniu procesora 1MHz (takie masz zadeklarowanie w programie) - 7% - czyli nie ma szans, abyś cokolwiek poprawnie odebrał. Jeszcze powiedz, że taktujesz mikrokontroler z wewnętrznego oscylatora RC :D.


    Faktycznie! Korazon ma racje!!!

    #define FOSC 1000000         //taktowanie procesora 


    taka masz czestotliwosc? W kodzie, ktory ja tobie podalem F_CPU = 12000000 - czyli 12MHz
  • #27 5313666
    Qcinski
    Poziom 15  
    Tak jest, wewnętrzny zegar 1MHz (fabrycznie). Czyli że co teraz?
  • #28 5313965
    JmL(TM)
    Poziom 24  
    No to o komunikacji z PC mozesz zapomniec dopoki nie zmienisz fuse bit'ow na zewnetrzny kwarc i takowy podepniesz [o fuse bit'ach sporo bylo juz na elektrodzie wiec uzyj "SZUKAJ"]. Mozesz sprawdzic tabele bledow transmisji np. na tej stronie: http://www.wormfood.net/avrbaudcalc.php i najlepiej wypadaja czestotliwosci: 3.6864 Mhz, 7.3728 Mhz, 11.0592 Mhz, 14.746 Mhz poniewaz przy dowolnym baud rate blad transmisji jest rowny zero. Ale to juz sam sprawdz dla kwarcu, ktory zechcesz podpiac pod uC...
REKLAMA