电脑端通过串口发送特定格式数据帧,包含指令和数据。
数据格式:{{指令1:数据1;指令2:数据2;......}}
STM32f103通过UART1与电脑通讯,接收数据后进行解析,并返回解析结果进行测试。
1、定义 int extractCommands()解析函数
// 结构体用于存储指令和数据
struct CommandData {
char command[MAX_CMD_LENGTH];//指令
unsigned long data; //数据
}
// 提取指令和数据的函数
//数据包格式:{{xx:xx;xx:xx;}}//以{{}}作为起止,以“;”分组,以“:”区分该组指令和数据
//入口参数:
// char *input --接收到的字符串数据帧
// struct CommandData *commands--返回CommandData 结构体数据,
int extractCommands(char *input, struct CommandData *commands) {
char *token;
int count = 0;
const char *start = strstr(input, "{{");
const char *end = strstr(input, "}}");
if (!start || !end || end <= start)
return -1; // 没有找到合法的开始和结束标志
// 去掉前面�????"{{"和后面的"}}"
start += 2;
size_t length = end - start; //去掉前后符号,内容的长度
// 拷贝数据到临时缓冲区
char temp[length + 1];
memcpy(temp, start, length);
temp[length] = '\0';
char temp1[sizeof(temp)];
memcpy(temp1, temp, sizeof(temp));
// 使用 strtok 函数按照分隔�???? ";" 对输入进行分割,然后内部用strchr按照分隔�????":"分割指令和数�????
token = strtok(temp, ";");
while (token != NULL && count < 10) {
char *colon = strchr(token, ':');
char strtemp[20];
if (colon != NULL) {
*colon = '\0'; // �???? ':' 替换�???? '\0' 以分隔指令和数据
strcpy(commands[count].command, token);
char *endptr;
strcpy(strtemp, colon + 1);
commands[count].data=strtoul(strtemp, &endptr, 10);
//strcpy(commands[count].data, colon + 1);
count++;
}
token = strtok(NULL, ";");
}
return count;
}
2、main函数中进行具体处理实现
int count;//数据组数量
struct CommandData commands[MAX_COMMANDS];//其中MAX_COMMANDS为数据中最大指令组数
//rx1_buff为UART1接收到的数据帧,解析后存到commands
count = extractCommands(rx1_buff, commands);
for (i = 0; i < count; i++)
{
// 向电脑发送解析后的指令和数据
printf_DMA("Command: %s, Data: %u\r\n", commands[i].command, commands[i].data);//printf_DMA为自定义的UART数据发送函数
}
//指令识别测试,测试接收到的Motor指令对应的数据,如果有这个指令反馈具体数据,没有这个指令提示未找到
for (i = 0; i < count; i++) { //
if (strcmp(commands[i].command,"Mortor") == 0) {
printf_DMA("Data for command %s: %u\r\n", command, commands[i].data);
return;
}
}
printf_DMA("Command %s not found\n", "Mortor");
3、测试