AVR半双工接收器中断错误

AVR半双工接收器中断错误

问题描述:

我试图用ATTiny841实现半双工UART。代码的想法是,当我传输除字符'd'之外的任何东西时,我不会收到任何回应,并且当我传送'd'时,我会将该信收回。经过各种角色的测试后,我总是收到我发送的同一封信。我在这里面临的一个主要问题是USART0_RX_vect。出于某种原因,if语句似乎不起作用。关于我能做些什么来解决这个问题的任何建议?AVR半双工接收器中断错误

#include <avr/io.h> 
#include <avr/interrupt.h> 

class CommsController { 
public: 
    uint8_t data; 
    bool bjsonComplete; 

    CommsController(uint8_t ubrr) { 
     UCSR0B |= (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0); // Enable Rx and Rx Complete Interrupt. 
     UBRR0H = (ubrr>>8); 
     UBRR0L = ubrr; 
     // Select 8-bit data frame, single stop bit and no parity using UCSR0C (Default values are what we want). 

     this->bjsonComplete = false; 
    } 

    void transmit(unsigned char data) { 
     UCSR0B &= ~(1<<RXEN0) & ~(1<<RXCIE0); // disable Rx and interrupt. 
     /* Wait for empty transmit buffer */ 
     while (!(UCSR0A & (1<<UDRE0))) 
     ; 
     /* Put data into buffer, sends the data */ 
     UDR0 = data; 
     while (!(UCSR0A & (1<<UDRE0) & (1<<TXC0))) {}; // Wait for empty transmit buffer. 
     UCSR0B |= (1<<RXEN0)|(1<<RXCIE0); // Re-enable Rx and interrupt. 
    } 
}; 


volatile uint8_t data = 0; 

CommsController* commsController; 

ISR(USART0_RX_vect) { 
    data = UDR0; 
    if(data == 'd') { 
     commsController->data = data; 
     commsController->bjsonComplete = true; 
    } 
} 

/* Replace with your library code */ 
int main(void) 
{ 
    cli(); 
    CommsController c(51); 
    commsController = &c; 
    sei(); 

    while(1) { 
     if(commsController->bjsonComplete) { 
      commsController->transmit(commsController->data); 
     } 
    } 

    return 0; 
} 
+0

你确定这是一个完整的例子来重现问题?除了开始之外,commsController->数据应该永远不会包含除'd'外的其他内容。我注意到的是,您应该在传输之后将commsController-> bjsonComplete设置回false。 –

+0

是的,这是该代码的其中一个问题。我确实发现它实际上是因为我没有声明commsController易失性。对于任何面临类似问题的人,我将在后面发布完整的工作代码。 – Hydroflax

#define F_CPU 8000000UL 

#include <avr/io.h> 
#include <avr/interrupt.h> 
#include <avr/delay.h> 

class CommsController { 
public: 
    volatile uint8_t data; 
    volatile bool bjsonComplete; 

    CommsController(uint8_t ubrr) { 
     UCSR0B |= (1<<RXEN0)|(1<<RXCIE0); // Enable Rx and Rx Complete Interrupt. 
     UBRR0H = (ubrr>>8); 
     UBRR0L = ubrr; 
     // Select 8-bit data frame, single stop bit and no parity using UCSR0C (Default values are what we want). 

     this->bjsonComplete = false; 
     this->data = 0; 
    } 

    void transmit(unsigned char data) volatile { 
     UCSR0B &= ~(1<<RXCIE0); // disable Rx interrupt. 
     /* Wait for empty transmit buffer */ 
     while (!(UCSR0A & (1<<UDRE0))); 

     /* Put data into buffer, sends the data */ 
     UDR0 = data; 
     while (!(UCSR0A & (1<<TXC0))); // Wait for empty transmit buffer. 
     UCSR0B |= (1<<RXCIE0); // Re-enable Rx interrupt. 
    } 
}; 

volatile CommsController c(51); 

ISR(USART0_RX_vect) { 
    c.data = UDR0; 
} 

/* Replace with your library code */ 
int main(void) 
{ 
    cli(); 
    sei(); 
    DDRB |= (1<<PORTB1); 
    PORTB &= ~(1<<PORTB1); 

    while(1) { 
     if(c.data == 'd') { 
      c.transmit('f'); 
      c.data = 0; 
     } 
    } 

    return 0; 
}