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

Atmega 32 USART Problem z wysylaniem/odbieraniem danych

mati1988k 13 Gru 2010 16:23 1581 5
REKLAMA
  • #1 8863456
    mati1988k
    Poziom 13  
    Witam.

    Napisałem prosty program do wysyłania i odbierania danych przez USART. Jednak nic się nie dzieje.
    UC - Atmega32
    Q - 16000000

    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>
    
    
    #define SetBit(x,y)	x |= (1<<y)
    #define ClrBit(x,y) x &= ~(1<<y)
    #define NegBit(x,y) x ^= (1<<y)
    
    
    volatile unsigned char bufor_RXD=0;
    volatile int a=0;               
    
    ISR (USART_RXC_vect)
    {
    	while(bit_is_set(UCSRA, 7));
     	bufor_RXD = UDR;
    	PORTA=0b00000000;
    }
    
    
    int main(void)
    {
      
    //ustawienia portów I/O
     	DDRD  = 0b00000000;   	
     	DDRA  = 0b11111111;   	
    
    
    	//1 - oznacza wyjście  0 - wejście
     	PORTA = 0b00000000;
    	PORTA = 0b10011001;   // diowy. 0 - zapalona
    
    	//**************************************
    	//ustawienie USART
    	//**************************************
    
    	UCSRB = 0b00011000;
    	UCSRC = 0b00000110;
    	UBRRL = 51;		   		//prędkość transmisji 19200
    	SetBit(UCSRB,7);      	//włączenie przerwania od USART RX
    
    	sei();
    
      while(1)
      {   
    
    		while (bit_is_set(UCSRA, 6));		//Czekamy na koniec wysyłania.
    		UDR=0x4F;
    		while (bit_is_set(UCSRA, 6));
    		UDR=0x4B;
    		while (bit_is_set(UCSRA, 6));
    		UDR=0x0D;
    		while (bit_is_set(UCSRA, 6));
    		UDR=0x0A;
    		while (bit_is_set(UCSRA, 6));
    
      }
    }
    


    Proszę niech ktoś rzuci okiem i powie co jest nie tak :)
  • REKLAMA
  • #2 8863670
    rumcajs666
    Poziom 12  
    Przeczytaj najpierw ze zrozumieniem dokumentację uC.
    Dodatkowo: po co pętla while w przerwaniu?
  • REKLAMA
  • #3 8863835
    Fajfer2
    Poziom 20  
    Wysyłanie:
    
    // wcześniej musi być:
     //  UCSRB &= (~(1<<TXCIE));
     //  UCSRB |= ((1<<UDRIE));
     //  UCSRB |= ((1<<TXEN));
     
    ISR(USART_UDRE_vect)
    {
       UDR = ZmiennaDoWyslania;
    // wyłączenie przerwań od możliwości załadowania bufora
       UCSRB &= (~(1<<UDRIE)); 
    // załączenie przerwania od całkowitego zakończenia nadawania
       UCSRB |= ((1<<TXCIE));
    }
    
    ISR(USART_TXC_vect)
    {
       UCSRB &= (~(1<<TXCIE));
       UCSRB &= (~(1<<UDRIE));
       UCSRB |= ((1<<RXEN));
       UCSRB |= ((1<<RXCIE));	
       FlagaZakonczeniaNadawania = 1;
    
    }
  • REKLAMA
  • #4 8863937
    mati1988k
    Poziom 13  
    Fajfer2 jesteś pewny, że to jedyny sposób wysyłania danych bo na atmedze 128 mam zrobione w podobny sposób jak tutaj i działa bezproblemowo.

    Ok działa. Po prostu BaudRate był źle ustawiony.

    Powinno być tak:

    unsigned int baud=51;
    	UBRRH = (unsigned char)(baud>>8);
    	UBRRL = (unsigned char)baud;	   		//prędkość transmisji 19200
  • REKLAMA
  • #5 8864344
    Fajfer2
    Poziom 20  
    Nie pisałem że to jedyny sposób, i raczej nie ma wiele wspólnego z danym typem AVR-a; zmieni się nazewnictwo konkretnego przerwania ISR, może nazwa rejestru UDR (ja mam tak napisany program do ATmega32).

    Prędkość wygodnie ustawić:
    
    	#ifdef BAUD
    	#undef BAUD
    	#endif
    	#define BAUD 19200
    	#include <util/setbaud.h>
    	UBRRH = UBRRH_VALUE;
    	UBRRL = UBRRL_VALUE;
    


    Czemu stosujesz pętlę "while" w przerwaniu od odbioru znaku ? Jak tak zrobisz, to możesz odczytać ostatnią (z kilku) nadaną daną. To by raczej musiało być w takim przypadku jak zrobiłeś, wpis do tablicy + informacja ile tam wpisano znaków.
  • #6 8866471
    mati1988k
    Poziom 13  
    Już jej tam nie ma :)
REKLAMA