我正在尝试使用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;
}
答案 0 :(得分:-1)
我后来发现问题实际上是因为我没有声明commsController是volatile。我将为面临类似问题的任何人发布以下完整的工作代码:
#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;
}