Часть проблемы заключается в том, что вы устанавливаете состояние, а затем воздействуете на него в тот же проход.Измените свой код, чтобы выйти из подпрограммы после обработки определенного символа, или измените второй и третий операторы if
на else if
.
Выполните отладчик, чтобы понять, что я имею в виду.
Установите состояние в состояние бездействия, а полученный символ - в '*', и вы получите следующую последовательность:
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, и ваше состояние "RX в процессе".
if(compass_packet.state == BUFFER_RX_IN_PROG) {
// TRUE because you just set it in the previous block
compass_packet.buffer[compass_packet.index] = byte;
// here you've now stored the leading character '*' again
(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_IDLE) {
if(byte == '*' || byte == '#') {
compass_packet.buffer[0] = byte;
compass_packet.index = 1;
compass_packet.state = BUFFER_RX_IN_PROG;
}
} else if(compass_packet.state == BUFFER_RX_IN_PROG) {
compass_packet.buffer[compass_packet.index] = byte;
(compass_packet.index)++;
if( byte == 0x0a) {
compass_packet.size = compass_packet.index;
compass_packet.state = BUFFER_RX_DONE;
decode_vehicle_command(&compass_packet);
compass_packet.state = BUFFER_RX_IDLE;
}
}
Выесть другие дыры в вашей конечной машине, кстати.Что произойдет, если вы получите слишком много символов перед знаком конца строки?