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()只是我调试使用的功能

效果验证