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

[ATMega32][C] problem z uartem

krzysiekk_20 14 Lut 2011 17:11 981 3
REKLAMA
  • #1 9150914
    krzysiekk_20
    Poziom 12  
    Witam,

    Mam problem z odbiorem danych przez uC a od niedawna programuję w C. Mam takie procedury:

    
    void InitUART()
       {
       UBRRH = (uint8_t)(UBRRVAL >> 8);
       UBRRL = (uint8_t)UBRRVAL;                   /*  Set the baud rate */
    
          UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0); /* Set frame format: 8data, 2stop bit */
       //UCSRC = (1 << UCSZ1) | (1 << UCSZ0);/* set to 8 data bits, 1 stop bit {PUTTY} */
       UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXC);
       //UCSRB = (1<<RXEN)|(1<<TXEN);/* Enable receiver and transmitter */
       }
    /* Read usart */
    unsigned char ReceiveByte( void )
       {
       while ( !(UCSRA &  (_BV(RXC))) );     /*  Wait for incomming data   */
       return UDR;/* Return the   data */
       }
    
    /***********************************************/
    /* Write usart */
    void TransmitByte( unsigned char data )
       {
       while ( !(UCSRA & (_BV(UDRE))) );   /* Wait for empty transmit buffer */
       UDR =  data;   /* Start transmittion   */
       }
    
    /***********************************************/
    /* Write usart 2 */
    void TransmitSTRING(char *text)
       {
       while(*text)
          {
          while (!( UCSRA & (1<<UDRE)));
             UDR = *text;
          text++;
          }
       }
    


    i z wysyłaniem nie mam problemu.Chodzi o odbiór znaków. Użyłem takiej procedury jak poniżej. Odbiór jest zrealizowany jest w przerwaniu. Funkcje lcd_g i lcd_d to funkcje do zmiany kontrastu na lcd. I tutaj gdy wysyłam jeden znak z PC g lub d to wszystko jest ok ale ja chce odbierać kilka znaków powiedzmy od początku lini do natrafienia na znak "\n". Nie wiem jak do tego podejść. Bo ta funkcja odbierania danych odbiera je jako byte a nie string.

    
    ISR (BADISR_vect){}
    
    uint8_t data;
    uint8_t data1;
    char buf[50]="";
     ISR (USART_RXC_vect)
       {
        ReceiveByte();
       data1 = UDR;
       sprintf(buf, "%d\n\r" , data1);
       TransmitSTRING(buf);
       //TransmitByte(data1);
      
    	if (data1 == 'g')
    	{ lcd_g();}  
        if (data1 == 'd')
    	{ lcd_d();}  
       }
    

    Np w C++ Builder były takie funkcje IntToStr() lub podobne. Czy tutaj też coś takiego jest? Interesuje mnie jak już powiedziałem odbieranie jakiegoś ciągu znaków do dalszej obróbki. W powyższym przykładzie jest można powiedzieć taka funkcja echa. i jak wyślę z PC znak "e" zatwierdzony enterem to odtrzymuję spowrotem 13 (znak entera) a potem w nowej linijce 101 (e w ascii).
  • REKLAMA
  • #2 9150965
    BoskiDialer
    Poziom 34  
    Jak to ma działać, gdy ReceiveByte odczytując UDR usuwa z niego bajt danych a Ty linijkę niżej od wywołania próbujesz ponownie pobrać bajt z UDR?
  • REKLAMA
  • #3 9153692
    Terminator
    Poziom 23  
    Wywal ReceiveByte() z funkcji ISR (USART_RXC_vect).
  • #4 9154350
    krzysiekk_20
    Poziom 12  
    Usunąłem tą funkcję z przerwania oraz zmieniłem %d na %c więc teraz mam zamiast liczby oznaczającej znak, jej faktyczny znak. Ale gdy wysyła pojedyńczą literek wszystko jest ok ale gdy chce wysłać więcej np ciąg znaków "zxcvbnm" to dostaje tylko 5 pierwszych znaków i nie wiem co jest nie tak. Bo jak rozumiem to przy każdym przerwaniu mogę odebrać 1 znak czy od razu cały ciąg (w UDR).
    To tylko pewien fragment kodu bo mam jeszcze jedną rzecz timer2 który daje przerwanie co 4ms i może to zakłóca przerwanie od nadejścia znaku.
REKLAMA