Строка buff
не определена, поэтому UART_SendString( buff );
будет отправлять любой мусор после полученных трех символов, пока не будет найден байт NUL (0).
char buff[4] = {0};
Будет место для NUL иинициализация гарантирует, что buff[3]
является терминатором NUL.
В качестве альтернативы, отправьте три символа по отдельности, поскольку без терминатора они не составляют действительную строку C (ASCIIZ).
Помимоотсутствие нулевого завершения, ваш код требует ввода точно в форме nnn!nnn!nnn!...
.Если другой конец фактически отправляет строк с терминаторами CR или CR + LF - nnn!<newline>nnn!<newline>nnn!<newline>...
ваш цикл приема выйдет из синхронизации.
Более безопасным решением является использование ранее полученных три символа при получении символа '!'
.Это можно сделать несколькими способами - для длинных буферов рекомендуется использовать кольцевой буфер, но для всего трех символов, вероятно, достаточно эффективно просто сдвигать символы влево при вставке нового символа - например:
char buff[4] ;
for(;;)
{
memset( buff, '0', sizeof(buff) - 1 ) ;
char ch = 0 ;
while( (ch != '!' )
{
ch = UART_RxChar() ;
if( isdigit(ch) )
{
// Shift left one digit
memmove( buff, &buff[1], sizeof(buff) - 2 ) ;
// Insert new digit at the right
buff[sizeof(buff) - 2] = ch ;
}
else if( ch != '!' )
{
// Unexpected character, reset buffer
memset( buff, '0', sizeof(buff) - 1 ) ;
}
}
UART_SendString( buff ) ;
UART_SendString( "\n" ) ;
}
Это также имеет то преимущество, что оно будет работать, когда введенный номер меньше трех цифр, и будет отбрасывать любую последовательность, содержащую нецифровые символы.