AVR 半双工接收器中断错误

AVR half duplex receiver interrupt error

我正在尝试使用 ATTiny841 实现半双工 UART。该代码的想法是,当我传输除字符 'd' 以外的任何内容时,我什么也没有收到,而当我传输 'd' 时,我会收到该字母。对此进行测试后,使用各种字符,我总是收到我发送的同一封信。我在这里面临的主要问题之一是 USART0_RX_vect。由于某种原因,if 语句似乎不起作用。关于我可以做些什么来解决这个问题有什么建议吗?

#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;
}

后来我发现问题实际上是因为我没有声明commsController volatile。我将为面临类似问题的任何人 post 下面的完整工作代码:

#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;
}