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

UART na AVR ATTiny2313, problem z ISR - własny kod

Bootstrap 28 Paź 2007 19:32 2138 3
REKLAMA
  • #1 4424319
    Bootstrap
    Poziom 11  
    Posty: 10
    Witam!

    Od dłuższego czasu męczę się aby napisać obsługę wysyłania przez UART na AtTiny2313. Mój kod znajduje się w załączniku. Po zaprogramowaniu procesora otrzymuję na terminalu:

    UART na AVR ATTiny2313, problem z ISR - własny kod

    Widać, że słowo "TESTOWY" jest jakoś dziwnie przekłamane, terminal wyrzuca błąd framing error. Prędkość transmisji ustawiona na 9600 bps, próbowałem zarówno z wewnętrznym oscylatorem jak i kwarcem 4 MHz.

    Myślałem, że może być problem z tym, że zanim jeden string zostanie wysłany to rozpoczyna się wysyłanie następnego. Dodałem więc zmienną status. Jeżeli usuniemy komentarz przy if(eStatus == READY) to na terminalu dostaniemy szukany string ale tylko jeden (przy "STRING\n\r dzieje się to samo):

    UART na AVR ATTiny2313, problem z ISR - własny kod

    Moim zdaniem ten drugi przypadek świadczy o tym, że nie są to problemy z zegarem. Dlaczego jednak w drugim przypadku procesor nie wchodzi ponownie do pętli while...??

    Dodam jeszcze, że gdy korzystamy ze statusu i wykomentujemy w ISR linijkę: "UCSRB &= ~(1<<UDRIE); " to na terminalu dostajemy ciągle powtarzający się ciąg "ESTOWY", więc zgubiona jest pierwsza litera no i oczywiście nie wyłączam przerwań. Już kompletnie nie wiem o co chodzi


    Jeżeli ktoś byłby w stanie przetestować ten kod, bądź w jakikolwiek sposób mi pomóc to będę bardzo wdzięczny :)
    Załączniki:
    • main.c (2.48 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • REKLAMA
  • #2 4424615
    Michał_z1
    Poziom 16  
    Posty: 190
    Pomógł: 13
    Ocena: 2
    Witam.
    Problem może być w wewnętrznym, fabrycznie ustawionym podziale zegara przez 8 w Attiny2313.
    pozdro.
  • REKLAMA
  • #3 4424653
    Bootstrap
    Poziom 11  
    Posty: 10
    Niestety nie. Podział zegara jest wyłączony. Jakbym miał 8x za niską częstotliwość w stosunku do baud'a to nie byłoby pomieszanych literek a same krzaki... :/ Problem moim zdaniem tkwi w linii wyłączania przerwania...
    UCSRB &= ~(1<<UDRIE);

    Jeżeli ją sie wykomentuje to wysyła cały czas "ESTOWY ESTOWY..." gubi pierwszą literę ale nie miesza...
  • #4 4425115
    Hauer
    Poziom 12  
    Posty: 29
    Pomógł: 1
    Jeśli chcesz oto mój program. Miałem przy nim problemy gdy używałem realterm. U mnie problemy się skończyły po zainstalowaniu hyper terminala.
    
    //////////////////////////////////////////////////////////////////////
    ///////////////////////////		RS232		//////////////////////////
    //////////////////////////////////////////////////////////////////////
    #include<avr/io.h>
    #include<avr/interrupt.h>	//potrzebne do przerwan
    
    #define FCPU 6000000	//kwarc 6MHz
    #define VUART 9600		//predkosc transmisji[b/s]
    #define VUBRR 38		//wpis dla VUART=9600 gwarantujacy 0.2%bledu
    
    unsigned char volatile flagrx=0;	//flaga odebrano znak
    short int m=1;
    char volatile komenda;		//odebrana komenda z pc
    char bufor[20];	//bufor
    char dane1[]="wcisnales:a";	//na końcu dołączany jest automatycznie znak '\0', który oznacza koniec łańcucha znaków w języku C
    char dane2[]="wcisnales: b";
    char dane3[]="wcisnij a lub b"; 
    
    /////	procedura obslugi odbiornika UART	/////
    SIGNAL(SIG_UART_RECV){	
    	komenda=UDR;		//odebrane zapamietuje w zmiennej komenda
    	flagrx=1;		//ustawia flage odebrania znaku
    }
    
    /////	procedura obslugi nadajnika UART	/////
    SIGNAL(SIG_UART_TRANS){	
    	if(bufor[m]!='\0'){
    		UDR=bufor[m]; 
    		m++;
    	}
    	else if(bufor[m] == '\0'){ 
    	//	UDR='\0';	//wysyla jeszcze znak konca'\0' i wylacza nad
    	//do poprawki	
    		UCR &= ~_BV(TXEN);   //zeruje bitTXEN wylacza nadajnik    
    		m=1;
    	}
    }
    /////	funkcja kopiujaca tablice dane do bufora i inicjujaca wysylanie		////
    void wyslij(char dane[]){
    	short int n;
    	for(n=0;dane[n]!='\0';n++)	//kopiuje dane[] do bufora[]
    		bufor[n]=dane[n];
    	bufor[n]=dane[n];	//dodaje na koniec bufora '\0'
    	UCR |= _BV(TXEN);	//wlacza nadajnik
    	UDR=bufor[0];		//wysyla pierwszy znak reszta wysyla w obsludze przerwania
    }
    int main(void){
    	DDRC=0x01;		//wyjscie na leda	
    	UBRR=VUBRR;		//ustaw predkosc transmisji	
    	UCR= 1<<RXCIE | 1<<RXEN | 1<<TXCIE;	//zezwolenie na przerwania od odb nad i zezw. na odb
    	
    	sei();		//wlacz przerwania
    	
    	while(1){
    		if(flagrx){
    			switch(komenda){
    				case 'a':
    					wyslij(dane1);
    					break;
    				case 'b':
    					wyslij(dane2);
    					break;
    				default:
    					wyslij(dane3);
    			}
    			flagrx=0;	//zeruje flage odbioru zeby juz nie wchodzilo w tego if-a
    			PORTC^=0x01;	//po odebraniu znaku zaswiecalub gasi leda
    		}
    
    	}
    	return 0;
    }
    
REKLAMA