目录

一、工程简介

二、STM32cubemax的配置

三、需要添加的代码

四、串口调试结果——成功控制。


一、工程简介

1.芯片:STM32H723ZGT6芯片型号

2.用到的外设功能:

PA3——SCREEN_RX

PA2——SCREEN_TX

PC8——灯的亮灭。

二、STM32cubemax的配置

1.新建工程_选择对应的芯片。

2.调试管脚的配置

3.FreeRTOS的环境配置

4.串口配置——串口配置成中断接收。

5.配置灯的管脚——重命名为LED。

6.配置FreeRTOS的选项——我们这里使用V2版本的。

7.创建任务——两个任务,一个控制灯的亮灭,一个是解析串口指令协议。

8.构建存储结构体的队列

——构建用于通信存储的数据。串口收发是使用uint8_t类型的。

——构建用于控制灯亮灭的数据。控制灯亮灭和颜色,这里是使用结构体进行传递。这里使用指针类型。

9.配置时钟——配置最高时钟。

10.生成代码

11.在工程目录添加文件夹——用于存放.c文件和.h文件。

12.将新建文件夹目录路径添加进来。

13.文件夹的创建

14.在main函数里面添加这个头文件

15.在串口中断中添加这些代码,这些代码主要是把串口中断产生的数据压入队列中进行任务交互。

16.新建的KEL工程需要勾选这个。

三、需要添加的代码

1.总共需要重新编写四个文件

2.inclides文件——主要用于主函数包含所有的结构体和头文件

//.h文件
#ifndef __INCLUDES_H
#define __INCLUDES_H

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>


#include "cmsis_os.h"
#include "FreeRTOS.h"


#include "LedTask.h"
#include "UpperTask.h"
/* Private includes ----------------------------------------------------------*/


/* Exported types ------------------------------------------------------------*/

/* Exported constants --------------------------------------------------------*/


/* Exported macro ------------------------------------------------------------*/


/* Exported functions prototypes ---------------------------------------------*/


/* Private defines -----------------------------------------------------------*/


#ifdef __cplusplus
}
#endif

#endif /* __INCLUDES_H */

3.UpperTask文件——用于处理串口接收数据

//.c文件
#include "upperTask.h"
#include "string.h"
#include "stdio.h"

/* 类型定义和结构体优化 */
typedef struct {
    const char* cmd_template;    // 命令模板
    int buffer_index;            // 使用的buffer索引
    uint8_t buffer_size;         // buffer大小
    void (*handler)(void);       // 命令处理函数
} CommandMap;

static void prvHandLedStatus_OFF(void);
static void prvHandLedStatus_ON(void);
/* 命令映射表 */
static const CommandMap cmd_map[] = {
    {"Func=LED_ON;", 0,sizeof("Func=LED_ON;")-1, prvHandLedStatus_ON},
	{"Func=LED_OFF;", 0,sizeof("Func=LED_OFF;")-1, prvHandLedStatus_OFF},
};

// 接收缓冲区
#define RX_BUFFER_SIZE 128 //缓存区大小
char RxBuffer[RX_BUFFER_SIZE]={0};// 用于存储接收到的指令
uint8_t RxIndex = 0;// 指令接收状态

void ExecuteCommand(char *cmd);
void SendResponse(const char* resp);
void ParseAndExecuteCommand(char* cmd);
void MCU_usart_handle(char Rxdata);
extern UART_HandleTypeDef huart2;
/*--------------------------------------------*/
void UpperStartTask(void *argument)
{
	usart2_receive_start();//串口初始化
	char Rxdata=0;
	for(;;)
	{
		osMessageQueueGet(CommandQueueHandle,&Rxdata,0,osWaitForever);
		MCU_usart_handle(Rxdata);/*数据处理*/
		
	}
}

/* 回调处理函数 */
void MCU_usart_handle(char Rxdata){
	
	
	if (Rxdata !='\n') // 检查指令结束
        {
			if(Rxdata!=' ')//不等于空格
			{
				RxBuffer[RxIndex]=Rxdata;
				RxIndex++; // 增加接收索引  
			}
        }
        else
        {
            RxBuffer[RxIndex] = '\0'; // 替换换行符为字符串结束符
			RxIndex = 0; // 重置接收索引
			ParseAndExecuteCommand(RxBuffer);
			
        }
}

/* 统一命令解析 */
void ParseAndExecuteCommand(char* cmd) {
    for(int i=0; i<sizeof(cmd_map)/sizeof(CommandMap); i++){
        if(strncmp(cmd, cmd_map[i].cmd_template,  cmd_map[i].buffer_size) == 0){
            if(cmd_map[i].handler) {
                cmd_map[i].handler();
            } else {
                ExecuteCommand(cmd); 
            }
            return;
        }else
		{
			if(i==sizeof(cmd_map)/sizeof(CommandMap)-1)
			{
			 SendResponse("undefined COMMAND\r\n");
			}
		}
    }
}


void ExecuteCommand(char *cmd) {
	SendResponse("undefined COMMAND\r\n");
}

/*--处理灯关灯-----------------------------------------------------------*/
static void prvHandLedStatus_OFF(void) {
    char response[100]={0};
	//LEDMessage *message=malloc(sizeof(LEDMessage));/*使用单片机的内存,需要使用对应的函数进行free释放内存*/
	LedMessage *message=pvPortMalloc(sizeof(LedMessage));/*使用freeRTOS分配的内存,需要使用对应的pvfree释放内存*/
	message->color=1;//
	message->state=0;//关灯成功
	// LEDMessage*pMessage =&message;
	osMessageQueuePut(LedQueueHandle,(&message),0,osWaitForever);
    snprintf(response, sizeof(response), "LED OFF SUCESS");
    SendResponse(response);
}

static void prvHandLedStatus_ON(void) {
    char response[100]={0};
	//LEDMessage *message=malloc(sizeof(LEDMessage));/*使用单片机的内存,需要使用对应的函数进行free释放内存*/
	LedMessage *message=pvPortMalloc(sizeof(LedMessage));/*使用freeRTOS分配的内存,需要使用对应的pvfree释放内存*/
	message->color=1;//
	message->state=1;//开灯成功
	// LEDMessage*pMessage =&message;
	osMessageQueuePut(LedQueueHandle,(&message),0,osWaitForever);
    snprintf(response, sizeof(response), "LED ON SUCESS");
    SendResponse(response);
}

/* 响应发送统一封装 ----------------------------------------------------------------------------------*/
void SendResponse(const char* resp) {
    HAL_UART_Transmit(&huart2, (uint8_t*)resp, strlen(resp), 1000);
}

//.h文件
#ifndef __UPPERTASK_H
#define __UPPERTASK_H

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/


/* Exported types ------------------------------------------------------------*/

/* Exported constants --------------------------------------------------------*/


/* Exported macro ------------------------------------------------------------*/


/* Exported functions prototypes ---------------------------------------------*/
void usart2_receive_start(void);

/* Private defines -----------------------------------------------------------*/


#ifdef __cplusplus
}
#endif

#endif /* __UPPERTASK_H */

4.ledTask文件——用于控制灯的亮灭及其颜色。

//.c文件
#include "ledTask.h"


void LedStartTask(void *argument)
{
  /* Infinite loop */
  for(;;)
  {
	LedMessage *message;
	osMessageQueueGet(LedQueueHandle,&message,0,osWaitForever);
	 switch(message->color)
	 {
		 case 0:
			 HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,message->state?GPIO_PIN_SET:GPIO_PIN_RESET);
			 break;
		 case 1:
			 HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,message->state?GPIO_PIN_SET:GPIO_PIN_RESET);
			 break;
		 
	 }
	HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
    //osDelay(2000);
  }
}

//.h文件
#ifndef __LEDTASK_H
#define __LEDTASK_H

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/


/* Exported types ------------------------------------------------------------*/

/* Exported constants --------------------------------------------------------*/


/* Exported macro ------------------------------------------------------------*/


/* Exported functions prototypes ---------------------------------------------*/


/* Private defines -----------------------------------------------------------*/


#ifdef __cplusplus
}
#endif

#endif /* __LEDTASK_H */

四、串口调试结果——成功控制。

---------------------------------------------------------------------------------------------------------------------------------

愿学者在学习的路上不迷路~

以上仅仅属于本人学习心得,可供学习参考,禁止商用~

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐