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

[ATtiny2313][C] Problem z odbiorem danych przez RS232

ADI-mistrzu 23 Maj 2009 18:07 3669 4
REKLAMA
  • #1 6565371
    ADI-mistrzu
    Poziom 30  
    Witam!

    Postanowiłem wziąć się w końcu za naukę obsługi RS232.
    Staram się komunikować z Attiny2313 przez port RS232 (po drodze jest oczywiście MAX232) i o ile wysyłanie danych poszło w miarę gładko (z PC do µC), tak w drugą stronę już nie chce iść.

    Kod mikrokontrolera:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    #define F_CPU 8000000UL
    #include <util/delay.h>
    
    #define UART_BAUD 9600 //Prędkość transmisji 9600
    #define UART_CONST (F_CPU/(16ul*UART_BAUD)-1)
    
    #define LED_ON PORTD = _BV(3)
    #define LED_OFF PORTD = ~_BV(3)
    
    void wyslij(unsigned char data){ //Funkcja do wysyłania danych
    UDR = data; //Wyślij bajt do UDR
    while( !(UCSRA & (1<<UDRE)) ); //Czekaj na zakończenie transmisji
    }
    
    unsigned char odbior(void){ //Funkcja do odbioru danych
    while( !(UCSRA & (1<<RXC)) ); //Czekaj na zakończenie transmisji
    return UDR; //Zwróć wartość UDR
    }
    unsigned int a=10, b;
    int main(void)
    {
    
    DDRD = 0x7E;
    PORTD= 0x02;
    
    DDRB = 0xFF;
    PORTB = 0xFF;
    
     UBRRH = (unsigned char)(UART_CONST>>8);
     UBRRL = (unsigned char)UART_CONST;
                                           
    UCSRB = _BV(RXEN), _BV(TXEN); //Uruchomienie RxD i TxD
                                           
    while(1){
    b=odbior(); //Odbieranie danych
      if(b!=0){ //Jeśli b różne od 0 to...
        switch(b){ 
          case 0x01: LED_ON; break; //Włącza diodę jeśli wysłano 1
          case 0x02: LED_OFF;break; //Wyłącza diodę jeśli wysłano 2
          case 0x05:
    
    	wyslij('5'); // Wysyła cyfrę 5 jeśli wysłano 5
    	LED_ON;
    	_delay_ms(250);  //Sygnalizowanie zakończenia transmisji przez mignięcie diodą
    	LED_OFF;
    	break;
    
          case 0x07:  // Jeśli wysłano 7 mignij kilkakrotnie
    	for(a=10;a>0;a--){
    	  LED_ON;
    	  _delay_ms(250);
    	  LED_OFF;
    	  _delay_ms(250);
    	} break;
          default:  // W pozostałych przypadkach mignij 2 razy
    	LED_ON; 
    	_delay_ms(255); 
    	LED_OFF; 
    	_delay_ms(255); 
    	 LED_ON;
    	_delay_ms(250);
    	LED_OFF;
          break;
        }
      }
    }
    }


    Kod PC:
    #include <stdio.h>
    #include "serial_linux.c" //Biblioteka do obsługi RS232
    
    #define ZEGAR 9600
    
    int main()
    {
     serial_open("/dev/ttyS0", ZEGAR); //Otwieranie portu i ustalanie prędkości
    
    while(1){
    printf("\nKod do wysłania : "); 
    unsigned int i;
      scanf("%i",&i); //Pobiera kod do wysłania
    
    printf("Wysyłam kod...\n");
    if(i!=5){ //Jeśli kod różny jest od 5 to...
    serial_write_byte(i); // ...wyślij go
    }else{ //Jesli jest równy 5 to...
    serial_write_byte(i); //...wyślij go
    printf("Poberam kod...\n");
    int pobrane = serial_read_byte(); // Pobierz dane z portu RS232
    printf("Pobrałem : %i\n",pobrane); //Wypisz je
    }
    }
    serial_close(); //Zamknij port
    
       return 0;
    }


    Za każdym razem przy próbie pobrania danych zwracane jest 0.
    Bibliotekę którą użyłem do kodu na PC załączam w temacie.

    Kompiluję program w GCC pod Linuksem.

    Jedynie co mi do głowy przychodzi że źle jest, to to że komputer pobiera dane za późno i tak naprawdę nic nie pobiera bo mikro kontroler już skończył.

    Pozdrawiam
  • REKLAMA
  • REKLAMA
  • #3 6566853
    ADI-mistrzu
    Poziom 30  
    No raczej tak, a co jest w tym kodzie źle ? Wpisuje 1 do bitów RXEN i TXEN w rejestrze UCSRB czyli uruchamiam wysyłanie i pobieranie (tak z dokumentacji się doczytałem).
  • REKLAMA
  • #4 6568120
    hose2
    Poziom 17  
    Ale operator przecinek działa trochę inaczej niż tutaj chcesz.
  • #5 6568723
    ADI-mistrzu
    Poziom 30  
    Jaki durny błąd popełniłem, aż mi głupio... :|

    Dzięki wielkie za pomoc, w życiu bym w tym miejscu błędu nie szukał.

    Pozdrawiam
REKLAMA