qzc0927

  • 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)

  • 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.還沒看,感覺也很有用

统计信息

已有163人来访过

  • 芯积分:336
  • 好友:1
  • 主题:58
  • 回复:65

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言