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

[C][atmega8]-jakie przerwanie od RX w celu wykonaniu funkcji

esnow 05 Gru 2009 15:02 1686 16
REKLAMA
  • #1 7348120
    esnow
    Poziom 14  
    potrzebuje przerwania, które w momencie pojawienia się impulsu na Rx odbierze stringa, zdekoduje a następnie wywołała funkcje.
    Ale nie wiem, które przerwanie z tej strony do tego użyc: http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html

    do obsługi UARTA używam następujących funkcji
    
    void USART_Transmit( unsigned char data )
    {
       while ( !( UCSRA & (1<<UDRE)) );   	       // Wait for empty transmit buffer 
       UDR = data;               				   // Put data into buffer, sends the data 
    }
    
    unsigned char USART_Receive( void )
    { 
       while ( !(UCSRA & (1<<RXC)) );             // Wait for data to be received 
       return UDR;                         		   // Get and return received data from buffer 
    }
    
    void USART_Init( unsigned long int ubrr )
    {
       UBRRH = (unsigned char)(ubrr>>8);          // Set baud rate 
       UBRRL = (unsigned char)ubrr;   
       UCSRB = (1<<RXEN)|(1<<TXEN);               // Enable Receiver and Transmitter 
       UCSRC = (1<<URSEL)|(0<<USBS)|(3<<UCSZ0);  // Set frame format: 8data, 1stop bit 
    }
    
    void send_string(const char *tekst)
    {
      while(*tekst)
        USART_Transmit(*tekst++);
    }
    
    void receive_string(void)
    {
    	unsigned char i=0;
    	do
    	{
    		if((bufor[i] = USART_Receive()) == '\n') break;
    		i++;
    	}while(i < 32); //zeby nie przepelnic bufora
    }
    
  • REKLAMA
  • #2 7348163
    ZbeeGin
    Poziom 39  
    ATMega8 nie posiada przerwań PCINTx (SIG_PIN_CHANGEX) które teoretycznie można by wykorzystać. Lepiej połączyć linię RXD z wyprowadzeniem INT0 (lub INT1) i tak skonfigurować przerwania by wykrywało zbocze opadające - bit startu. Jak wykryje zbocze to przerwanie trzeba zablokować, przekazać działanie do modułu USART, który pobierze nadchodzące znaki, i jak napotka koniec ciągu znów włączyć przerwania z INTx i wywoła funkcję.
  • REKLAMA
  • #3 7348236
    gothye
    Poziom 33  
    ale po co skoro można odbierać z USART za pomocą przerwań ,bez potrzeby sterowania INTx:?:
  • REKLAMA
  • #4 7348272
    esnow
    Poziom 14  
    gothye,
    w jaki sposób?
  • #5 7348286
    ZbeeGin
    Poziom 39  
    gothye napisał:
    ale po co skoro można odbierać z USART za pomocą przerwań ,bez potrzeby sterowania INTx:?:

    Kolega wyraźnie napisał: "impuls na Rx". Nie wiemy dokładnie czy przypadkiem nie ma jakiegoś dziwnego urządzenia, które przed wysłaniem ciągu przekazuje impuls.

    Jak mówi słynne informatyczne przysłowie: Śmieci na wejściu = śmieci na wyjściu. Szkoda, że tak często sprawdza się na tym forum.
  • #6 7348331
    gothye
    Poziom 33  
    w bardzo prosty sposób ,ale jak kolega wyżej napisał warto abys podał z jakim dokładnie urządzeniem sie komunikujesz za pomocą AVR
    a co do przerwan UARTu'..

    właczasz je przez ustawienie bitu RXCIE w UCSRB czyli :

    UCSRB = _BV(RXEN) | _BV(TXEN) | _BV(RXCIE);


    a sama obsługa :

    SIGNAL (SIG_UART_RECV) 
    {
         char znak  = UDR ;
    }
  • #8 7348581
    esnow
    Poziom 14  
    komputer <--> przejsciowka USB w oparciu o atmega8 <--> atmega8

    Dodano po 26 [minuty]:

    
    void USART_Init( unsigned long int ubrr )
    {
       UBRRH = (unsigned char)(ubrr>>8);          // Set baud rate 
       UBRRL = (unsigned char)ubrr;   
       UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);               // Enable Receiver and Transmitter 
       UCSRC = (1<<URSEL)|(0<<USBS)|(3<<UCSZ0);  // Set frame format: 8data, 1stop bit 
    }
    

    
    SIGNAL (SIG_UART_RECV)
    {
         char znak=UDR;
         PORTC ^= _BV(PC5);
         rc5send(0,1);
    }
    

    i nie działa...
  • #9 7348849
    gothye
    Poziom 33  
    rc5send(0,1); usun z przerwania i wprowadz jakąs flagę której stan będziesz sprawdzał w programie wykonywał rc5send(0,1); i zerował ją

    co do samej procedury zrób echo i sprawdz wszelkie połączenia :

    ISR (SIG_UART_RECV) 
    { 
         char znak=UDR; 
         UDR = znak ;
    }


    a w głownym programie odblokuj przerwania :

  • #11 7348948
    esnow
    Poziom 14  
    
    ISR(USART_RXC_vect) 
    {
    char znak=UDR;
    UDR=znak;
    }
    


    
    void USART_Transmit( unsigned char data )
    {
       while ( !( UCSRA & (1<<UDRE)) );   	       // Wait for empty transmit buffer 
       UDR = data;               				   // Put data into buffer, sends the data 
    }
    
    unsigned char USART_Receive( void )
    { 
       while ( !(UCSRA & (1<<RXC)) );             // Wait for data to be received 
       return UDR;                         		   // Get and return received data from buffer 
    }
    
    void USART_Init( unsigned long int ubrr )
    {
       UBRRH = (unsigned char)(ubrr>>8);          // Set baud rate 
       UBRRL = (unsigned char)ubrr;   
       UCSRB = (1<<RXEN)|(1<<TXEN)|(RXCIE);               // Enable Receiver and Transmitter 
       UCSRC = (1<<URSEL)|(0<<USBS)|(3<<UCSZ0);  // Set frame format: 8data, 1stop bit 
    }
    


    i main:
    
    int main(void)
    {
        DDRB = 0xff;	PORTB = 0xff;
        DDRC = 0xff;	PORTC = 0x00;
    	
       USART_Init(UART_CONST); 	 //inicjalizacja rs'a
       sei();
    
    while(1)
    {
    
    }
    return 0;
    }
    


    echo nie wraca, natomiast jak zrobie tak:
    
    while(1)
    {
    char qqq = USART_Receive();
    UDR = qqq;
    }
    

    to echo wraca.

    Dodano po 19 [minuty]:

    ani to: ISR(USART_RXC_vect)
    ani to: SIGNAL(SIG_UART_RECV) NIE POMAGA!
  • #13 7351118
    _Robak_
    Poziom 33  
    Cytat:

    UCSRC = (1<<URSEL)|(0<<USBS)|(3<<UCSZ0);


    A co to jest ? ;>

    Dam Ci moze kod do obslugi ktora na 100% dziala ;) Sobie przeanalizuj jak to ma byc
    
    #define BUFF_SIZE   8 
    volatile unsigned char UART0recv, UARTBuffer[BUFF_SIZE], UARTCount, UARTGet, rx_counter; 
    
    // Zmienne globalne, reszta 
    unsigned char a; 
    
    ISR(USART_RXC_vect) 
    { 
        
       UARTBuffer[UARTCount] = UDR; 
       UARTCount++; 
       rx_counter++; 
       if ( UARTCount == BUFF_SIZE ) 
       { 
          UARTCount = 0;       
       } 
           
    
    
    
    } 
    
    void uart_init(void) 
    { 
       UBRRL=25; 
       UCSRB=_BV(RXEN)|_BV(TXEN)|_BV(RXCIE); 
       UCSRC=_BV(URSEL)|_BV(UCSZ1)|_BV(UCSZ0); 
    } 
    
    void uart_putc(unsigned char ch) 
    { 
        
      loop_until_bit_is_set(UCSRA,UDRE); 
      UDR=ch; 
          
    } 
    
    unsigned char uart_getc (void) 
    { 
    
       if (UARTGet==BUFF_SIZE) 
       { 
          UARTGet = 0;       
       } 
    
       rx_counter--; 
       return (UARTBuffer[UARTGet++]); 
    
    }
    
  • #14 7351391
    esnow
    Poziom 14  
    Cytat:
    A co to jest ? ;>

    [C][atmega8]-jakie przerwanie od RX w celu wykonaniu funkcji
  • REKLAMA
  • #16 7352950
    esnow
    Poziom 14  
    Weis,
    tak tutaj głównie błąd leżał. dzięki.

    _Robak_,
    czy tym przerwaniem odbierasz stringa:
    
    ISR(USART_RXC_vect)
    {
       
       UARTBuffer[UARTCount] = UDR;
       UARTCount++;
       rx_counter++;
       if ( UARTCount == BUFF_SIZE )
       {
          UARTCount = 0;       
       }
    } 
    
  • #17 7354093
    _Robak_
    Poziom 33  
    Stringa jak stringa, zmienna 8 bitowa ;) A z tym zapisem, oczywiscie nie jest to blad, ale chyba lepiej kazdy bit z osobna zalaczac ;)
REKLAMA