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

ATmega8 i RS232: Nie działa wysyłanie danych na terminal po RS232

CichyMarek 05 Mar 2007 15:14 2241 5
REKLAMA
  • #1 3645685
    CichyMarek
    Poziom 11  
    Posty: 20
    Witam !!

    Napisałem sobie ostatnio prosty program do wysyłania danych na terminal po RSie :

    
    #include <avr/io.h>
    
    #define F_CPU 8000000UL 			 		   // 8MHz wewnetrzny
    #define BAUD 19200UL				   		  // predkosc transmisji
    #define MYUBRR ((F_CPU/(16*BAUD))-1)
    
    void UART_init(unsigned int ubrr)         // inicjalizacja
    {
       UBRRH = (unsigned char) (ubrr>>8);     // ustawienie prędkości transmisji
       UBRRL = (unsigned char) ubrr;
       UCSRB = (1<<RXEN)|(1<<TXEN);          // włączenie odbiornika oraz nadajnika
       UCSRC = (1<<URSEL)|(3<<UCSZ0);        // 8 bitów danych, 1 bity stopu, brak parzystości
    }
    
    void USART_out (unsigned char data)     		 // wysłanie pojedynczego znaku
    {
       while (!(UCSRA & (1<<UDRE)));
       UDR = data;
    }
    
    void sendString(unsigned char s[])
    {
    	int i = 0;
    	
    	while(i < 64) 
    	{
    		if( s[i] == '\0' ) break;
    		USART_out(s[i++]);
    	}
    }
    
    void delay(unsigned char t)							// wytracanie czasu
    {
       unsigned char x, z;                
       for( ; t > 0; --t)                
          for(z = 10; z > 0; --z)          
             for(x = 25 * 8; x > 0; --x)    
                __asm("nop");             
    }
    
    int main(void)
    {
    	UART_init(MYUBRR);    							// Inicjalizacja RS232
    	while (1)
    		{
    			delay(100);
           		sendString("1 2 3 RAZ dwa TRZY 123\r"); 
    		}
    return 0;
    } 


    Po podłączaniu uP do komputera przez port szeregowy i odpaleniu programu terminalowego (Terminal v1.9b by Bray++), zamiast mojego wysłanego tekstu (1 2 3 RAZ dwa TRZY 123) otrzymuję coś takiego (ale tylko w przypadku jak w terminalu ustawie 7 bitów danych ):

    ATmega8 i RS232: Nie działa wysyłanie danych na terminal po RS232

    W kodzie mam zdefiniowaną prędkość 19200, 8 bitów danych, 1 bit stopu, brak parzystości. Jeżeli to samo ustawie w terminalu to otrzymuję już tylko krzaki. Ma ktoś jakieś sugestię dlaczego może się tak dziać ? Jeżeli odłączę kanały Rx i Tx od procka i zewrę je ze sobą to na terminalu otrzymuję dokładnie to co wpisuję z klawiatury. Dlaczego cyfry wysyłają się bez błędy, a zamiast liter wysyła się co chce ?
    Atmega korzysta z wewnętrznego oscylatora ustawionego na 8MHz, program piszę w AVRStudio4.

    Pomocy, siedzę już nad tym kilkanaście godzin i powoli już głupieję :cry:
  • REKLAMA
  • Pomocny post
    #2 3645883
    szymtro
    Poziom 30  
    Posty: 1421
    Pomógł: 101
    Ocena: 59
    Zmień w kodzie definicję frq na 1000000 i spróbuj. Bo wtedy powinno być dobrze.
  • REKLAMA
  • Pomocny post
    #3 3645892
    mirekk36
    Poziom 42  
    Posty: 9195
    Pomógł: 964
    Ocena: 2289
    nie znam dokładnie C ale czy w tej linijce poniżej nie popełniasz błędu przypadkiem?

    Cytat:
    UCSRC = (1<<URSEL)|(3<<UCSZ0);


    nie powinno to być tak?

    UCSRC = (1<<URSEL)|(1<<UCSZ0);


    druga sprawa to czy na pewno dobrze ustawiłeś ATmega8 na 8MHz fusikami ??? bo domyślnie ustawiona jest zdaje się na 1MHz

    pozdrówka
  • REKLAMA
  • #4 3646105
    CichyMarek
    Poziom 11  
    Posty: 20
    Fusebity mam ustawione jak na obrazku poniżej (czyli teoretycznie na te 8MHz):

    ATmega8 i RS232: Nie działa wysyłanie danych na terminal po RS232

    Zmiana na
    UCSRC = (1<<URSEL)|(1<<UCSZ0); 


    nic nie poprawia, ciągle śmieci.
    Dlaczego w terminalu muszę mieć ustawione bity danych na 7, pomimo tego że w programie mam ustawione 8, żeby cokolwiek działało ?

    Na tym forum znalazłem taki przykładowy prgramik:
    
    #include <avr/io.h>
    #include <stdlib.h>
    #include <avr/interrupt.h>
    #include <avr/signal.h>
    #include <inttypes.h>
    #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))
    
    #define F_CPU 8000000UL // 8MHz zegar procesora
    #define UART_BAUD 19200UL
    #define _UBBR_ ((F_CPU/(16*UART_BAUD))-1)
    unsigned char byte;
    
    
    int USART_Transmit( unsigned char data )
    {
    while ( !( UCSRA & (1<<UDRE)) );/* Wait for empty transmit buffer */
    UDR = data;/* Put data into buffer, sends the data */
    return 0;
    }
    
    
    void USART_Init( unsigned int baud_reg )    // inicjalizacja
       {
       UBRRH = (unsigned char)(baud_reg>>8);    // ustawienie prędkości
       UBRRL = (unsigned char)baud_reg;
       UCSRB = (1 << RXCIE) | (1 << RXEN) | (1 << TXEN);  // transmisja dwukierunkowa, odbieranie/nadawanie
       UCSRC = (1 << URSEL) | DATA_BITS_8 | PARITY_NONE | STOP_BITS_1; // ustawienie 8 bitów danych i 1 bity stopu 
       sei();
       }
    
    int main (void)
       {
       USART_Init(_UBBR_);
       DDRB |= (1 << PB1);
    
       while(1)
          {
          }
       return 0;
       }
    
    
    SIGNAL (SIG_UART_RECV)
       {
       PORTB ^= (1 << PB1);
       byte = UDR;
       USART_Transmit(byte);
       }
    


    Program realizuję funkcję echa, to co odbierze z powrotem wysyła.
    Jak w terminalu ustawie tak jak w kodzie, czyli: prędkość 19200UL, 8 bitow to zamiast symboli z klawiatury wyświetla symbole ASCII :) jak zmienię na 7 bitów to poprawnie wyświetla litery, a cyfry dopiero co którąś. Jak zmniejszę prędkość do 14400 (ale tylko w terminalu, w kodzie pozostaje 19200) to wyświetla dokładnie te znaki które mu wysyłam, niezależnie już czy będzie ustawione 8 czy 7 bitów (przy innych ustawieniach krzaki)
    :|. O co z tym chodzi ? Domyślam się że problem jest z dopasowaniem prędkości, tylko nie mam zielonego pojęcia jak się z tym uporać ....
  • REKLAMA
  • Pomocny post
    #5 3646135
    mirekk36
    Poziom 42  
    Posty: 9195
    Pomógł: 964
    Ocena: 2289
    w nocie aplikacyjnej ATmega8 masz taką sekcję:

    "Examples of Baud Rate Setting"

    tam zobaczysz sobie na jakie prędkości transmisji możesz sobie pozwolić przy danej częstotliwości taktowania procka. Weź jednak pod uwagę pewne rozbieżności jeśli używasz oscylatora a nie kwarca zewn.

    Jeśli piszesz, że działa ci dobrze na 4800 to zrób tak - najpierw ustaw do celów testowych taką prędkość na jakiej wszystko działa poprawnie - może uda ci się na najczęściej używanej czyli 9600 i dopracuj swoje procedury przesyłania i odbioru. A następnie popróbuj ew skalibrować wewn. oscylator to czasem pomaga. Poza tym jeśli ci będzie dobrze działać na 9600 to zastanów się czy koniecznie musisz mieć te większe prędkości czy jednak wystarczy 9600

    .... oczywiście za prawidłowo działający uznaj stan taki, że masz i w uC i w terminalu ustawione takie same parametry i wszystko jest ok a nie, że w jednym np 8bitów a w drugim 7 itp
  • #6 3646178
    CichyMarek
    Poziom 11  
    Posty: 20
    Wielkie dzięki za pomoc !! :D
    Przestawiłem fusebajty aby uP pracował na wewnętrznym oscylatorze 2MHz, zmieniłem w programie na tą samą częstotliwość i działa :D Ustawienia w terminalu i procu są takie same :))

    Jednak dziwi mnie trochę to dlaczego nie chcę pracować przy wyższym taktowaniu, a według manuala teoretycznie powinien ...
REKLAMA