基于FreeRTOS实现串口接收数据(HC05)的STM32平衡小车01

CubeMX平衡小车01——基于FreeRTOS实现串口接收数据

一、实现功能及实验环境

1.实现功能

手机数据——>HC05——>USART2——>STM32解析收到的数据——>USART1——>电脑串口软件显示4个SHORT

①数据格式

手机数据为12字节,包头为0xA5、包尾为0x5A、倒数第二位为校验位(为纯数据低八位的和)

②手机端APP

③电脑串口软件显示4个SHORT

2.实验环境

开发板为STM32F103CCU6

连接方式:串口2通过蓝牙HC05接受数据,串口1通过左侧USB口连接电脑

二、串口接收基础

1.阻塞式

占用资源

    while (1)
    {
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
        if(HAL_OK == HAL_UART_Receive(&huart2, (uint8_t *)recv_buff, 12, 0xFFFF))
        {
            //可以自由对recv_buff进行操作
        }
    }

2.中断式

全部放到mian.c中

main()
{
    HAL_UART_Receive_IT(&huart2, (uint8_t *)recv_buff, 12);//开启串口2中断
    while (1)
    {
        //可以进行其他操作
    }
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    HAL_UART_Receive_IT(&huart2, (uint8_t *)recv_buff, 12);//开启串口2中断
    if(VerifyData(recv_buff, 12))
    {
        GetPIDFromHC05(recv_buff);
        printf("%d,%d,%d,%d\r\n", PIDFromHC05.BalanceKP, PIDFromHC05.BalanceKD, PIDFromHC05.SpeedKP, PIDFromHC05.SpeedKI);
    }
}

3.DMA式

将中断式中_IT换成_DMA即可,不要忘了在CubeMX中开启串口2的DMA即可

三、串口数据处理

手机端发送

1.校验

只有校验完成,才能认为接受到的数据是我想要的,而不是干扰

/***********************************************************
*@fuction	:VerifyData
*@brief		:对数据进行校验
*@param		:data为数据,dataBIT为位数
*@return	:返回1验证通过
*@author	:--
*@date		:2023-07-19
***********************************************************/

char VerifyData(uint8_t *data, uint8_t dataBIT)
{
    uint8_t sumdata = 0;
    int datak;
    if(data[0] == 0xa5 && data[dataBIT - 1] == 0x5a)//首先确保包头、包尾是对的
    {
        for(datak = 1; datak < 10; datak++)
        {
            sumdata = sumdata + data[datak];
        }
        if(sumdata == data[datak])//校验和也是对的
        {
            return 1;
        }
        return 0;
    }
    return 0;
}

2.取数据

定义结构体

struct HC05_PID_DATA
{
	uint8_t LedStatus;
	short BalanceKP;
	short BalanceKD;
	short SpeedKP;
	short SpeedKI;	
};
struct HC05_PID_DATA PIDFromHC05;

利用结构体取数据

void GetPIDFromHC05(uint8_t *data)
{
    PIDFromHC05.LedStatus = data[1];
    PIDFromHC05.BalanceKP = data[3] << 8 | data[2];
    PIDFromHC05.BalanceKD = data[5] << 8 | data[4];
    PIDFromHC05.SpeedKP = data[7] << 8 | data[6];
    PIDFromHC05.SpeedKI = data[9] << 8 | data[8];
}

四、FreeRTOS二值信号量

1.在CubeMX中设置,直接在keil中生成

#include "cmsis_os.h"
extern osSemaphoreId_t myBinarySem_rxokHandle;

2.释放二值信号量

osSemaphoreRelease(myBinarySem_rxokHandle); //释放二值信号量 

这个要放在中断中

3.等待二值信号量

osSemaphoreAcquire(myBinarySem_rxokHandle,osWaitForever);//等待二值信号量,只有等到了才会往下运行

我对二值信号量的理解:我认为就是一个信号FLAG,中断来了就发个信号,这个信号相当于一个全局变量

五、CubeMX设置

1.串口1设置

串口1不需要额外设置,波特率调为115200即可

2.串口2设置

串口2需开启DMA

3.freertos设置

任务随便设置几个,二值信号量参照第四部分

六、程序编写

1.main.h

/* USER CODE BEGIN Includes */
#include "myUsart.h"
#include "bluetooth_hc05.h"
/* USER CODE END Includes */

2.main.c

/* USER CODE BEGIN Includes */
uint8_t buf[12];
#include "cmsis_os.h"
extern osSemaphoreId_t myBinarySem_rxokHandle;
/* USER CODE END Includes */

/* USER CODE BEGIN 0 */
extern struct HC05_PID_DATA PIDFromHC05;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    HAL_UART_Receive_DMA(&huart2, buf, 12);
    if(VerifyData(buf, 12) == 1)
    {
        GetPIDFromHC05(buf);
        osSemaphoreRelease(myBinarySem_rxokHandle); //释放二值信号量       
    }
}
/* USER CODE END 0 */

    /* USER CODE BEGIN 2 */
    HAL_UART_Receive_DMA(&huart2, buf, 12);
    printf("HC05 FreeRTOS TEST\r\n");
    /* USER CODE END 2 */

3.myUsart.c

#include "myUsart.h"
#include "stm32f4xx_hal.h"
#include "usart.h"
#ifdef __GNUC__
	#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
	#else
		#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif 
PUTCHAR_PROTOTYPE
{	
	HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
	return ch;
}

4.bluetooth_hc05.c

#include "bluetooth_hc05.h"
struct HC05_PID_DATA PIDFromHC05;

char VerifyData(uint8_t *data, uint8_t dataBIT)
{
    uint8_t sumdata = 0;
    int datak;
    if(data[0] == 0xa5 && data[dataBIT - 1] == 0x5a)
    {
        for(datak = 1; datak < 10; datak++)
        {
            sumdata = sumdata + data[datak];
        }
        if(sumdata == data[datak])
        {
            return 1;
        }
        return 0;
    }
    return 0;
}

void GetPIDFromHC05(uint8_t *data)
{
    PIDFromHC05.LedStatus = data[1];
    PIDFromHC05.BalanceKP = data[3] << 8 | data[2];
    PIDFromHC05.BalanceKD = data[5] << 8 | data[4];
    PIDFromHC05.SpeedKP = data[7] << 8 | data[6];
    PIDFromHC05.SpeedKI = data[9] << 8 | data[8];
}

omHC05.LedStatus = data[1];
    PIDFromHC05.BalanceKP = data[3] << 8 | data[2];
    PIDFromHC05.BalanceKD = data[5] << 8 | data[4];
    PIDFromHC05.SpeedKP = data[7] << 8 | data[6];
    PIDFromHC05.SpeedKI = data[9] << 8 | data[8];
}

物联沃分享整理
物联沃-IOTWORD物联网 » 基于FreeRTOS实现串口接收数据(HC05)的STM32平衡小车01

发表评论