Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C AVR UART读取单个字节两次_C_Avr_Uart - Fatal编程技术网

C AVR UART读取单个字节两次

C AVR UART读取单个字节两次,c,avr,uart,C,Avr,Uart,我目前正在编写一个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接收代码,使用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]来解决这个问题,但我很好奇我到底做错了什么。

部分问题在于,您设置了一个状态,然后在同一过程中对其进行操作。处理特定字符后,将代码更改为退出例程,或将第二个和第三个
if
语句更改为
else if

用调试器一步一步地检查它,看看我的意思

将状态设置为idle,将接收的字符设置为“*”,您将得到以下序列:

if(compass_packet.state == BUFFER_RX_IDLE) {
    // TRUE
    if(byte == '*' || byte == '#') {
        // TRUE
        compass_packet.buffer[0] = byte;
        compass_packet.index = 1;
        compass_packet.state = BUFFER_RX_IN_PROG;
    }
}
此时,前导字符存储在缓冲区中,索引为1,您的状态为“正在接收”

换行符终止字符也有类似的问题

尝试:


顺便说一句,您的状态机中还有其他漏洞。如果在行尾标记之前有太多字符,会发生什么情况?

查看函数
vehicle\u 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\u packet.state=BUFFER\u RX\u(在_PROG
中)后,输入第二个条件,因为您刚刚设置了要这样做的状态。在第二个条件中,您再次将
字节
保存到缓冲区---每个字节都保存相同的字节

if(compass_packet.state == BUFFER_RX_IN_PROG) {
    compass_packet.buffer[compass_packet.index] = byte;
    ...
通常,我对这些条件使用
开关
(或
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? */
}

如果不看你的代码,另一台设备可能会回显接收到的字符吗?我不这么认为。我给sendChar打了8次电话,我得到了8个字符。你应该添加
compass\u comm\u packet
结构的最小定义,以及
vehicle\u recv()
的使用及其上下文。天哪,我觉得自己很笨。非常感谢你抓住了我的错误。非常感谢!是的,你是对的。我当然也应该处理好这种情况。
if(compass_packet.state == BUFFER_RX_IN_PROG) {
    compass_packet.buffer[compass_packet.index] = byte;
    ...
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? */
}