gpt4 book ai didi

c - AVR UART 读取单个字节两次

转载 作者:行者123 更新时间:2023-11-30 18:27:23 25 4
gpt4 key购买 nike

我目前正在编写一个 UART 接收代码,该代码使用 AVR ATtiny87 读取并解析来自另一台机器的命令。这个想法是检测起始字符并将其存储在缓冲区中,并继续存储 UART 字节,直到接收到 0x0a (FL)。我这样做没有问题,但由于某种原因,我的代码读取每个字节两次。以下是我的函数,由我的内核循环调用。

void vehicle_recv(void) {
uint8_t n = 0;
char byte;

byte = LINDAT; //Reads and stores the content of the UART data register.

if(compass_packet.state == BUFFER_RX_IDLE) {
if(byte == '*' || byte == '#') {
compass_packet.buffer[0] = byte;
compass_packet.index = 1;
compass_packet.state = BUFFER_RX_IN_PROG;
}
}
if(compass_packet.state == BUFFER_RX_IN_PROG) {
compass_packet.buffer[compass_packet.index] = byte;
(compass_packet.index)++;
if(byte == 0x0a) {
compass_packet.buffer[compass_packet.index] = byte;
(compass_packet.index)++;
compass_packet.size = compass_packet.index;
compass_packet.state = BUFFER_RX_DONE;
}
}
if(compass_packet.state == BUFFER_RX_DONE) {
decode_vehicle_command(&compass_packet);
compass_packet.state = BUFFER_RX_IDLE;
}
}


uint8_t decode_vehicle_command(struct compass_comm_packet *RX_buffer) {

debugChar(debug_str);
sendChar(RX_buffer->buffer[0]);
sendCRLF();
sendChar(RX_buffer->buffer[1]);
sendCRLF();
sendChar(RX_buffer->buffer[2]);
sendCRLF();
sendChar(RX_buffer->buffer[3]);
sendCRLF();
sendChar(RX_buffer->buffer[4]);
sendCRLF();
sendChar(RX_buffer->buffer[5]);
sendCRLF();
sendChar(RX_buffer->buffer[6]);
sendCRLF();
sendChar(RX_buffer->buffer[7]);
sendCRLF();

uint8_t return_value = 0;


if(RX_buffer->buffer[0] == '*') {
switch(RX_buffer->buffer[1]) {

case 'H':
strcpy(debug_str, "Heading\r\n");
debugChar(debug_str);
break;
case 'R':
strcpy(debug_str, "Reset\r\n");
debugChar(debug_str);
break;
case 'S':
strcpy(debug_str, "Stop\r\n");
debugChar(debug_str);
break;
case 'C':
strcpy(debug_str, "Calibrate\r\n");
debugChar(debug_str);
break;
}
}

当我发送*H(CR)(FL)时,我希望decode_vehicle_command()函数输出*H(CR)(FL)。然而,我一直看到**HH(CR)(CR)(FL)(FL)。我可以通过使用 RX_buffer->buffer[2] 而不是 RX_buffer->buffer[1] 来解决这个问题,但我很好奇我到底做错了什么。

最佳答案

查看函数 vehicle_recv(),您可以得到:

if(compass_packet.state == BUFFER_RX_IDLE) {
if(byte == '*' || byte == '#') {
compass_packet.buffer[0] = byte;
compass_packet.index = 1;
compass_packet.state = BUFFER_RX_IN_PROG;
}
}
if(compass_packet.state == BUFFER_RX_IN_PROG) {
compass_packet.buffer[compass_packet.index] = byte;
(compass_packet.index)++;
if(byte == 0x0a) {
compass_packet.buffer[compass_packet.index] = byte;
(compass_packet.index)++;
compass_packet.size = compass_packet.index;
compass_packet.state = BUFFER_RX_DONE;
}
}
if(compass_packet.state == BUFFER_RX_DONE) {
decode_vehicle_command(&compass_packet);
compass_packet.state = BUFFER_RX_IDLE;
}

在第一个条件中设置 compass_packet.state = BUFFER_RX_IN_PROG 后,您将进入第二个条件,因为您刚刚设置了状态。在第二个条件中,您再次将 byte 保存到缓冲区 - 每个相同的字节

if(compass_packet.state == BUFFER_RX_IN_PROG) {
compass_packet.buffer[compass_packet.index] = byte;
...

通常,我对这些条件使用switch(或if ... else);这可能也是您的需要:

switch(compass_packet.state) {
case BUFFER_RX_IDLE:
if(byte == '*' || byte == '#') {
compass_packet.buffer[0] = byte;
compass_packet.index = 1;
compass_packet.state = BUFFER_RX_IN_PROG;
}
break;
case BUFFER_RX_IN_PROG:
compass_packet.buffer[compass_packet.index] = byte;
(compass_packet.index)++;
if(byte == 0x0a) {
compass_packet.buffer[compass_packet.index] = byte;
(compass_packet.index)++;
compass_packet.size = compass_packet.index;
compass_packet.state = BUFFER_RX_DONE;
}
break;
case BUFFER_RX_DONE:
decode_vehicle_command(&compass_packet);
compass_packet.state = BUFFER_RX_IDLE;
break;
default:
/* WTF? */
}

关于c - AVR UART 读取单个字节两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56813366/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com