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

AT Mega8: Przykład przerwania odbioru znaku przez RS232 w C, 4.9152MHz, 4800Bd

al555 14 Lis 2004 00:28 2198 2
  • #1 983754
    al555
    Poziom 20  
    Posty: 485
    Pomógł: 32
    Ocena: 8
    Mógłby ktoś zamieścić programik w C (!!!) który wskutek odebrania znaku przez port szeregowy spowoduje wywołanie przerwania dla AT Mega8 związanego z odebraniem znaku
    Rezonator zewnętrzny 4.9152MHz, 4800Bd 8bitów danych, 1 bit stopu

    Przerwanie nie musi nic robić - nawet odczytywać rejestru odbiornika - żeby się tylko wywołało.

    Próbuje od dłuższego czasu zwalczyć przerwania w tym procesorze i nie wiem co robie źle.
    Nie chce zamieszczać swojego kodu żeby nie sugerować, chociaż jak ktoś wolałby poprawiać kod to chętnie zamieszcze !

    Prosze o pomoc !

    Pozdrawiam
  • #2 984643
    wisiena
    Poziom 18  
    Posty: 223
    Pomógł: 21
    Ocena: 5
    Witam !!!
    Nie napisałeś jakiego używasz kompilatora a w przypadku przerwań, wiele od niego zależy. W standardzie ANSI C nie opisuje się przerwań więc wyglądają one różnie. To kod dla standardowego kompilatora CodeVision.
    Obsługuje tylko odbiornik w przerwaniu pakując odebrany bajt do bufora.
    Pzdrawiam (M.)

    
    #include <mega8.h>
    
    #define RXB8 1
    #define TXB8 0
    #define UPE 2
    #define OVR 3
    #define FE 4
    #define UDRE 5
    #define RXC 7
    
    #define FRAMING_ERROR (1<<FE)
    #define PARITY_ERROR (1<<UPE)
    #define DATA_OVERRUN (1<<OVR)
    #define DATA_REGISTER_EMPTY (1<<UDRE)
    #define RX_COMPLETE (1<<RXC)
    
    // USART Receiver buffer
    #define RX_BUFFER_SIZE 8
    char rx_buffer[RX_BUFFER_SIZE];
    unsigned char rx_wr_index,rx_rd_index,rx_counter;
    // This flag is set on USART Receiver buffer overflow
    bit rx_buffer_overflow;
    
    // USART Receiver interrupt service routine
    #pragma savereg-
    interrupt [USART_RXC] void usart_rx_isr(void)
    {
    char status,data;
    #asm
        push r26
        push r27
        push r30
        push r31
        in   r26,sreg
        push r26
    #endasm
    status=UCSRA;
    data=UDR;
    if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
       {
       rx_buffer[rx_wr_index]=data;
       if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
       if (++rx_counter == RX_BUFFER_SIZE)
          {
          rx_counter=0;
          rx_buffer_overflow=1;
          };
       };
    #asm
        pop  r26
        out  sreg,r26
        pop  r31
        pop  r30
        pop  r27
        pop  r26
    #endasm
    }
    #pragma savereg+
    
    #ifndef _DEBUG_TERMINAL_IO_
    // Get a character from the USART Receiver buffer
    #define _ALTERNATE_GETCHAR_
    #pragma used+
    char getchar(void)
    {
    char data;
    while (rx_counter==0);
    data=rx_buffer[rx_rd_index];
    if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
    #asm("cli")
    --rx_counter;
    #asm("sei")
    return data;
    }
    #pragma used-
    #endif
    
    // Standard Input/Output functions
    #include <stdio.h>
    
    // Declare your global variables here
    
    void main(void)
    {
    // Declare your local variables here
    
    // Input/Output Ports initialization
    // Port B initialization
    // Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In
    // State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=T
    PORTB=0x00;
    DDRB=0x00;
    
    // Port C initialization
    // Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In
    // State0=T State1=T State2=T State3=T State4=T State5=T State6=T
    PORTC=0x00;
    DDRC=0x00;
    
    // Port D initialization
    // Func0=In Func1=In Func2=In Func3=In Func4=In Func5=In Func6=In Func7=In
    // State0=T State1=T State2=T State3=T State4=T State5=T State6=T State7=T
    PORTD=0x00;
    DDRD=0x00;
    
    // Timer/Counter 0 initialization
    // Clock source: System Clock
    // Clock value: Timer 0 Stopped
    TCCR0=0x00;
    TCNT0=0x00;
    
    // Timer/Counter 1 initialization
    // Clock source: System Clock
    // Clock value: Timer 1 Stopped
    // Mode: Normal top=FFFFh
    // OC1A output: Discon.
    // OC1B output: Discon.
    // Noise Canceler: Off
    // Input Capture on Falling Edge
    TCCR1A=0x00;
    TCCR1B=0x00;
    TCNT1H=0x00;
    TCNT1L=0x00;
    OCR1AH=0x00;
    OCR1AL=0x00;
    OCR1BH=0x00;
    OCR1BL=0x00;
    
    // Timer/Counter 2 initialization
    // Clock source: System Clock
    // Clock value: Timer 2 Stopped
    // Mode: Normal top=FFh
    // OC2 output: Disconnected
    ASSR=0x00;
    TCCR2=0x00;
    TCNT2=0x00;
    OCR2=0x00;
    
    // External Interrupt(s) initialization
    // INT0: Off
    // INT1: Off
    MCUCR=0x00;
    
    // Timer(s)/Counter(s) Interrupt(s) initialization
    TIMSK=0x00;
    
    // USART initialization
    // Communication Parameters: 8 Data, 1 Stop, No Parity
    // USART Receiver: On
    // USART Transmitter: Off
    // USART Mode: Asynchronous
    // USART Baud rate: 4800
    UCSRA=0x00;
    UCSRB=0x90;
    UCSRC=0x86;
    UBRRH=0x00;
    UBRRL=0x3F;
    
    // Analog Comparator initialization
    // Analog Comparator: Off
    // Analog Comparator Input Capture by Timer/Counter 1: Off
    // Analog Comparator Output: Off
    ACSR=0x80;
    SFIOR=0x00;
    
    // Global enable interrupts
    #asm("sei")
    
    while (1)
          {
          // Place your code here
    
          };
    }
    
    
  • #3 984680
    GienekS
    Poziom 32  
    Posty: 1971
    Pomógł: 139
    Ocena: 15
    W AVR GCC używam czegoś takiego.
    Załączniki:
    • uart.c (4.27 KB) Musisz być zalogowany, aby pobrać ten załącznik.
REKLAMA