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

Obsługa przerwań w Atmega 16

mgucio 14 Kwi 2010 16:46 2789 10
REKLAMA
  • #1 7960529
    mgucio
    Poziom 10  
    Witam serdecznie.
    Prosze o pomoc bo nie umiem sobie z tym poradzić.
    Chciałbym zmienić ten program tak aby wykorzystać przerwania obsługujące dane które przychodza z portu RS232, nie trzeba wtedy cały czas nasłuchiwać w pętli ( w moim programie to sa pętle 'if').Program działa poprawnie ale czas reakcji po otrzymaniu danej jest długi.Wiem że trzeba zastosować przerwanie" SIG_USART_RECV"
    ale nie wiem gdzie mam je wstawić.

    #include <avr/io.h>                // dostęp do rejestrów
    #include<avr/interrupt.h>
    #define F_CPU                8000000ul         // częstotliwość zegara w Hz 
    #include<util/delay.h>
    #define cbi(sfr, b) (sfr &= ~(1<<b)) // bit 0 na pin portu 
    #define sbi(sfr, b) (sfr |= (1<<b))  // bit 1 na pin portu 
    unsigned char byte;
    
    // Definicje funkcji 
    
    // inicjalizacja portu szeregowego 
    void UART_Init( unsigned int baud ) 
    { 
       /* Set baud rate */ 
       UBRRH = 0; 
       UBRRL = 51; 
       /* Enable receiver and transmitter */ 
       UCSRB = (1<<RXCIE)|(1<<TXEN)|(1<<RXEN); 
      
      
          /* Set frame format: 8data, 1stop bit */ 
       UCSRC = (1<<URSEL)|(3<<UCSZ0); 
       
    } 
    
    // wysyła znak podany jako parametr na port szeregowy 
    void UART_putchar (unsigned char c) 
    { 
         /* Wait for empty transmit buffer */ 
       while ( !( UCSRA & _BV(UDRE)) ) 
       ; 
    
       /* Put data into buffer, sends the data */ 
       UDR = c; 
    } 
    
    // odbiera znak z portu szeregowego i zwraca go jako wartość funkcji 
    unsigned char UART_getchar (void) 
    { 
         /* Wait for data to be received */ 
       while ( !(UCSRA & (1<<RXC)) ) 
       ; 
       /* Get and return received data from buffer */ 
       return UDR; 
    } 
    
    
     
    
    
    
    
    int main(void)                        // program główny 
    { 
    
    
    DDRB=0xff;
    DDRC=0xff;
      UART_Init(19200);                        // inicjalizacja portu szeregowego 
    
    //////////////////////////////////////////////////////////////
      while(1)                        // pętla nieskończona 
      { 
    ////////////1 silnik///////////////////////
    
    if( UART_getchar()==0x73)// s
      {
     sbi(PORTB,0);
     sbi(PORTB,1);
      }
     do
     {
       	cbi(PORTB,2);
        _delay_ms(250);
    	sbi(PORTB,2);
    	_delay_ms(250);
    	} while (UART_getchar()==0x73);//s
    
    
    if( UART_getchar()==0x72)//r
      {
    
    sbi(PORTB,0);
    cbi(PORTB,1);
    }
    do
    {
    	
    	cbi(PORTB,2);
        _delay_ms(250);
    	sbi(PORTB,2);
    	_delay_ms(250);
    	}while (UART_getchar()==0x72);//r
    
    /////////////////////////////////////////
    
    
    }
     }
  • REKLAMA
  • #2 7960539
    tadzik85
    Poziom 38  
    Wstawić możesz gdziekolwiek.
    Deklaracja obsługi przerwania wygląda tak

    ISR(UART_RX_vect)
    {
               /tu kod usługi obioru
    return
    }
    

    W przerwaniu po odebraniu wszystkich danych ustawiasz flagę i oczekujesz jej w pętli głównej.
  • REKLAMA
  • #4 7960747
    mgucio
    Poziom 10  
    Robak użyłem Twoich funkci ale dalej nie działa.Prosze Cie jeszcze o podpowiedz co jeszcze jest źle. Z góry dziękuje

     
    
    #include <avr/io.h>                // dostęp do rejestrów
    #include<avr/interrupt.h>
    #define F_CPU                8000000ul         // częstotliwość zegara w Hz 
    #include<util/delay.h>
    #define cbi(sfr, b) (sfr &= ~(1<<b)) // bit 0 na pin portu 
    #define sbi(sfr, b) (sfr |= (1<<b))  // bit 1 na pin portu 
    unsigned char byte;
    
    // Definicje funkcji 
    
    // inicjalizacja portu szeregowego 
    void UART_Init( unsigned int baud ) 
    { 
       /* Set baud rate */ 
       UBRRH = 0; 
       UBRRL = 51; 
       /* Enable receiver and transmitter */ 
       UCSRB = (1<<RXCIE)|(1<<TXEN)|(1<<RXEN); 
      
      
          /* Set frame format: 8data, 1stop bit */ 
       UCSRC = (1<<URSEL)|(3<<UCSZ0); 
       
    } 
    
    #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;       
       } 
           
    
    }
    
    unsigned char uart_getc (void) 
    { 
    
       if (UARTGet==BUFF_SIZE) 
       { 
          UARTGet = 0;       
       } 
    
       rx_counter--; 
       return (UARTBuffer[UARTGet++]); 
    
    } 
    void uart_putc(unsigned char ch) 
    { 
        
      loop_until_bit_is_set(UCSRA,UDRE); 
      UDR=ch; 
          
    } 
    
    
    int main(void)                        // program główny 
    { 
    
    
    DDRB=0xff;
    DDRC=0xff;
      UART_Init(19200);                        // inicjalizacja portu szeregowego 
    
    //////////////////////////////////////////////////////////////
      while(1)                        // pętla nieskończona 
      { 
    ////////////1 silnik///////////////////////
    
    if( uart_getc()==0x73)// s
      {
     sbi(PORTB,0);
     sbi(PORTB,1);
      }
     do
     {
       	cbi(PORTB,2);
        _delay_ms(250);
    	sbi(PORTB,2);
    	_delay_ms(250);
    	} while (uart_getc()==0x73);//s
    
    
    if( uart_getc()==0x72)//r
      {
    
    sbi(PORTB,0);
    cbi(PORTB,1);
    }
    do
    {
    	
    	cbi(PORTB,2);
        _delay_ms(250);
    	sbi(PORTB,2);
    	_delay_ms(250);
    	}while (uart_getc()==0x72);//r
    
    /////////////////////////////////////////
    
    
    }
     }
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
     
    
      
      
      
     
  • REKLAMA
  • #5 7960831
    _Robak_
    Poziom 33  
    Generalnie korzystać z tego musisz w taki sposób;)
    
    if(rx_counter) uart_putchar(uart_getchar());
    

    rx_counter przechowuje ile jest znaków w buforze, jeśli jest 0 nie możesz getcharem odbierać znaków.
  • #6 7960947
    mgucio
    Poziom 10  
    Robak chyba ja tego nie łapie:(
    mozesz mi wiecej podpowiedziec jak mam to w main zrobić


    #include <avr/io.h>                // dostęp do rejestrów
    #include<avr/interrupt.h>
    #include<avr/signal.h>
    #define F_CPU                8000000ul         // częstotliwość zegara w Hz 
    #include<util/delay.h>
    #define cbi(sfr, b) (sfr &= ~(1<<b)) // bit 0 na pin portu 
    #define sbi(sfr, b) (sfr |= (1<<b))  // bit 1 na pin portu 
    unsigned char byte;
    
    
    #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(unsigned int baud) 
    { 
       UBRRL=51; 
       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++]); 
    } 
    
    
    int main(void)                        // program główny 
    { 
    
    
    DDRB=0xff;
    DDRC=0xff;
      uart_init(19200);                        // inicjalizacja portu szeregowego 
    
    //////////////////////////////////////////////////////////////
      while(1)                        // pętla nieskończona 
      { 
    ////////////1 silnik///////////////////////
    
    if(rx_counter) uart_putc(uart_getc()==0x73)// s
      {
     sbi(PORTB,0);
     sbi(PORTB,1);
      }
     do
     {
       	cbi(PORTB,2);
        _delay_ms(250);
    	sbi(PORTB,2);
    	_delay_ms(250);
    	} while(rx_counter) uart_putc(uart_getc()==0x72);//s
    
    
    if(rx_counter) uart_putc(uart_getc()==0x72)//r
      {
    
    sbi(PORTB,0);
    cbi(PORTB,1);
    }
    do
    {
    	
    	cbi(PORTB,2);
        _delay_ms(250);
    	sbi(PORTB,2);
    	_delay_ms(250);
    	} while (rx_counter) uart_putc(uart_getc()==0x72);//r
    
    /////////////////////////////////////////
    
    
    }
     }
  • #7 7961094
    _Robak_
    Poziom 33  
    Nie łapiesz:) Napisałem w jednej linijce żeby było wszystko;) Od początku w takim razie
    Czekanie na znak ,odbiór i odesłanie
    
    void main (void)
    {
      while(1)
      {
        while(!rx_counter);
        a=uart_getchar();
        uart_putchar(a);
      }
    }
    


    Jeśli jest znak to odbiór i odesłanie
    
    if(rx_counter)
    {
      a=uart_getchar();
      uart_putchar(a);
    }
    


    Przesłanie ile jest znaków w buforze
    
    uart_putchar(rx_counter);
    
  • #9 7961143
    _Robak_
    Poziom 33  
    gothye słuszna uwaga. Poza tym przeczyść maina, i po kolei wklejaj kawałki kodu a nie od razu wszystko, przez to main wygląda jak kupa głupot że tak to określę.
  • REKLAMA
  • #10 7961289
    mgucio
    Poziom 10  
    Wprowadziłem Twoje podpowiedzi za które jestem wdzięczny:)
    więc tak przez hyper terminal sprawdzam to i wysyła znak podany z klawiatury ale go nie zwraca, nie ma zadnej reakcji na diodach ( po włączeniu 1 lub 2 ma sie zmieniać ich stan)


    #include <avr/io.h>                // dostęp do rejestrów 
    #include<avr/interrupt.h> 
    #include<avr/signal.h> 
    #define F_CPU                8000000ul         // częstotliwość zegara w Hz 
    #include<util/delay.h> 
    #define cbi(sfr, b) (sfr &= ~(1<<b)) // bit 0 na pin portu 
    #define sbi(sfr, b) (sfr |= (1<<b))  // bit 1 na pin portu 
    unsigned char byte; 
    
    
    #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(unsigned int baud) 
    { 
       UBRRL=51; 
       UCSRB=_BV(RXEN)|_BV(TXEN)|_BV(RXCIE); 
       UCSRC=_BV(URSEL)|_BV(UCSZ1)|_BV(UCSZ0); 
    
    sei();
    } 
    
    
    
    
    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++]); 
    } 
    
    
    
    void main (void) 
    { 
    DDRB=0xff; 
    uart_init(19200);
    
      while(1) 
      { 
        while(!rx_counter); 
        a=uart_getc(); 
        uart_putc(a); 
      } 
     
    
     if(rx_counter) 
    { 
      a=uart_getc(); 
      uart_putc(a); 
    } 
    uart_putc(rx_counter); 
    
    
    if(uart_getc()==0x31) 
      { 
     sbi(PORTB,0); 
     sbi(PORTB,1); 
      
    
    
    if(uart_getc()==0x32)
      { 
    
    cbi(PORTB,0); 
    cbi(PORTB,1); 
    } 
    } 
     
    }
  • #11 7961453
    _Robak_
    Poziom 33  
    Patrząc na twój program widać że kompletnie nie masz pojęcia co się dzieje. Proponuję najpierw napisać kilka prostszych programów.
REKLAMA