- 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)
- 2024-07-30
-
发表了主题帖:
NUCLEO-H533RE开发板测评04(IAP应用升级)
## 4:FLASH操作
### 4.1:flash説明
![image-20240716153824296](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240716153824296.png)
![image-20240716155759579](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240716155759579.png)
![image-20240716155823792](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240716155823792.png)
![image-20240716155857648](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240716155857648.png)
顾名思义,单片机的flash有512个字节,有2个存储库,分别为256个字节,前面在做擦除操作的时候,后面可以进行写入擦做,每个扇区大小为8,共64个扇区。现在的单片机越来越强大,功能也越来越多,这里先使用熟悉传统的读写操作。
其中FLASH操作函数为:
```C
HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, Address, ((uint32_t)QuadWord))
```
每次写入数据为16个字节,128位。参考函数定义说明:
```C
/**
* @brief Program a quad-word at a specified address.
* @param TypeProgram Indicate the way to program at a specified address.
* This parameter can be a value of @ref FLASH_Type_Program
* @param FlashAddress specifies the address to be programmed.
* This parameter shall be aligned to the Flash word (128-bit)
* @param DataAddress specifies the address of data to be programmed
* This parameter shall be 32-bit aligned
* @retval HAL_StatusTypeDef HAL Status
*/
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
```
FLASH读写程序:
```
/*在更新内部Flash时候禁用指令缓存*/
if (HAL_ICACHE_Disable() != HAL_OK)
{
Error_Handler();
}
/*解锁Flash以启用对Flash控制寄存器的访问*/
HAL_FLASH_Unlock();
/* 擦除用户Flash区域*/
/*(由Flash USER START ADDR和FLASH USER END _ADDR定义的区域)*/
/* Get the 1st sector to erase */
FirstSector = GetSector(FLASH_USER_START_ADDR);
gpio_port_set();
setSysRunState(STATE_RUN); //开始运行
uart_device_init(DEV_UART2); // 使能DMA接收
__HAL_LINKDMA(&huart2, hdmatx, handle_GPDMA1_Channel1); // 使能串口 DMA 发送
printf("init_ok\r\n");
setSysUpdateState(INIT);
printf("FLASH_BANK_SIZE=%d\r\n",FLASH_BANK_SIZE/1024);
/* Get the 1st sector to erase */
FirstSector = GetSector(FLASH_USER_START_ADDR);
printf("FirstSector=%d\r\n",FirstSector);
/* Get the number of sector to erase from 1st sector*/
NbOfSectors = GetSector(FLASH_USER_END_ADDR) - FirstSector + 1;
printf("NbOfSectors=%d\r\n",NbOfSectors);
/* Get the bank */
BankNumber = GetBank(FLASH_USER_START_ADDR);
printf("BankNumber=%d",BankNumber);
/* Fill EraseInit structure*/
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS; //擦除类型
EraseInitStruct.Banks = BankNumber;
EraseInitStruct.Sector = FirstSector;
EraseInitStruct.NbSectors = NbOfSectors;
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK)
{
while (1)
{
Error_Handler();
}
}
Address = FLASH_USER_START_ADDR;
while (Address < FLASH_USER_END_ADDR)
{
/*往Flash里面写数据*/
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, Address, ((uint32_t)QuadWord)) == HAL_OK)
{
Address = Address + 16;
}
else
{
while (1)
{
Error_Handler();
}
}
}
/* 锁定Flash以禁止对Flash控制寄存器的访问 (建议用于保护FLASH存储器免受可能的意外操作) */
HAL_FLASH_Lock();
/* Re-enable instruction cache */
if(HAL_ICACHE_Enable() != HAL_OK)
{
Error_Handler();
}
MemoryProgramStatus = Check_Program(FLASH_USER_START_ADDR, FLASH_USER_END_ADDR, QuadWord);
/*Check if there is an issue to program data*/
if(MemoryProgramStatus != 0)
{
printf("Flash_Write_Read_Failure\r\n");
}
else
{
printf("Flash_Write_Read_Success\r\n");
}
```
### 4.2:FLASH设置
IAP程序设置
![image-20240730225734670](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240730225734670.png)
APP地址和标志位地址设置:
```
#define APP_START_ADDR 0x0800C000
#define APP_END_ADDR 0x08040000
#define IAP_UPGRADE_FLAG_ADDR (APP_END_ADDR-8192) //一个扇区有8K
```
APP程序设置
![image-20240730225758164](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240730225758164.png)
代码设置:
```C
SCB->VTOR = FLASH_BASE | 0xC000; //重映射向量表
```
APP跳转处理
```C
void iap_load_app(uint32_t appxaddr)
{
__disable_irq ();//关闭总中断
JumpAddress = *(__IO uint32_t*) (appxaddr + 4);
JumpToApplication = (pFunction) JumpAddress;
__set_MSP(*(__IO uint32_t*) appxaddr);//设置MSP堆栈指针值
JumpToApplication();
}
```
### 4.3:自定义通讯协议
| 名称 | 帧头 | 长度 | 具体数据 | 校验CRC16 |
| ---- | ------ | ------ | ------------------------ | --------- |
| 长度 | 2 | 2 | N | 2 |
| 值 | 0x55AA | 0x0101 | 包含命令,地址,数据等等 | 0x0102 |
### 4.4:上位机界面
![image-20240730230748526](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240730230748526.png)
### 4.5:实现过程
https://www.bilibili.com/video/BV1VFvCexEud/?vd_source=d89384d7551b55d1559dd2bf89310863
- 2024-07-22
-
回复了主题帖:
STM32H533样例程序出错
bigbat 发表于 2024-7-19 15:24
该项目是ST公司的例程ADC_MultiChannelSingleConversion
只要执行就回停在硬件出错循环里
&n ...
测试需要怎么接线,需要什么外设吗?
- 2024-07-16
-
回复了主题帖:
NUCLEO-H533RE开发板测评03(低功耗模式应用)
freebsder 发表于 2024-7-15 18:46
谢谢分享,期待后续!
大家一起学习交流
-
回复了主题帖:
NUCLEO-H533RE开发板测评03(低功耗模式应用)
怀揣少年梦 发表于 2024-7-15 21:49
我测试的好像没有这么高,我看看我哪里有问题
我测试的是,在低功耗模式是,睡眠,停止和待机模式,都是按键唤醒,加了任务,定时器这些,比你的功耗要高些,后续还需要优化
- 2024-07-15
-
发表了主题帖:
NUCLEO-H533RE开发板测评03(低功耗模式应用)
# 低功耗模式概述:
![image-20240715113933244](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240715113933244.png)
先说明下几个测电流接口:
![image-20240712112846019](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240712112846019.png)
测试电流接口:
![image-20240712113059852](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240712113059852.png)
DD measurement指测量供电电流。
### 3.1:睡眠模式
当中断/事件发生时,所有外围设备继续工作,并可以醒CPU。我们使用板载按键来实现唤醒。
![image-20240711174427807](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240711174427807.png)
設置PC13為外部中斷模式。
![image-20240711175521001](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240711175521001.png)
当前有以下几个任务:
1:RTC时钟任务;
2:定时器LED 灯闪烁任务
3:串口收发任务
编写代码:
使用状态机切换系统运行状态
```C
typedef enum
{
STATE_IDLE, /**< 空闲状态*/
STATE_RUN, /**< 运行状态*/
STATE_SLEEP, /**< 睡眠状态*/
STATE_STOP, /**< 停止模式*/
STATE_STANDBY, /**< 待机模式*/
}Run_State;
```
根据状态来切换运行模式:
```
void task4_hook(void)
{
RTC_TimeShow(aShowTime); //执行RTC任务
setTimeCountData(COUNT_ADD); //时间计数
GlobalData retrievedData = getData(); //获取计数值
printf("retrievedData.timeCount=%d\r\n",retrievedData.timeCount);
if(retrievedData.timeCount ==10)
{
setSysRunState(STATE_SLEEP); //进入睡眠模式测试
// setSysRunState(STATE_STOP); //进入停止模式测试
// setSysRunState(STATE_STANDBY); //进入待机模式测试
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); //关闭LED灯
}
// DEBUG_LOG("1s\r\n");
}
```
```
// 状态转换函数
void transitionToNextState(void) {
GlobalData retrievedData = getData(); //获取信息
switch (retrievedData.sysRunState) {
case STATE_IDLE:
HAL_ResumeTick();
setTimeCountData(COUNT_ZERO); //计数清0
setSysRunState(STATE_RUN);
break;
case STATE_RUN:
//TODO
break;
case STATE_SLEEP:
/*进入睡眠模式前准备工作*/
printf("cpu run into sleep....rn");
HAL_SuspendTick(); /*暂停Tick增量以防止Systick中断唤醒。否则Systick中断将在1ms内唤醒设备*/
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
break;
case STATE_STOP:
/*进入停止模式前准备工作*/
printf("cpu run into stop....rn");
HAL_SuspendTick(); /*暂停Tick增量以防止Systick中断唤醒。否则Systick中断将在1ms内唤醒设备*/
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON,PWR_STOPENTRY_WFI);
break;
case STATE_STANDBY:
/*进入待机模式前准备工作*/
printf("cpu run into standby....rn");
HAL_SuspendTick(); /*暂停Tick增量以防止Systick中断唤醒。否则Systick中断将在1ms内唤醒设备*/
HAL_PWR_EnterSTANDBYMode();
break;
default:
break;
}
}
```
使用外部中断实现各个模式的唤醒
```
void EXTI13_IRQHandler(void)
{
/* USER CODE BEGIN EXTI13_IRQn 0 */
/* USER CODE END EXTI13_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
/* USER CODE BEGIN EXTI13_IRQn 1 */
/* USER CODE END EXTI13_IRQn 1 */
}
```
然后用万用表接到JP2两端,查看系统运行电流。
系统运行时工作电流:
![image-20240715103249627](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240715103249627.png)
功耗30ma左右;
进入睡眠模式电流:
![image-20240715103324650](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240715103324650.png)
功耗15ma左右;
停止模式功耗:
![image-20240715103637521](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240715103637521.png)
功耗0.34ma左右;
![image-20240715103724108](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240715103724108.png)
功耗3.7ua左右;
具体视频如下:
https://www.bilibili.com/video/BV1jE4m1R7ay/?spm_id_from=333.999.0.0&vd_source=d89384d7551b55d1559dd2bf89310863
当前测试状态,使用按键来唤醒不同低功耗模式,整体功耗测试下来比官方的要高,后续针对具体低功耗要求进行优化。
- 2024-07-10
-
回复了主题帖:
NUCLEO-H533RE开发板测评02(串口-DMA-GPIO-定时器-RTC等各类外设实现)
Jacktang 发表于 2024-7-10 07:48
视频讲解的很细心啊,学习了
GPDMA還有一個 linked-list.還沒看,感覺也很有用
- 2024-07-09
-
回复了主题帖:
NUCLEO-H533RE开发板测评01(开发环境搭建)
秦天qintian0303 发表于 2024-7-9 07:14
现在H533是不是还是用STM32CubeIDE开发比较顺利啊,毕竟是新芯片
都一样的,感觉都比较方便
- 2024-07-08
-
发表了主题帖:
NUCLEO-H533RE开发板测评02(串口-DMA-GPIO-定时器-RTC等各类外设实现)
## 二、各类外设功能
### 2.1:串口功能应用
#### 2.1.1:Debug调试输出
为了验证各个功能模块,先配置下调试信息,由于板载自带stlink_v3,并且配备串口调试,我们使用板载串口来进行调试,stlink自动安装好驱动之后,打开串口调试工具,就可以看到串口信息了。
![image-20240707084127881](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240707084127881.png)
先查看硬件接口,配置串口信息。
![image-20240707085347035](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240707085347035.png)
图形化配置串口输出,
![image-20240707091207839](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240707091207839.png)
自动化生成代码,编译完成。
烧录程序,查看串口调试信息:
![image-20240707091850827](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240707091850827.png)
#### 2.1.2:串口中断接收数据
先配置串口中断,再图形化界面上设置:
![image-20240707124459132](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240707124459132.png)
再编写串口中断回调函数:
```C
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//串口中断回调函数
{
uint8_t tempVar =0; //临时变量
if (huart == &huart2) //判断中断来源(串口2)
{
tempVar = USART2->RDR; //一个给发送用(TDR),一个给接收用(RDR),
printf("%c",tempVar);
rxBuffer[receivedIndex++] = tempVar;
if (receivedIndex == sizeof(rxBuffer))
{
receivedIndex = 0;
}
HAL_UART_Receive_IT(&huart2, &rxBuffer[receivedIndex], 1); //再开启接收中断
}
}
```
打开串口调试助手,验证数据收发:
![image-20240707124744461](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240707124744461.png)
发送132个字节,接收132个字节。
#### 2.1.3:串口DMA介绍
STM32H5的DMA做GPDMA(General purpose direct memory access controller (GPDMA)),主要功能如下:
![image-20240707151616385](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240707151616385.png)
![image-20240707151921205](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240707151921205.png)
![image-20240707152029455](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240707152029455.png)
感觉很强大,我们就从传统的DMA进行处理;
#### 2.1.4:串口DMA接收
先进行图形化配置:
![image-20240707171757513](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240707171757513.png)
编写串口中断接收函数:
```C
#define RX_BUFFER_SIZE 20
uint8_t aRXBufferUser[RX_BUFFER_SIZE];
uint8_t aRXBufferA[RX_BUFFER_SIZE];
uint8_t aRXBufferB[RX_BUFFER_SIZE];
__IO uint32_t uwNbReceivedChars;
uint8_t *pBufferReadyForUser;
uint8_t *pBufferReadyForReception;
/*开始前处理*/
void StartReception(void)
{
/* Initializes Buffer swap mechanism (used in User callback) :
- 2 physical buffers aRXBufferA and aRXBufferB (RX_BUFFER_SIZE length)
*/
pBufferReadyForReception = aRXBufferA;
pBufferReadyForUser = aRXBufferB;
uwNbReceivedChars = 0;
if (HAL_OK != HAL_UARTEx_ReceiveToIdle_DMA(&huart2, aRXBufferUser, RX_BUFFER_SIZE))
{
Error_Handler();
}
}
/*发送接收到的数据*/
void UserDataTreatment(UART_HandleTypeDef *huart, uint8_t* pData, uint16_t Size)
{
uint8_t* pBuff = pData;
uint8_t i;
for (i = 0; i < Size; i++)
{
while (!(__HAL_UART_GET_FLAG(huart, UART_FLAG_TXE))) {}
huart->Instance->TDR = *pBuff;
pBuff++;
}
}
/*串口中断接收处理*/
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
static uint8_t old_pos = 0;
uint8_t *ptemp;
uint8_t i;
if (huart == &huart2) //判断中断来源(串口2)
{
printf("12");
/* Check if number of received data in recpetion buffer has changed */
if (Size != old_pos)
{
/* Check if position of index in reception buffer has simply be increased
of if end of buffer has been reached */
if (Size > old_pos)
{
/* Current position is higher than previous one */
uwNbReceivedChars = Size - old_pos;
/* Copy received data in "User" buffer for evacuation */
for (i = 0; i < uwNbReceivedChars; i++)
{
pBufferReadyForUser = aRXBufferUser[old_pos + i];
}
}
else
{
/* Current position is lower than previous one : end of buffer has been reached */
/* First copy data from current position till end of buffer */
uwNbReceivedChars = RX_BUFFER_SIZE - old_pos;
/* Copy received data in "User" buffer for evacuation */
for (i = 0; i < uwNbReceivedChars; i++)
{
pBufferReadyForUser = aRXBufferUser[old_pos + i];
}
/* Check and continue with beginning of buffer */
if (Size > 0)
{
for (i = 0; i < Size; i++)
{
pBufferReadyForUser[uwNbReceivedChars + i] = aRXBufferUser;
}
uwNbReceivedChars += Size;
}
}
/* Process received data that has been extracted from Rx User buffer */
UserDataTreatment(&huart2, pBufferReadyForUser, uwNbReceivedChars);
/* Swap buffers for next bytes to be processed */
ptemp = pBufferReadyForUser;
pBufferReadyForUser = pBufferReadyForReception;
pBufferReadyForReception = ptemp;
}
/* Update old_pos as new reference of position in User Rx buffer that
indicates position to which data have been processed */
old_pos = Size;
}
}
```
![image-20240707173257990](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240707173257990.png)
#### 2.1.5:串口DMA发送
配置图形化界面的时候,GPDMA由两种方式 linked-list mode和standard request mode, standard request mode就是传统的请求模式, linked-list模式就是可以将地址不连续或者长度不一样的的多个数组按照顺序发送出去,同样也可以接收数据到不同地址和大小的数组里面。我们可以定义三个buffer,然后通过DMA同时发送出去。我们先采用普通模式。
![image-20240708195604926](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240708195604926.png)
使用DMA发送函数
HAL_UART_Transmit_DMA(&huart2, pBufferReadyForUser,uwNbReceivedChars); //串口DMA发送数据
### 2.2:GPIO口输入输出
GPIO输出的话,就不多讲了,前面LED闪烁就是GPIO输出,这里再说下GPIO口输入,我们这里使用按键来做说明。先查看硬件原理图:
![image-20240708131311551](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240708131311551.png)
引脚接口为PC13。接着进行图形化界面配置:
![image-20240708135125956](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240708135125956.png)
根据原理图信息,默认为下拉,按键触发时为高电平。编写获取按键状态代码:
```C
static uint16_t get_key_input(void)
{
uint16_t key_val = NOKEY_INPUT_VALUE;
if(SET==HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13)) //默认低电平,触发按键时为高电平
{
key_val |= KEY1_INPUT_VALUE;
}
return key_val;
}
```
按键框架采用multbutton,来识别短按,长按,连续按,以及双击;编写按键任务函数:
```C
void Key_Scan_Task(void)
{
uint16_t key_val = KEY_NONE;
key.scan_flag = 1;
if (key.scan_flag)
{
key_val = key_scan();
switch (key_val)
{
case KEY1_SHORT:
printf("KEY1_SHORT.\r\n");
setKeyData(KEY1_SHORT);
break;
case KEY1_LONG:
printf("KEY1_LONG.\r\n");
setKeyData(KEY1_LONG);
break;
case KEY1_CNTINUS:
printf("KEY1_CNTINUS.\r\n");
setKeyData(KEY1_CNTINUS);
break;
case KEY1_DOUBLE:
printf("KEY1_DOUBLE.\r\n");
setKeyData(KEY1_DOUBLE);
break;
default:
break;
}
}
}
```
串口调试界面如下:
![image-20240708144359510](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240708144359510.png)
### 2.3:定时器
目的:实现1S内的定时器中断,进行LED翻转。先进行图形化配置:
使能定时器
![image-20240708154645348](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240708154645348.png)
设置分频参数:
![image-20240708144633407](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240708144633407.png)
在配置定时器中断:
![image-20240708144654120](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240708144654120.png)
```apl
理论解释:时钟源是250MHz,预分频器(Prescaler)的值设置为 25000-1 = 24999。周期(Period)的值设置为 10000-1 = 9999。
时钟源频率 / (预分频器值 + 1) = 250MHz / (24999 + 1) = 25MHz / 25000 = 10kHz,这意味着定时器每100微秒(1/10kHz)增加一次。
周期时间 = (周期值 + 1) * (1 / 计数频率) = (9999 + 1) * (1 / 10kHz) = 10000 * 0.0001s = 1s
所以,这个TIM6定时器被配置为1秒的周期。每当定时器从0计数到9999时,它会产生一个更新事件或触发一个中断(如果中断被启用),然后重新开始从0计数。
```
编写定时器中断回调函数:
```C
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM6)
{
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
}
}
```
### 2.4:RTC时钟
1:启动STM32CubeMX:打开STM32CubeMX软件。先使能RTC
![image-20240708154148862](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240708154148862.png)
2:配置时钟
![image-20240708154236995](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240708154236995.png)
3:设置参数
General选项组里配置小时模式,有24小时制和12小时制可选,
后面的127和255组合成分频系数,127实际对应128,255实际对应256,所以128×256=32768,正好实现输入32.768KHz[时钟分频](https://so.csdn.net/so/search?q=时钟分频&spm=1001.2101.3001.7020)到1Hz。
![image-20240708154346125](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240708154346125.png)
4:初始化设置时间
![image-20240708154440180](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240708154440180.png)
5:设置闹钟
![image-20240708155743949](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240708155743949.png)
6:使能闹钟中断
![image-20240708155821609](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240708155821609.png)
添加闹钟中断处理函数,当发生闹钟时候,我们打印一次数据:
```
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{
DEBUG_LOG("Alarm_Begin\r\n");
}
```
查看串口调试输出:
![image-20240708160204194](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240708160204194.png)
### 各个外设实现结果
[localvideo]9b11086fdd426579a6e34bc671c18a36[/localvideo]
- 2024-07-06
-
发表了主题帖:
NUCLEO-H533RE开发板测评01(开发环境搭建)
# STM32H5学习笔记
#学习笔记
## 1:开发环境搭建和资料获取
https://www.st.com.cn/zh/embedded-software/stm32cubeh5.html#get-software
![image-20240706215012191](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240706215012191.png)
点击工具与软件:
![image-20240706215055681](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240706215055681.png)
## 2:创建工程模块
按照日常开发经验先选择生成不带Trustzone的工程;自动生成代码提示警告,如下:
![image-20240702134206798](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240702134206798.png)
根据错误提示:使能ICACHE。
![image-20240702134442444](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240702134442444.png)
修改后再自动生成代码。
![image-20240702142105289](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240702142105289.png)
## 3:配置时钟
STM32H523产品系列具有256至512 KB的Flash存储器、272 KB SRAM,提供39至144引脚的BGA和LQFP封装,以及WLCSP39和UFQFN48封装。
STM32H533产品系列除了具有512 KB Flash存储器,还采用了额外的硬件加密加速引擎(AES、PKA和OTFDEC)以及ST-iROT。
这两个产品系列均采用Arm® Cortex®-M33内核,并搭载面向Armv8-M的TrustZone®技术、DSP和浮点单元 (FPU),运行频率高达250 MHz,环境温度范围可选,最高可达125 °C。我们这里配置250M时钟。先查看电路图:
![image-20240706215511515](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240706215511515.png)
实现250M的时钟,时钟计算配置为,24/12*250/2=250M;
![image-20240706215627021](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240706215627021.png)
## 4:LED点灯
LED引脚接口:
![image-20240706220002781](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240706220002781.png)
引脚接口为PA5。
图形化配置:
![image-20240706220038549](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240706220038549.png)
再次点击自动化生成代码:
![image-20240706220127255](https://boreyun.oss-cn-shanghai.aliyuncs.com/image-20240706220127255.png)
添加代码,设置LED循环翻转亮灭:
```c
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ICACHE_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
HAL_Delay(500);
}
/* USER CODE END 3 */
}
```
## ==5:实现结果==
[localvideo]fd5023a8fa9610e6807b5c588e7ca6f3[/localvideo]
至此,开发环境搭建完毕,后续进行外设开发,包含GPIO口按键,串口USART,定时器输出,RTC时钟;