- 2024-12-19
-
回复了主题帖:
测评入围名单: NXP MCX A系列 FRDM-MCXA156开发板
个人信息无误,确认可以完成测评分享计划
- 2024-12-09
-
发表了主题帖:
极海APM32M3514电机通用评估板学习笔记01(开发环境搭建和RTT调试输出)
本帖最后由 qzc0927 于 2024-12-9 15:47 编辑
# 准备资料
## 硬件开发工具
> https://www.geehy.com/design/hardware
> https://www.geehy.com/design/hardware_detail/77
找到我们对应的电机开发板资料。如下图所示:
![image-20241206171314344](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241206171314344.png)
## 软件开发工具
> https://www.geehy.com/design/software
找到我们对应的电机开发板的资料,如下图所示:
![image-20241206171225270](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241206171225270.png)
# 工程结构
## 开发环境搭建
使用keil进行开发,创建工程,编译;
![image-20241209104247683](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241209104247683.png)
## 电源供电问题
我的板子type-c电源供电没用,但是程序可以下载,导致我程序对的,无法运行;后面直接用12V电源供电了;
## GPIO操作
GPIO的操作,使用板载LED灯进控制实现;
### 硬件设计
![image-20241209105316548](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241209105316548.png)
![image-20241209105341816](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241209105341816.png)
从原理图可以看出,使用引脚PA12来实现 LED灯闪烁来判断系统工作状态;
### 软件设计
- 1、头文件定义:
```C
#ifndef __DRV_LED_H
#define __DRV_LED_H
#include
#define LED_N 2 //预留一个,LED1作为电源指示灯,默认从LED2开始
#define LED2_PIN GPIO_PIN_12
#define LED2_GPIO_PORT GPIOA
#define LED2_GPIO_CLK RCM_AHB_PERIPH_GPIOA
#define LED3_PIN GPIO_PIN_1
#define LED3_GPIO_PORT GPIOC
#define LED3_GPIO_CLK RCM_AHB_PERIPH_GPIOC
//typedef
typedef enum
{
LED2 = 0,
LED3 = 1
} LED_T;
#ifdef __cplusplus
extern "C" {
#endif
//函数声明
void LedGpioInit(void);
void LedToggle(LED_T Led);
#ifdef __cplusplus
}
#endif
#endif
```
- 2、源文件代码:
```C
#include "drv_led.h"
#include
//其他库的头文件
#include "apm32m35xx_rcm.h"
#include "apm32m35xx_gpio.h"
#include "apm32m35xx_misc.h"
//#include "bsp.h"
GPIO_T* GPIO_PORT[LED_N] = {LED2_GPIO_PORT, LED3_GPIO_PORT};
const GPIO_PIN_T GPIO_PIN[LED_N] = {LED2_PIN, LED3_PIN};
const RCM_AHB_PERIPH_T GPIO_CLK[LED_N] = {LED2_GPIO_CLK, LED3_GPIO_CLK};
void LedGpioInit(void)
{
GPIO_Config_T gpioConfig;
RCM_EnableAHBPeriphClock(LED2_GPIO_CLK);
/* LED2 GPIO configuration */
gpioConfig.pin = LED2_PIN;
gpioConfig.mode = GPIO_MODE_OUT;
gpioConfig.outtype = GPIO_OUT_TYPE_PP;
gpioConfig.speed = GPIO_SPEED_50MHz;
gpioConfig.pupd = GPIO_PUPD_NO;
GPIO_Config(LED2_GPIO_PORT, &gpioConfig);
}
void LedOn(LED_T Led)
{
GPIO_PORT[Led]->BSC = GPIO_PIN[Led];
}
void LedOff(LED_T Led)
{
GPIO_PORT[Led]->BR = GPIO_PIN[Led];
}
void LedToggle(LED_T Led)
{
GPIO_PORT[Led]->ODATA ^= GPIO_PIN[Led];
}
```
- 3、编写测试函数
```c
int main(void)
{
BspInit();
DriverInit();
while (1)
{
APM_DelayMs(1000);
LedToggle(LED2);
}
}
```
- 3、结果验证
烧录程序后,可以看到板载LED每隔1秒闪烁;
## 串口通讯
### 硬件设计
![image-20241209141206762](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241209141206762.png)
![image-20241209141239057](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241209141239057.png)
排查发现,串口和晶振是公用引脚接口,板子默认为晶振接口,R44和R45电阻未焊接,串口未连接,后续软件先不处理,采用RTT_Viewer作为调试接口使用;
### 软件设计
//硬件接口复用了,先不做处理
## RTT Viewer
### RTT Viewer概述
所谓RTT,即是实时传输技术,我们所用到的组件是由SEGGER公司开发,这家公司一款比较广为人知的产品就是J-link,支持所有ARM芯片的调试和仿真。RTT允许目标设备和主机之间进行双向通信,比传统的 UART 调试更快、更可靠,并且几乎不会影响到程序的运行,占用的资源非常
### RTT Viewer移植
具体移植过程参考下面这篇文章,这里不在多说明。
> https://blog.csdn.net/weixin_42530814/article/details/138866691
### 结果验证
编写测试程序:
```C
int main(void)
{
BspInit();
DriverInit();
while (1)
{
APM_DelayMs(1000);
DEBUG_LOG("LedToggle");
LedToggle(LED2);
}
}
```
打开第三方RTT Viewer客户端,查看终端输出:
![image-20241209151124034](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241209151124034.png)
- 2024-11-27
-
回复了主题帖:
测评入围名单:极海APM32M3514电机通用评估板
个人信息无误,确认可以完成测评分享计划。
- 2024-11-20
-
回复了主题帖:
有奖活动 | 英飞凌新品情报站:最新5V XENSIV™ PAS CO2传感器
套件测试视频,B站链接CO2传感器使用
- 2024-11-19
-
回复了主题帖:
CW32L010学习笔记
Jacktang 发表于 2024-11-16 09:18
用type-c直接供电比较方便了
需要注意,这个板子的电源兼容常见的3.3V和5V,有些模块在3.3V供电的要注意
-
发表了主题帖:
【英飞凌XENSIV™ PAS CO2传感器】学习笔记01
CO2传感器评估套件评测
[TOC]
# 评估套件介绍
XENSIV™PAS CO2是一种真正的二氧化碳传感器,它改进了现有二氧化碳传感器的尺寸和性能解决。该传感器是基于独特的光声光谱(PAS)原理设计的。致
XENSIV TM PAS CO2 Sensor2Go评估套件可确保高效快速的评估。易于使用PC GUI随软件包一起提供。
![image-20241027195435043](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241027195435043.png)
# 硬件详细说明
## 硬件主板模块
该评估套件由模块开发板和接口底板组成,硬件视图如下:
![image-20241027195742981](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241027195742981.png)
引脚分布如下:
![image-20241027200231518](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241027200231518.png)
模块引脚分布视图:
![image-20241027200351675](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241027200351675.png)
# 软件说明
## 下载英飞凌的软件工具
具体链接地址如下:
> https://www.infineon.com/cms/en/design-support/tools/utilities/infineon-developer-center-idc-launcher/?redirId=160101
安装后的工具截图如下:
![image-20241027200945169](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241027200945169.png)
## 下载CO2图形化工具
选择下图中的CO2 GUI工具进行安装:
![image-20241027201054149](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241027201054149.png)
具体安装就不详细说明了,安装结果如下:
![image-20241027202024865](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241027202024865.png)
## 设备连接
将我们的的CO2评估套件通过USB连接到电脑上,打开软件,等待设备连接,软件会自动识别套件使用的串口。等待设备连接:
![image-20241027202035834](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241027202035834.png)
连接成功后,会自动进入到检测状态,
![image-20241027202151978](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241027202151978.png)
## 配置模块
### 设备采样频率
![image-20241027202443915](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241027202443915.png)
可以对设备进行校准,提高检测精度。
### 显示信息校准
点击-setting,进行界面显示信息的校准设定。
![image-20241027202615578](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241027202615578.png)
## 历史数据采样信息
当前我们设定60s进行采样,历史检测结果如下:
![image-20241027203050732](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241027203050732.png)
当前只采用官方软件进行测试,后续可以自己编程程序,连接单片机进行输出;
- 2024-11-15
-
发表了主题帖:
CW32L010学习笔记
CW32学习开发笔记
# 硬件原理图:
## 主芯片
![image-20241114103849101](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241114103849101.png)
引脚封装图:
![image-20241114104051352](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241114104051352.png)
CW32L010 是基于 eFlash 的单芯片低功耗微控制器,集成了主频高达 48MHz 的 ARM® Cortex®-M0+ 内核、
高速嵌入式存储器(多至 64K 字节 FLASH 和多至 4K 字节 SRAM)以及一系列全面的增强型外设和 I/O 口。
所有型号都提供全套的通信接口(二路 UART、一路 SPI 和一路 I2C)、12 位高速 ADC、四组通用和基本定时器、
一组低功耗定时器以及一组高级控制 PWM 定时器。
## 供电电源
使用type-c直接供电即可,不需要再接其他电源转换芯片,CW32L010 可以在 -40℃到 85℃的温度范围内工作,供电电压宽达 1.62V ~ 5.5V。支持 Sleep 和 DeepSleep两种低功耗工作模式。
![image-20241114104435067](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241114104435067.png)
## 复位电路
![image-20241114104524841](C:/Users/syz/AppData/Roaming/Typora/typora-user-images/image-20241114104524841.png)
## 滤波电路
![image-20241114104852343](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241114104852343.png)
## 内部稳压
![image-20241114105052457](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241114105052457.png)
![image-20241114105024829](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241114105024829.png)
## 调试下载
默认使用SWD接口下载程序,原理图如下:
![image-20241114105146199](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241114105146199.png)
## 板载指示灯
用于查看系统运行状态,原理图如下:
![image-20241114110648242](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241114110648242.png)
# 软件功能
## 工程创建
具体如何创建工程就不所说明了,官方例程都有说明,我主要说下的我的目录结构设计:
![image-20241114105830013](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241114105830013.png)
## 串口通讯
内部集成 2 个通用异步收发器 (UART),支持异步全双工、同步半双工和单线半双工模式,支持硬件数据流控
和多机通信,还支持 LIN(局域互连网络);可编程数据帧结构,可以通过小数波特率发生器提供宽范围的
波特率选择。内置定时器模块,支持等待超时检测、接收空闲检测、自动波特率检测和通用定时功能。
UART 控制器工作在双时钟域下,允许在深度休眠模式下进行数据的接收,接收完成中断可以唤醒 MCU 回到
运行模式。注意:仅 UART1 支持 LIN 和定时器功能;UART2 可通过片内外设互联与 BTIM/GTIM/ATIM 的从模式协同工
作实现超时定时器相关功能。我们接着实现串口通讯功能;
- 1.串口功能硬件引脚
![image-20241114135526600](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241114135526600.png)
使用串口2来是实现通讯,再看引脚的复用功能。
![image-20241114135659092](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241114135659092.png)
- 2.代码实现
```C
#include "bsp_uart2.h"
#include "cw32l010_gpio.h"
#include "cw32l010_uart.h"
#include "stdio.h"
#include "cw32l010_sysctrl.h"
//UARTx
#define DEBUG_UARTx CW_UART2
#define DEBUG_UART_CLK SYSCTRL_APB1_PERIPH_UART2
#define DEBUG_UART_APBClkENx SYSCTRL_APBPeriphClk_Enable1
#define DEBUG_UART_BaudRate 115200
#define DEBUG_UART_UclkFreq HSIOSC_VALUE //串口全速运行
//UARTx GPIO
#define DEBUG_UART_GPIO_CLK (SYSCTRL_AHB_PERIPH_GPIOB)
#define DEBUG_UART_TX_GPIO_PORT CW_GPIOB
#define DEBUG_UART_TX_GPIO_PIN GPIO_PIN_5
#define DEBUG_UART_RX_GPIO_PORT CW_GPIOB
#define DEBUG_UART_RX_GPIO_PIN GPIO_PIN_6
//GPIO AF
#define DEBUG_UART_AFTX PB05_AFx_UART2TXD()
#define DEBUG_UART_AFRX PB06_AFx_UART2RXD()
static void UART_Configuration(void)
{
// //外设时钟使能,放在外设里面自己进行使能
DEBUG_UART_APBClkENx(DEBUG_UART_CLK, ENABLE);
UART_InitTypeDef UART_InitStructure = {0};
UART_InitStructure.UART_BaudRate = DEBUG_UART_BaudRate;
UART_InitStructure.UART_Over = UART_Over_16;
UART_InitStructure.UART_Source = UART_Source_PCLK;
UART_InitStructure.UART_UclkFreq = DEBUG_UART_UclkFreq;
UART_InitStructure.UART_StartBit = UART_StartBit_FE;
UART_InitStructure.UART_StopBits = UART_StopBits_1;
UART_InitStructure.UART_Parity = UART_Parity_No ;
UART_InitStructure.UART_HardwareFlowControl = UART_HardwareFlowControl_None;
UART_InitStructure.UART_Mode = UART_Mode_Rx | UART_Mode_Tx;
UART_Init(DEBUG_UARTx, &UART_InitStructure);
}
/**
* @brief 配置GPIO
*
*/
static void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
//外设时钟使能,放在外设里面自己进行使能
SYSCTRL_AHBPeriphClk_Enable(DEBUG_UART_GPIO_CLK, ENABLE);
GPIO_WritePin(DEBUG_UART_TX_GPIO_PORT, DEBUG_UART_TX_GPIO_PIN,GPIO_Pin_SET); // 设置TXD的默认电平为高,空闲
GPIO_InitStructure.Pins = DEBUG_UART_TX_GPIO_PIN;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Init(DEBUG_UART_TX_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.Pins = DEBUG_UART_RX_GPIO_PIN;
GPIO_InitStructure.Mode = GPIO_MODE_INPUT_PULLUP;
GPIO_Init(DEBUG_UART_RX_GPIO_PORT, &GPIO_InitStructure);
//UART TX RX 复用
DEBUG_UART_AFTX;
DEBUG_UART_AFRX;
}
void UART2_Configuration(void)
{
UART_Configuration();
GPIO_Configuration();
}
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
/**
* @brief Retargets the C library printf function to the UART.
*
*/
PUTCHAR_PROTOTYPE
{
UART_SendData_8bit(DEBUG_UARTx, (uint8_t)ch);
while (UART_GetFlagStatus(DEBUG_UARTx, UART_FLAG_TXE) == RESET);
return ch;
}
size_t __write(int handle, const unsigned char * buffer, size_t size)
{
size_t nChars = 0;
if (buffer == 0)
{
/*
* This means that we should flush internal buffers. Since we
* don't we just return. (Remember, "handle" == -1 means that all
* handles should be flushed.)
*/
return 0;
}
for (/* Empty */; size != 0; --size)
{
UART_SendData_8bit(DEBUG_UARTx, *buffer++);
while (UART_GetFlagStatus(DEBUG_UARTx, UART_FLAG_TXE) == RESET);
++nChars;
}
return nChars;
}
/******************************************************************************
* EOF (not truncated)
******************************************************************************/
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
```
- 3.编写打印测试函数
```C
static void Printf_Function(void)
{
DEBUG_LOG("\r\n");
DEBUG_LOG(" Compile time:");
DEBUG_LOG(__DATE__);
DEBUG_LOG(" ");
DEBUG_LOG(__TIME__);
DEBUG_LOG("\r\n+-------------------+\r\n");
DEBUG_LOG("%s,%s,%d,%s\r\n", __FUNCTION__,__FILE__,__LINE__,__DATE__);
DEBUG_LOG("\r\n+-------------------+\r\n");
}
```
- 4.查看串口终端信息
使用MobaXterm终端工具查看:
![image-20241114140550582](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241114140550582.png)
- 5.注意点
为了让代码支持GNU扩展,keil设置需要注意:
![image-20241114140950288](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241114140950288.png)
同时,串口打印的时候,添加头文件`"stdio.h"`;
## GPIO口输入输出
根据板载资源,使用板载的LED来测试。前面硬件说明的时候提到,使用的引脚为PB00;就直接上代码了。
- 1.编写驱动代码
```C
#include "drv_led.h"
// 初始化 LED 引脚
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__SYSCTRL_GPIOB_CLK_ENABLE();
GPIO_InitStruct.IT = GPIO_IT_NONE;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pins = LED_GPIO_PINS;
GPIO_Init(LED_GPIO_PORT, &GPIO_InitStruct);
}
// 控制 LED 开关
void LED_Control(GPIO_PinState state)
{
GPIO_WritePin(LED_GPIO_PORT, LED_GPIO_PINS,state);
}
// 切换 LED 状态
void LED_Toggle(void) {
GPIO_TogglePin(LED_GPIO_PORT, LED_GPIO_PINS);
}
// 读取 LED 状态
int LED_Read(void) {
return GPIO_ReadPin(LED_GPIO_PORT, LED_GPIO_PINS) == GPIO_Pin_SET ? 1 : 0;
}
// 定义并初始化 LED 操作结构体实例
LED_Ops_t myLED = {
.init = LED_Init,
.control = LED_Control,
.toggle = LED_Toggle,
.read = LED_Read
};
```
- 2.编写测试程序
```C
int32_t main(void)
{
bsp_init();
driver_init();
while(1)
{
SysTickDelay(1000);
myLED.toggle();
}
}
```
调试下载之后,可直接观察板载LED灯是否在循环闪烁。
## 调试等级
- 1.直接上代码,调试等级头文件;
```C
#ifndef __LOG_H
#define __LOG_H
#include
#include
#include
#include
#define GLOB_LOG_EVEL LOG_DEBUG
typedef enum {
FALSE,
TRUE
} status;
// 定义日志级别
typedef enum {
LOG_DEBUG,
LOG_INFO,
LOG_WARNING,
LOG_ERROR
} LogLevel;
//extern LogMsg lmsg;
// 颜色
#define Blue "\033[34m" // Blue
#define Green "\033[32m" // Green
#define Yellow "\033[33m" // Yellow
#define Red "\033[31m" // Red
#define Reset "\033[0m" // Reset color
// 记录日志的宏定义
#define LOG_MESSAGE(format, ...) printf("[NTP]:%s(),Line:%05d: " format "\r\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
void LOG_MSG(LogLevel level, const char *message);
#endif
```
- 2.功能函数实现文件:
```C
#include "log.h"
// 日志输出函数
void LOG_MSG(LogLevel level, const char *message) {
switch (level) {
case LOG_DEBUG:
printf(Blue "DEBUG: %s" Reset "\r\n", message);
break;
case LOG_INFO:
printf(Green "INFO: %s" Reset "\r\n", message);
break;
case LOG_WARNING:
printf(Yellow "WARNING: %s" Reset "\r\n", message);
break;
case LOG_ERROR:
printf(Red "ERROR: %s" Reset "\r\n", message);
break;
default:
printf("UNKNOWN: %s\n", message);
break;
}
}
```
- 3.编写测试函数
```C
/*宏定义错误码信息*/
static void Error_Code_Info(void)
{
DEBUG_LOG("%d", SYSTEM_OK);
DEBUG_LOG("%d", SYSTEM_ERR_E_1);
DEBUG_LOG("%d", SYSTEM_ERR_E_2);
DEBUG_LOG("%d", SYSTEM_ERR_MQTT_INFO_ERROR);
LOG_MSG(LOG_DEBUG, "This is a debug message");
LOG_MSG(LOG_INFO, "This is an info message");
LOG_MSG(LOG_WARNING, "This is a warning message");
LOG_MSG(LOG_ERROR, "This is an error message");
}
```
- 4.终端输出
![image-20241114145804066](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241114145804066.png)
## 串口中断
CW32单片机的串口有好几种工作方式,异步全双工,同步半双工,单线半双工,由于没有DMA通道,为了避免频繁的进入中断,采用串口接收中断,串口查询发送方式实现收发;
配置简单队列消息,实现方式如下:
- 1、定义队列结构
```C
#define myQ2_SIZE 512
#define RxBuffer2_SIZE myQ2_SIZE
typedef volatile struct
{
uint8_t m_getIdx;
uint8_t m_putIdx;
uint8_t m_entry[ myQ2_SIZE ];
} myQ2;
extern myQ2 volatile RxBuffer2;
extern myQ2 volatile TxBuffer2;
void UART2_Buffer_Init(void);
```
- 2、初始化队列结构
```C
myQ2 volatile RxBuffer2;
myQ2 volatile TxBuffer2;
void UART2_Buffer_Init(void)
{
CBUF_Init(RxBuffer2);
CBUF_Init(TxBuffer2);
}
```
- 3、使能串口接收中断
```C
void NVIC_Configuration(void)
{
//优先级,无优先级分组
NVIC_SetPriority(DEBUG_UART_IRQ, 0);
//UARTx中断使能
NVIC_EnableIRQ(DEBUG_UART_IRQ);
//使能UARTx RC中断
UART_ITConfig(DEBUG_UARTx, UART_IT_RC, ENABLE);
UART_ClearITPendingBit(CW_UART2, UART_IT_RC);
}
```
- 4、编写测试函数,实现串口功能收发
```C
int32_t main(void)
{
bsp_init();
driver_init();
while(1)
{
uint16_t dataLen=0;
dataLen = CBUF_Len(RxBuffer2);
if(dataLen!=0)
{
//拷贝数据
memcpy((char*)TxBuffer2.m_entry,(char*)RxBuffer2.m_entry,dataLen);
//查询发送数据
UART_SendBuf_Polling(CW_UART2,TxBuffer2.m_entry,dataLen);
USART2_Clear();
}
SysTickDelay(1000);
myLED.toggle();
}
}
```
- 5、查看串口终端收发
![image-20241115144847070](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241115144847070.png)
从截图可以看出,当前收发数据一致;
## 控制台Shell
下面介绍下开源项目是 letter-shell,一个功能强大的嵌入式shell,letter shell 3.x是一个C语言编写的,可以嵌入在程序中的嵌入式shell,通俗一点说就是一个串口命令行,可以通过命令行调用、运行程序中的函数。目前 letter-shell 3.0版本支持的功能有:
- 命令自动补全
- 快捷键功能定义
- 命令权限管理
- 用户管理
- 变量支持
> 项目地址:https://github.com/NevermindZZT/letter-shell
移植过程:
- 1.复制源码到工程中:
![image-20241115165344228](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241115165344228.png)
- 2.在自定义接口`shell_port.c`中实现自己的串口读写函数
```C
#include "shell.h"
#include "main.h"
#include "bsp_uart2.h"
#include "shell_port.h"
Shell shell;
char shellBuffer[512];
/**
* @brief 用户shell写
*
* @param data 数据
* @param len 数据长度
*
* @return short 实际写入的数据长度
*/
short userShellWrite(char *data, unsigned short len)
{
UART_SendBuf_Polling(CW_UART2,(uint8_t *)data, len);
return len;
}
/**
* @brief 用户shell读
*
* @param data 数据
* @param len 数据长度
*
* @return short 实际读取到
*/
short userShellRead(char *data, unsigned short len)
{
return UART2_GetString((uint8_t *)data, len);
}
/**
* @brief 用户shell上锁
*
* @param shell shell
*
* @return int 0
*/
int userShellLock(Shell *shell)
{
return 0;
}
/**
* @brief 用户shell解锁
*
* @param shell shell
*
* @return int 0
*/
int userShellUnlock(Shell *shell)
{
return 0;
}
/**
* @brief 用户shell初始化
*
*/
void userShellInit(void)
{
//注册自己实现的写函数
shell.write = userShellWrite;
// shell.read = userShellRead;
//调用shell初始化函数
shellInit(&shell, shellBuffer, 512);
}
```
- 3.在终端函数中定义
对于裸机环境,在主循环中调用`shellTask`,或者在接收到数据时,调用`shellHandler`,我这里在中断中调用
```C
void UART2_IRQHandler(void)
{
/* USER CODE BEGIN */
uint8_t TxRxBuffer;
if (UART_GetITStatus(CW_UART2, UART_IT_RC) != RESET)
{
/*使用简易队列进行接收数据*/
TxRxBuffer = UART_ReceiveData_8bit(CW_UART2);
shellHandler(&shell,TxRxBuffer);
CBUF_Push(RxBuffer2, TxRxBuffer);
UART_ClearITPendingBit(CW_UART2, UART_IT_RC);
}
/* USER CODE END */
}
```
- 4.调用初始化shell
```C
userShellInit();
```
- 5.串口终端实现结果
![image-20241115170003058](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241115170003058.png)
查看当前系统时钟:
![image-20241115170036353](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20241115170036353.png)
其他实现方式,参考官方文档说明。
- 2024-11-05
-
加入了学习《自己动手写操作系统》,观看 通过修改SP,来修改调用的函数
-
加入了学习《自己动手写操作系统》,观看 自己动手写操作系统
- 2024-08-26
-
加入了学习《CH582 微信小程序控制LED》,观看 CH582 微信小程序控制LED
-
加入了学习《CH582 蓝牙控制LED》,观看 CH582 蓝牙控制LED
- 2024-08-19
-
回复了主题帖:
NUCLEO-H533RE开发板测评10(LVGL综合应用)
wangerxian 发表于 2024-8-19 17:09
老兄的Keil配色挺别致的,和屏幕设计一个配色
常规配置
-
回复了主题帖:
NUCLEO-H533RE开发板测评10(LVGL综合应用)
秦天qintian0303 发表于 2024-8-18 21:36
你这屏有点大啊,幸亏STM32H533的主频够高
图形化就选择一个屏幕大点的
- 2024-08-17
-
发表了主题帖:
NUCLEO-H533RE开发板测评10(LVGL综合应用)
## 10.LVGL显示温湿度
### 10.1:SHT30温湿度模块
采用SHT30温湿度模块来获取温湿度数据,模块如下:
![image-20240817163127313](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240817163127313.png)
接口是IIC,使用PB6和PB7。使用cubemx配置,具体前面的文章的IIC配置,基本一致。SHT30的i2c地址是0x44;
其中温湿度数据处理函数:
```C
void sHT30 Read(float *temperature, float *humidity)
{
uint8 t buf[6];
float temp, hum;
buf[0]= 0x2c;
buf[1]= 0x06;
HAL I2C Master Transmit(&hi2c1,SHT30 I2C ADDRESS, buf, 2, 1000);HAL Delay(20);
HAL I2C Master Receive(&hi2c1,SHT30 I2C ADDRESS, buf, 6, 1000);
uint16 t st = buf[e]
- 2024-08-15
-
发表了主题帖:
NUCLEO-H533RE开发板测评09(HASH算法加密)
群里已经看到关于AES加解密的,这里就评测下hash算法加密
## 9:HASH算法加密
在现代计算机领域,数据的完整性和安全性是非常重要的,为了保证数据的完整性,我们需要使用一些算法进行数据校验。其中,哈希算法是最常用的一种算法之一,SHA1、SHA256、SHA384和SHA512都是SHAHash Algorithm)系列的哈希算法,它们的区别主要在于输出长度和运算速度。
![image-20240815152458282](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240815152458282.png)
### 9.1:SHA1验证
下面结合板子进行测试,首先测试SHA1,配置cubemx,使能hash算法;
![image-20240815152847192](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240815152847192.png)
自动化生成代码之后,初始化hash算法,调用如下函数:
```
MX_HASH_Init();
```
打比方初始化设置需要加密的内容为“123456”,SHA1的结果为
```C
7c4a8d09ca3762af61e59520943dc26494f8941b
```
打开hash校验算法网址
https://tool.528sq.cn/allencrypt/
![image-20240815153205026](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240815153205026.png)
编写测试代码:
```
if (HAL_HASH_Start(&hhash, (uint8_t *)Input, INPUT_TAB_SIZE, aDigest, 0xFF) != HAL_OK)
{
Error_Handler();
}
for(int i=0;i
- 2024-08-14
-
回复了主题帖:
NUCLEO-H533RE开发板测评08(LVGL移植)
Jacktang 发表于 2024-8-14 07:17
效果不错,后续针对LVGL进行优化会更好
是的,后续有时间针对LVGL好好开发,还有,SPI使用杜邦线连接,感觉时速比较慢
- 2024-08-13
-
发表了主题帖:
NUCLEO-H533RE开发板测评08(LVGL移植)
打开LVGL Guider编辑器,创建工程
![image-20240809230102539](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240809230102539.png)
选择LVGL版本,是用V8.3
![image-20240809230127272](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240809230127272.png)
选择模拟器
![image-20240809230149762](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240809230149762.png)
设计LVGL界面:
![image-20240809231545113](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240809231545113.png)
修改样式和中英文显示:
![image-20240813160225545](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240813160225545.png)
使用官方工具不用关心中文字符问题;
保存文件:
![image-20240813154757988](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240813154757988.png)
移植LVGL项目工程,打开git,下载LVGL8.3的工程包
https://gitcode.com/gh_mirrors/lv/lvgl/tree/release/v8.3?init=initRepo,
![image-20240813155029716](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240813155029716.png)
具体移植过程就有部多讲了,例程比较多,其中显示画点的函数需要先测试调通;
```C
/*Flush the content of the internal buffer the specific area on the display
*You can use DMA or any hardware acceleration to do this operation in the background but
*'lv_disp_flush_ready()' has to be called when finished.*/
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
if(disp_flush_enabled) {
/*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/
int32_t x;
int32_t y;
for(y = area->y1; y y2; y++) {
for(x = area->x1; x x2; x++) {
/*Put a pixel to the display. For example:*/
/*put_px(x, y, *color_p)*/
POINT_COLOR=color_p->full;
LCD_DrawPoint(x,y);//画一个点
color_p++;
}
}
}
/*IMPORTANT!!!
*Inform the graphics library that you are ready with the flushing*/
lv_disp_flush_ready(disp_drv);
}
```
初始化函数,也是官方的例程,需要跑通,我这里没有使用触摸,先显示图形界面,确保整个移植业务流程跑通
```C
LCD_Init(); //液晶屏初始化,就是LCD显示驱动
lv_init(); // LVGL 初始化
lv_port_disp_init(); // 注册LVGL的显示任务
// lv_port_indev_init(); // 注册LVGL的触屏检测任务,没有触摸可以屏蔽
// HAL_TIM_Base_Start_IT(&htim6); //也可以先取消,这个用于lvgl业务处理
// 按钮
lv_obj_t *myBtn = lv_btn_create(lv_scr_act()); // 创建按钮; 父对象:当前活动屏幕
lv_obj_set_pos(myBtn, 10, 10); // 设置坐标
lv_obj_set_size(myBtn, 120, 50); // 设置大小
// 按钮上的文本
lv_obj_t *label_btn = lv_label_create(myBtn); // 创建文本标签,父对象:上面的btn按钮
lv_obj_align(label_btn, LV_ALIGN_CENTER, 0, 0); // 对齐于:父对象
lv_label_set_text(label_btn, "Test"); // 设置标签的文本
// 独立的标签
lv_obj_t *myLabel = lv_label_create(lv_scr_act()); // 创建文本标签; 父对象:当前活动屏幕
lv_label_set_text(myLabel, "Hello world!"); // 设置标签的文本
lv_obj_align(myLabel, LV_ALIGN_CENTER, 0, 0); // 对齐于:父对象
lv_obj_align_to(myBtn, myLabel, LV_ALIGN_OUT_TOP_MID, 0, -20); // 对齐于:某对象
```
程序烧录之后,能显示界面,说明LVGL例程移植没有问题;
![image-20240813155642646](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240813155642646.png)
能出现这个界面,说明整个移植过程没有问题,后续将使用的LVGL界面文件添加进来,并进行初始化。
```
setup_ui(&guider_ui); // 初始化 UI
events_init(&guider_ui); // 初始化 事件
```
最后,实现结果如下:
![image-20240813155906189](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240813155906189.png)
后续针对LVGL进行优化设计;
- 2024-08-09
-
发表了主题帖:
NUCLEO-H533RE开发板测评07(SPI应用)
本次测评下SPI接口,采用4.0的LCD的屏幕
![image-20240809212109658](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240809212109658.png)
硬件接口如下:
| 序号 | 引脚标号 | 说明 |
| ------------------------------------------------------------ | --------- | --------------------------------------------------- |
| 1 | VCC | 5V/3.3V电源输入 |
| 2 | GND | 接地 |
| 3 | CS | 液晶屏片选信号,低电平使能 |
| 4 | RESET | 液晶屏复位信号,低电平复位 |
| 5 | DC/RS | 液晶屏命令/数据选择信号,低电平:命令,高电平:数据 |
| 6 | SDI(MOSI) | 液晶屏SPI总线写数据信号 |
| 7 | SCK | 液晶屏SPI总线时钟信号 |
| 8 | LED | 背光控制,高电平点亮,如无需控制则接3.3V常亮 |
| 9 | SDO(MISO) | SPI总线读数据信号,如无需读取功能则可不接 |
| (以下为触摸屏信号线接线,如无需触摸或者模块本身不带触摸功能,可不连接) | | |
| 10 | T_CLK | 触摸SPI总线时钟信号 |
| 11 | T_CS | 触摸屏片选信号,低电平使能 |
| 12 | T_DIN | 触摸SPI总线输入 |
| 13 | T_DO | 触摸SPI总线输出 |
| 14 | T_IRQ | 触摸屏中断信号,检测到触摸时为低电平 |
软件编程:
CubeMX设置
配置SPI为全双工
![image-20240809212847806](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240809212847806.png)
![image-20240809212904634](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240809212904634.png)
设置波特率为20Mbit/s,也可以设置更高,理论上可以达到100MBit/s;这里采用杜邦线连接,最高时速达不到;
总界面配置如下:
![image-20240809213112597](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240809213112597.png)
采用SPI1通讯;
软件代码程序编程:
SPI写函数:
```C
u8 SPI_WriteByte(SPI_TypeDef* SPIx,u8 Byte)
{
HAL_SPI_Transmit(&hspi1, &Byte, 1, 0x100);
}
```
GPIO口配置函数
```C
void LCD_GPIOInit(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin : PA5 */
GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
```
LCD初始化函数:
```C
void LCD_Init(void)
{
// SPI1_Init(); //硬件SPI1初始化
LCD_GPIOInit();//LCD GPIO初始化
LCD_RESET(); //LCD 复位
//*************4.0inch ILI9486初始化**********//
LCD_WR_REG(0XF1);
LCD_WR_DATA(0x36);
LCD_WR_DATA(0x04);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x3C);
LCD_WR_DATA(0X0F);
LCD_WR_DATA(0x8F);
LCD_WR_REG(0XF2);
LCD_WR_DATA(0x18);
LCD_WR_DATA(0xA3);
LCD_WR_DATA(0x12);
LCD_WR_DATA(0x02);
LCD_WR_DATA(0XB2);
LCD_WR_DATA(0x12);
LCD_WR_DATA(0xFF);
LCD_WR_DATA(0x10);
LCD_WR_DATA(0x00);
LCD_WR_REG(0XF8);
LCD_WR_DATA(0x21);
LCD_WR_DATA(0x04);
LCD_WR_REG(0XF9);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x08);
LCD_WR_REG(0x36);
LCD_WR_DATA(0x08);
LCD_WR_REG(0xB4);
LCD_WR_DATA(0x00);
LCD_WR_REG(0xC1);
LCD_WR_DATA(0x47); //0x41
LCD_WR_REG(0xC5);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0xAF); //0x91
LCD_WR_DATA(0x80);
LCD_WR_DATA(0x00);
LCD_WR_REG(0xE0);
LCD_WR_DATA(0x0F);
LCD_WR_DATA(0x1F);
LCD_WR_DATA(0x1C);
LCD_WR_DATA(0x0C);
LCD_WR_DATA(0x0F);
LCD_WR_DATA(0x08);
LCD_WR_DATA(0x48);
LCD_WR_DATA(0x98);
LCD_WR_DATA(0x37);
LCD_WR_DATA(0x0A);
LCD_WR_DATA(0x13);
LCD_WR_DATA(0x04);
LCD_WR_DATA(0x11);
LCD_WR_DATA(0x0D);
LCD_WR_DATA(0x00);
LCD_WR_REG(0xE1);
LCD_WR_DATA(0x0F);
LCD_WR_DATA(0x32);
LCD_WR_DATA(0x2E);
LCD_WR_DATA(0x0B);
LCD_WR_DATA(0x0D);
LCD_WR_DATA(0x05);
LCD_WR_DATA(0x47);
LCD_WR_DATA(0x75);
LCD_WR_DATA(0x37);
LCD_WR_DATA(0x06);
LCD_WR_DATA(0x10);
LCD_WR_DATA(0x03);
LCD_WR_DATA(0x24);
LCD_WR_DATA(0x20);
LCD_WR_DATA(0x00);
LCD_WR_REG(0x3A);
LCD_WR_DATA(0x66);
LCD_WR_REG(0x11);
LCD_WR_REG(0x36);
LCD_WR_DATA(0x28);
HAL_Delay(120);
LCD_WR_REG(0x29);
LCD_direction(USE_HORIZONTAL);//设置LCD显示方向
// LCD_LED=1;//点亮背光
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET);
LCD_Clear(WHITE);//清全屏白色
}
```
英文字符显示:
```C
void English_Font_test(void)
{
DrawTestPage("测试5:英文显示测试");
Show_Str(10,30,BLUE,YELLOW,"6X12:abcdefghijklmnopqrstuvwxyz0123456789",12,0);
Show_Str(10,45,BLUE,YELLOW,"6X12:ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",12,1);
Show_Str(10,60,BLUE,YELLOW,"6X12:~!@#$%^&*()_+{}:?/|-+.",12,0);
Show_Str(10,80,BLUE,YELLOW,"8X16:abcdefghijklmnopqrstuvwxyz0123456789",16,0);
Show_Str(10,100,BLUE,YELLOW,"8X16:ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",16,1);
Show_Str(10,120,BLUE,YELLOW,"8X16:~!@#$%^&*()_+{}:?/|-+.",16,0);
HAL_Delay(1200);
}
```
实现结果:
![image-20240809222227032](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240809222227032.png)
中文显示:
```C
void Chinese_Font_test(void)
{
DrawTestPage("测试6:中文显示测试");
Show_Str(10,30,BLUE,YELLOW,"16X16:字体测试",16,0);
Show_Str(10,50,BLUE,YELLOW,"16X16:字体测试",16,0);
Show_Str(10,70,BLUE,YELLOW,"24X24:中文测试",24,1);
Show_Str(10,100,BLUE,YELLOW,"32X32:字体测试",32,1);
HAL_Delay(1200);
}
```
实现结果:
![image-20240809222911415](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240809222911415.png)
- 2024-08-07
-
发表了主题帖:
NUCLEO-H533RE开发板测评06(IIC应用)
## 6:IIC驱动
使用硬件IIC来驱动OLED显示,查看板子的IIC接口。
![image-20240807160214538](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240807160214538.png)
OLED显示接口:
![image-20240807160401461](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240807160401461.png)
cubemx配置接口
![image-20240807160454509](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240807160454509.png)
配置参数选择默认就好,IIC速度为100KHz;
IIC通讯时序图:
![image-20240807160959714](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240807160959714.png)
程序编写:
IIC初始化配置:
```C
I2C_HandleTypeDef hi2c1;
/* I2C1 init function */
void MX_I2C1_Init(void)
{
/* USER CODE BEGIN I2C1_Init 0 */
/* USER CODE END I2C1_Init 0 */
/* USER CODE BEGIN I2C1_Init 1 */
/* USER CODE END I2C1_Init 1 */
hi2c1.Instance = I2C1;
hi2c1.Init.Timing = 0x10909CEC;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
Error_Handler();
}
/** Configure Analogue filter
*/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
Error_Handler();
}
/** Configure Digital filter
*/
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN I2C1_Init 2 */
/* USER CODE END I2C1_Init 2 */
}
```
关键的IIC读写函数
```
uint8_t CMD_Data[25]={
0xAE,//关闭显示
0xD5,//设置时钟分频因子,震荡频率
0x80, //[3:0],分频因子;[7:4],震荡频率
0xA8,//设置驱动路数
0X3F,//默认0X3F(1/64)
0xD3,//设置显示偏移
0X00,//默认为0
0x40,//设置显示开始行 [5:0],行数.
0x8D,//电荷泵设置
0x14,//bit2,开启/关闭
0x20,//设置内存地址模式
0x02,//[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10;
0xA1,//段重定义设置,bit0:0,0->0;1,0->127;
0xC8,//设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数
0xDA,//设置COM硬件引脚配置
0x12,//[5:4]配置
0x81,//对比度设置
0xEF,//1~255;默认0X7F (亮度设置,越大越亮)
0xD9,//设置预充电周期
0xf1,//[3:0],PHASE 1;[7:4],PHASE 2;
0xDB,//设置VCOMH 电压倍率
0x30,//[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;
0xA4,//全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)
0xA6,//设置显示方式;bit0:1,反相显示;0,正常显示
0xAF,//开启显示
}; //初始化命令
#define OLED_ADDRESS 0x78
void WriteCmd_init(void)
{
uint8_t i = 0;
for(i=0; i120){x=0;y+=2;}
j++;
}
}
void OLED_P8x16Str(uint8_t x,uint8_t y,uint8_t ch[])
{
uint8_t c=0,i=0,j=0;
while (ch[j]!='\0')
{
c =ch[j]-32;
if(x>120){x=0;y++;}
OLED_Set_Pos(x,y);
for(i=0;i
- 2024-07-31
-
发表了主题帖:
NUCLEO-H533RE开发板测评05(FreeRTOS应用)
## 5:FreeRTOS应用
### 5.1:CubeMX配置
打开现有工程,找到FreeRTOS的相关配置,如下:
![image-20240731110706756](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240731110706756.png)
当前配置为灰色,需要下载一下对应的资源包,以方便有对应的源码,进行install一下。
![image-20240731110836687](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240731110836687.png)
安装完成后,就有相应的freertos配置了。
![image-20240731110937585](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240731110937585.png)
安装完成之后进行配置:
![image-20240731111050368](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240731111050368.png)
接着配置RTOS
![image-20240731115508004](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240731115508004.png)
### 5.2:创建任务
我们创建2个任务,一个任务LED闪烁,一个任务串口1秒打印一次数据;
LED 闪烁任务:
```
void StartDefaultTask1(void *argument)
{
/* USER CODE BEGIN defaultTask */
/* Infinite loop */
for(;;)
{
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
vTaskDelay(500);
}
/* USER CODE END defaultTask */
}
```
串口打印任务:
```
void StartDefaultTask2(void *argument)
{
/* USER CODE BEGIN defaultTask */
/* Infinite loop */
for(;;)
{
printf("1000ms\r\n");
vTaskDelay(1000);
}
/* USER CODE END defaultTask */
}
```
在“MX_FREERTOS_Init”函数中,初始化创建这两个任务:
```
xTaskCreate(
StartDefaultTask2, // 函数指针, 任务函数
"printf_task", // 任务的名字
200, // 栈大小,单位为word,10表示40字节
NULL, // 调用任务函数时传入的参数
osPriorityNormal, // 优先级
NULL); // 任务句柄, 以后使用它来操作这个任务
xTaskCreate(
StartDefaultTask1, // 函数指针, 任务函数
"led_task", // 任务的名字
200, // 栈大小,单位为word,10表示40字节
NULL, // 调用任务函数时传入的参数
osPriorityNormal, // 优先级
NULL); // 任务句柄, 以后使用它来操作这个任务
```
5.3:实现结果
可以根据串口输出,查看自己的任务是否执行;
![image-20240731120441787](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240731120441787.png)