STM32Cubemx-H7-9-串口接受不定长度数据并识别
前言
使用串口,想要别发“hellow”,我就可以直接返回“world”
当别人多了你名字,等其他长度, 修改起来是不是就会很麻烦了呢?
你是不是就傻眼了呢
所以就是想通过串口像现实生活中一样,一段时间内,比如一分钟别人把几句话讲完了,那我们就倾听这几句话,然后再根据听到的内容去完成对应的任务
单片机的串口只能一个字一个字的听,那么我们要通过配合定时器,把一分钟内说的话串成一段话
所以就是要串口结合单片机
STM32CUBEMX配置
主要就是串口1打开
和打开定时器中断,我这里是使用定时器2
设定定时时间为10m
定义变量
把tim.h添加到uart.c里面去
#include "tim.h"
char buffer[1],OUT[100];
uint8_t flag=0;
uint32_t length=0,time=0;
这里简单讲,结合串口和定时器中断代码就会理解
其中buffer是串口缓冲,每次接收一个字符
OUT[100]是输出缓存,我设置最大是100个字节
flag是发送标志位,只有串口接收到数据后,标志位为1,定时器检测到标志位为1时才能发送
length是数据长度,每结束后到一个就++
time是时间标志,每10ms++一次,加到10后也就是100ms,如果串口无接收,那么就发送或者执行对应程序
初始化代码编写
使能定时器
HAL_TIM_Base_Start_IT(&htim2);
使能串口接收
HAL_UART_Receive_IT(&huart1,(uint8_t *)buffer,1);
串口中断代码
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1)
{
OUT[length++]=buffer[0];
time=0,flag=1;
HAL_UART_Receive_IT(&huart1,(uint8_t *)buffer,1);
}
}
OUT用于接收,每次接受就把标志位flag为1,就是表示已经接收过数据,等会要发送的
time每次接收就刷新时间
定时器中断代码
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM2)
{
time++;
if((time>10)&&flag)
{
time=0;
flag=0;
printf("%s\r\n",OUT);
if(strcmp(OUT,"led_on")==0)
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_0,0);
if(strcmp(OUT,"led_off")==0)
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_0,1);
memset(OUT, '\0', sizeof(OUT));
length=0;
}
}
}
中断代码的含义就是,如果超过100ms,都没有接收到数据,而且flag为1,说明已经接收到过数据了,那么就代表已经接收完数据了
然后执行自己定义的功能函数
首先是把time和flag清零
然后使用strcmp比较,如果返回0那么代表和自己定义的字符串相等,并执行对应功能
这里就是开灯和关灯
memset(OUT, '\0', sizeof(OUT));
length=0;
然后这个是把字符串数组清零,用于下一次接收,要不然原来的数据会被覆盖掉
然后接受长度也清楚为0,
这里的printf()只是我调试使用的功能