news 2026/4/23 18:42:58

[STM32L5] STM32L562E-DK开发板的BSP学习

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
[STM32L5] STM32L562E-DK开发板的BSP学习

该工程所在位置 STM32Cube_FW_L5_V1.5.0\Projects\STM32L562E-DK\Examples\BSP\MDK-ARM
打开工程,找到main.c的main函数,查看硬件初始化函数

复制

  1. static void SystemHardwareInit(void)
  2. {
  3. /* Init LEDs */
  4. if (LedInitialized != SET)
  5. {
  6. if (BSP_LED_Init(LED9) != BSP_ERROR_NONE)
  7. {
  8. Error_Handler();
  9. }
  10. if (BSP_LED_Init(LED10) != BSP_ERROR_NONE)
  11. {
  12. Error_Handler();
  13. }
  14. LedInitialized = SET;
  15. }
  16. /* Init User push-button in EXTI Mode */
  17. if (ButtonInitialized != SET)
  18. {
  19. if (BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI) != BSP_ERROR_NONE)
  20. {
  21. Error_Handler();
  22. }
  23. ButtonInitialized = SET;
  24. }
  25. /* Initialize the LCD */
  26. if (LcdInitialized != SET)
  27. {
  28. LCD_UTILS_Drv_t lcdDrv;
  29. /* Initialize the LCD */
  30. if (BSP_LCD_Init(0, LCD_ORIENTATION_PORTRAIT) != BSP_ERROR_NONE)
  31. {
  32. Error_Handler();
  33. }
  34. /* Set UTIL_LCD functions */
  35. lcdDrv.DrawBitmap = BSP_LCD_DrawBitmap;
  36. lcdDrv.FillRGBRect = BSP_LCD_FillRGBRect;
  37. lcdDrv.DrawHLine = BSP_LCD_DrawHLine;
  38. lcdDrv.DrawVLine = BSP_LCD_DrawVLine;
  39. lcdDrv.FillRect = BSP_LCD_FillRect;
  40. lcdDrv.GetPixel = BSP_LCD_ReadPixel;
  41. lcdDrv.SetPixel = BSP_LCD_WritePixel;
  42. lcdDrv.GetXSize = BSP_LCD_GetXSize;
  43. lcdDrv.GetYSize = BSP_LCD_GetYSize;
  44. lcdDrv.SetLayer = BSP_LCD_SetActiveLayer;
  45. lcdDrv.GetFormat = BSP_LCD_GetFormat;
  46. UTIL_LCD_SetFuncDriver(&lcdDrv);
  47. /* Clear the LCD */
  48. UTIL_LCD_Clear(UTIL_LCD_COLOR_WHITE);
  49. /* Set the display on */
  50. if (BSP_LCD_DisplayOn(0) != BSP_ERROR_NONE)
  51. {
  52. Error_Handler();
  53. }
  54. LcdInitialized = SET;
  55. }
  56. /* Initialize the TouchScreen */
  57. if (TsInitialized != SET)
  58. {
  59. TS_Init_t TsInit;
  60. /* Initialize the TouchScreen */
  61. TsInit.Width = 240;
  62. TsInit.Height = 240;
  63. TsInit.Orientation = TS_ORIENTATION_PORTRAIT;
  64. TsInit.Accuracy = 10;
  65. if (BSP_TS_Init(0, &TsInit) != BSP_ERROR_NONE)
  66. {
  67. Error_Handler();
  68. }
  69. /* Configure TS interrupt */
  70. if (BSP_TS_EnableIT(0) != BSP_ERROR_NONE)
  71. {
  72. Error_Handler();
  73. }
  74. TsInitialized = SET;
  75. }
  76. }

该函数对LED 、按钮、LCD屏幕、触摸屏进行初始化,并由初始化完成标志位变量进行置位。
LED的初始化函数如下

复制

  1. int32_t BSP_LED_Init(Led_TypeDef Led)
  2. {
  3. int32_t status = BSP_ERROR_NONE;
  4. GPIO_InitTypeDef GPIO_Init;
  5. /* Enable the GPIO_LED Clock */
  6. if (Led == LED9)
  7. {
  8. LED9_GPIO_CLK_ENABLE();
  9. }
  10. else /* Led = LED10 */
  11. {
  12. /* Enable VddIO2 for GPIOG */
  13. __HAL_RCC_PWR_CLK_ENABLE();
  14. HAL_PWREx_EnableVddIO2();
  15. LED10_GPIO_CLK_ENABLE();
  16. }
  17. /* configure the GPIO_LED pin */
  18. GPIO_Init.Pin = LED_PIN[Led];
  19. GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
  20. GPIO_Init.Pull = GPIO_PULLUP;
  21. GPIO_Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  22. HAL_GPIO_Init(LED_PORT[Led], &GPIO_Init);
  23. HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_SET);
  24. return status;
  25. }

该函数对IO所在的时钟进行了启用,并对IO进行配置,配置为输出高电平。
按钮的配置,如下

复制

  1. int32_t BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode)
  2. {
  3. int32_t status = BSP_ERROR_NONE;
  4. GPIO_InitTypeDef GPIO_Init;
  5. uint32_t BSP_BUTTON_IT_PRIO[BUTTONn] = {BSP_BUTTON_USER_IT_PRIORITY};
  6. uint32_t BUTTON_EXTI_LINE[BUTTONn] = {BUTTON_USER_EXTI_LINE};
  7. BSP_EXTI_LineCallback ButtonCallback[BUTTONn] = {BUTTON_USER_EXTI_Callback};
  8. /* Enable the BUTTON clock */
  9. BUTTON_USER_GPIO_CLK_ENABLE();
  10. GPIO_Init.Pin = BUTTON_PIN[Button];
  11. GPIO_Init.Pull = GPIO_NOPULL;
  12. GPIO_Init.Speed = GPIO_SPEED_FREQ_HIGH;
  13. if (ButtonMode == BUTTON_MODE_GPIO)
  14. {
  15. /* Configure Button pin as input */
  16. GPIO_Init.Mode = GPIO_MODE_INPUT;
  17. HAL_GPIO_Init(BUTTON_PORT[Button], &GPIO_Init);
  18. }
  19. if (ButtonMode == BUTTON_MODE_EXTI)
  20. {
  21. /* Configure Button pin as input with External interrupt */
  22. GPIO_Init.Mode = GPIO_MODE_IT_RISING;
  23. HAL_GPIO_Init(BUTTON_PORT[Button], &GPIO_Init);
  24. if (HAL_EXTI_GetHandle(&hpb_exti[Button], BUTTON_EXTI_LINE[Button]) == HAL_OK)
  25. {
  26. if (HAL_EXTI_RegisterCallback(&hpb_exti[Button], HAL_EXTI_RISING_CB_ID, ButtonCallback[Button]) == HAL_OK)
  27. {
  28. /* Enable and set Button EXTI Interrupt to the lowest priority */
  29. HAL_NVIC_SetPriority(BUTTON_IRQn[Button], BSP_BUTTON_IT_PRIO[Button], 0x00);
  30. HAL_NVIC_EnableIRQ(BUTTON_IRQn[Button]);
  31. }
  32. else
  33. {
  34. status = BSP_ERROR_PERIPH_FAILURE;
  35. }
  36. }
  37. else
  38. {
  39. status = BSP_ERROR_PERIPH_FAILURE;
  40. }
  41. }
  42. return status;
  43. }

可配置为IO模式和中断模式

复制

  1. <div>static void BUTTON_USER_EXTI_Callback(void)</div><div>{</div><div> BSP_PB_Callback(BUTTON_USER);</div><div>}</div><div>
  2. </div><div><div>__weak void BSP_PB_Callback(Button_TypeDef Button)</div><div>{</div><div> /* Prevent unused argument(s) compilation warning */</div><div> UNUSED(Button);</div><div>
  3. </div><div> /* This function should be implemented by the user application.</div><div> It is called into this driver when an event on Button is triggered. */</div><div>}</div></div>


层层嵌套,不知道这么做目的是不是为了可移植性。

LCD的硬件接口初始化采用如下函数

复制

  1. int32_t BSP_LCD_Init(uint32_t Instance, uint32_t Orientation)
  2. {
  3. int32_t status = BSP_ERROR_NONE;
  4. if ((Instance >= LCD_INSTANCES_NBR) || (Orientation > LCD_ORIENTATION_LANDSCAPE_ROT180))
  5. {
  6. status = BSP_ERROR_WRONG_PARAM;
  7. }
  8. else
  9. {
  10. /* Power up LCD */
  11. ST7789H2_PowerUp();
  12. /* Probe the LCD driver */
  13. if (ST7789H2_Probe(Orientation) != BSP_ERROR_NONE)
  14. {
  15. status = BSP_ERROR_COMPONENT_FAILURE;
  16. }
  17. }
  18. return status;
  19. }

根据函数定义到定义引脚的宏,知道了供电控制引脚、复位引脚、背光引脚,

复制

  1. #define LCD_POWER_GPIO_PORT GPIOH
  2. #define LCD_POWER_GPIO_PIN GPIO_PIN_0
  3. #define LCD_POWER_GPIO_CLOCK_ENABLE() __HAL_RCC_GPIOH_CLK_ENABLE()
  4. #define LCD_RESET_GPIO_PORT GPIOF
  5. #define LCD_RESET_GPIO_PIN GPIO_PIN_14
  6. #define LCD_RESET_GPIO_CLOCK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE()
  7. #define LCD_BACKLIGHT_GPIO_PORT GPIOE
  8. #define LCD_BACKLIGHT_GPIO_PIN GPIO_PIN_1
  9. #define LCD_BACKLIGHT_GPIO_CLOCK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()

上电函数就是对LCD供电、复位、以及打开背光

复制

  1. static void ST7789H2_PowerUp(void)
  2. {
  3. GPIO_InitTypeDef GPIO_InitStruct;
  4. /* Initialize and configure the ST7789H2 power pin */
  5. LCD_POWER_GPIO_CLOCK_ENABLE();
  6. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  7. GPIO_InitStruct.Pull = GPIO_NOPULL;
  8. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  9. GPIO_InitStruct.Pin = LCD_POWER_GPIO_PIN;
  10. HAL_GPIO_Init(LCD_POWER_GPIO_PORT, &GPIO_InitStruct);
  11. /* Power on the ST7789H2 */
  12. HAL_GPIO_WritePin(LCD_POWER_GPIO_PORT, LCD_POWER_GPIO_PIN, GPIO_PIN_RESET);
  13. /* Initialize and configure the ST7789H2 reset pin */
  14. LCD_RESET_GPIO_CLOCK_ENABLE();
  15. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  16. GPIO_InitStruct.Pull = GPIO_NOPULL;
  17. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  18. GPIO_InitStruct.Pin = LCD_RESET_GPIO_PIN;
  19. HAL_GPIO_Init(LCD_RESET_GPIO_PORT, &GPIO_InitStruct);
  20. /* Reset the ST7789H2 */
  21. HAL_GPIO_WritePin(LCD_RESET_GPIO_PORT, LCD_RESET_GPIO_PIN, GPIO_PIN_RESET);
  22. HAL_Delay(1); /* wait at least 10us according ST7789H2 datasheet */
  23. HAL_GPIO_WritePin(LCD_RESET_GPIO_PORT, LCD_RESET_GPIO_PIN, GPIO_PIN_SET);
  24. HAL_Delay(120); /* wait maximum 120ms according ST7789H2 datasheet */
  25. /* Initialize GPIO for backlight control and enable backlight */
  26. LCD_BACKLIGHT_GPIO_CLOCK_ENABLE();
  27. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  28. GPIO_InitStruct.Pull = GPIO_NOPULL;
  29. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  30. GPIO_InitStruct.Pin = LCD_BACKLIGHT_GPIO_PIN;
  31. HAL_GPIO_Init(LCD_BACKLIGHT_GPIO_PORT, &GPIO_InitStruct);
  32. HAL_GPIO_WritePin(LCD_BACKLIGHT_GPIO_PORT, LCD_BACKLIGHT_GPIO_PIN, GPIO_PIN_SET);
  33. }

该LCD采用了并口发送数据

复制

  1. /** @defgroup STM32L562E-DK_LCD_Private_Functions STM32L562E-DK LCD Private Functions
  2. * @{
  3. */
  4. /**
  5. * [url=home.php?mod=space&uid=247401]@brief[/url] Probe the ST7789H2 LCD driver.
  6. * @param Orientation LCD_ORIENTATION_PORTRAIT, LCD_ORIENTATION_LANDSCAPE,
  7. * LCD_ORIENTATION_PORTRAIT_ROT180 or LCD_ORIENTATION_LANDSCAPE_ROT180.
  8. * @retval BSP status.
  9. */
  10. static int32_t ST7789H2_Probe(uint32_t Orientation)
  11. {
  12. int32_t status;
  13. ST7789H2_IO_t IOCtx;
  14. uint32_t st7789h2_id;
  15. static ST7789H2_Object_t ST7789H2Obj;
  16. uint32_t lcd_orientation;
  17. /* Configure the LCD driver */
  18. IOCtx.Address = LCD_FMC_ADDRESS;
  19. IOCtx.Init = LCD_FMC_Init;
  20. IOCtx.DeInit = LCD_FMC_DeInit;
  21. IOCtx.ReadReg = LCD_FMC_ReadReg16;
  22. IOCtx.WriteReg = LCD_FMC_WriteReg16;
  23. IOCtx.SendData = LCD_FMC_Send;
  24. IOCtx.GetTick = LCD_FMC_GetTick;
  25. if (ST7789H2_RegisterBusIO(&ST7789H2Obj, &IOCtx) != ST7789H2_OK)
  26. {
  27. status = BSP_ERROR_BUS_FAILURE;
  28. }
  29. else if (ST7789H2_ReadID(&ST7789H2Obj, &st7789h2_id) != ST7789H2_OK)
  30. {
  31. status = BSP_ERROR_COMPONENT_FAILURE;
  32. }
  33. else if (st7789h2_id != ST7789H2_ID)
  34. {
  35. status = BSP_ERROR_UNKNOWN_COMPONENT;
  36. }
  37. else
  38. {
  39. Lcd_CompObj[0] = &ST7789H2Obj;
  40. Lcd_Drv[0] = (LCD_Drv_t *) &ST7789H2_Driver;
  41. if (Orientation == LCD_ORIENTATION_PORTRAIT)
  42. {
  43. lcd_orientation = ST7789H2_ORIENTATION_PORTRAIT;
  44. }
  45. else if (Orientation == LCD_ORIENTATION_LANDSCAPE)
  46. {
  47. lcd_orientation = ST7789H2_ORIENTATION_LANDSCAPE;
  48. }
  49. else if (Orientation == LCD_ORIENTATION_PORTRAIT_ROT180)
  50. {
  51. lcd_orientation = ST7789H2_ORIENTATION_PORTRAIT_ROT180;
  52. }
  53. else
  54. {
  55. lcd_orientation = ST7789H2_ORIENTATION_LANDSCAPE_ROT180;
  56. }
  57. if (Lcd_Drv[0]->Init(Lcd_CompObj[0], ST7789H2_FORMAT_RBG565, lcd_orientation) < 0)
  58. {
  59. status = BSP_ERROR_COMPONENT_FAILURE;
  60. }
  61. else
  62. {
  63. status = BSP_ERROR_NONE;
  64. }
  65. }
  66. return status;
  67. }

采用FMC地址给屏幕发送数据

复制

  1. #define LCD_REGISTER_ADDR FMC_BANK1_1
  2. #define LCD_DATA_ADDR (FMC_BANK1_1 | 0x00000002UL)
  3. #define LCD_FMC_ADDRESS 1U

复制

  1. static void Display_DemoDescription(void)
  2. {
  3. char desc[60];
  4. /* Set font */
  5. UTIL_LCD_SetFont(&Font20);
  6. /* Clear the LCD */
  7. UTIL_LCD_Clear(UTIL_LCD_COLOR_WHITE);
  8. /* Set the LCD Text Color */
  9. UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_DARKBLUE);
  10. UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_WHITE);
  11. /* Display LCD messages */
  12. UTIL_LCD_DisplayStringAt(0, 10, (uint8_t *)"STM32L562E-DK BSP", CENTER_MODE);
  13. UTIL_LCD_DisplayStringAt(0, 35, (uint8_t *)"drivers example", CENTER_MODE);
  14. /* Draw Bitmap */
  15. UTIL_LCD_DrawBitmap(80, 65, (uint8_t *)st**);
  16. UTIL_LCD_SetFont(&Font8);
  17. UTIL_LCD_DisplayStringAt(0, 220, (uint8_t *)"Copyright (c) STMicroelectronics 2019", CENTER_MODE);
  18. UTIL_LCD_SetFont(&Font12);
  19. UTIL_LCD_FillRect(0, 145, 240, 50, UTIL_LCD_COLOR_BLUE);
  20. UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_WHITE);
  21. UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_BLUE);
  22. UTIL_LCD_DisplayStringAt(0, 150, (uint8_t *)"Press User push-button", CENTER_MODE);
  23. UTIL_LCD_DisplayStringAt(0, 165, (uint8_t *)"to start :", CENTER_MODE);
  24. sprintf(desc,"%s example", BSP_examples[DemoIndex].DemoName);
  25. UTIL_LCD_DisplayStringAt(0, 180, (uint8_t *)desc, CENTER_MODE);
  26. }




编译工程烧录





效果不错,这个工程里出现了函数指针结构体,比较难的一个知识点。

复制

  1. typedef int32_t (*ST7789H2_Write_Func)(void *, uint16_t, uint8_t *, uint32_t);
  2. typedef int32_t (*ST7789H2_Read_Func)(void *, uint16_t, uint8_t *, uint32_t);
  3. typedef int32_t (*ST7789H2_Send_Func)(void *, uint8_t *, uint32_t);
  4. typedef struct
  5. {
  6. ST7789H2_Write_Func WriteReg;
  7. ST7789H2_Read_Func ReadReg;
  8. ST7789H2_Send_Func SendData;
  9. void *handle;
  10. } ST7789H2_ctx_t;




---------------------
作者:gaoyang9992006
链接:https://bbs.21ic.com/icview-3430608-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 9:48:44

运动服饰ERP适合中小品牌吗

万达宝ERP&#xff1a;模块化架构与轻量化部署的平衡之道万达宝ERP为中小运动服饰品牌提供模块化功能组合&#xff0c;企业可按需选择采购、库存、销售、财务等核心模块&#xff0c;避免一次性投入过高成本。系统支持云端部署&#xff0c;无需自建服务器&#xff0c;初始实施成…

作者头像 李华
网站建设 2026/4/23 9:48:05

VR防震减灾学习机,提升应急反应能力的关键工具

在城市化快速发展的今天&#xff0c;地震等自然灾害依然时有发生。传统防震减灾宣传多依赖于纸质手册、宣讲课程或演练&#xff0c;存在抽象、枯燥、缺乏代入感等问题&#xff0c;往往难以真正让公众掌握应急技巧。正因如此&#xff0c;VR防震减灾学习机应运而生&#xff0c;借…

作者头像 李华
网站建设 2026/4/23 11:14:50

AI写教材必备!掌握低查重技巧,让教材生成又快又好

在创作教材之前&#xff0c;选择工具总是个让人头疼的问题&#xff01;如果用普通的办公软件&#xff0c;功能简直单一得可怜&#xff0c;格式和框架得自己一点一点弄&#xff1b;换用那些专业的编写工具&#xff0c;操作可就繁琐多了&#xff0c;学会了还得花上好几天&#xf…

作者头像 李华
网站建设 2026/4/22 22:35:24

AI写论文宝藏合集!4款AI论文生成工具,为你的论文创作添动力!

在为期刊论文、毕业论文或职称论文的撰写感到烦恼吗&#xff1f;当我们用手动写作时&#xff0c;面对海量的文献&#xff0c;恍若在大海中捞针&#xff0c;而繁琐的格式规定则让人感到无奈&#xff0c;不断的修改又让人心力交瘁&#xff0c;低效率的问题成了许多学者的普遍困扰…

作者头像 李华
网站建设 2026/4/23 11:14:18

设计离职交接清单生成工具,输入岗位(行政/销售/技术),生成定制化交接清单,标注核心工作文件位置,对接人,帮离职/接手人高效交接,不留隐患。

1. 实际应用场景与痛点 场景 在企业中&#xff0c;员工离职时需要交接工作内容&#xff0c;包括&#xff1a; - 核心项目文件位置 - 对接人联系方式 - 未完成事项 - 账号权限移交 不同岗位&#xff08;行政 / 销售 / 技术&#xff09;交接重点不同&#xff1a; - 行政&#…

作者头像 李华
网站建设 2026/4/23 14:29:18

3.5 容量规划:如何预估和规划MySQL资源需求

3.5 容量规划:如何预估和规划MySQL资源需求 📚 学习目标 通过本节学习,你将掌握: ✅ 容量规划的重要性和目标 ✅ 存储、内存、CPU、IO、网络等资源的评估方法 ✅ 数据增长预测模型和容量需求计算 ✅ 容量规划的最佳实践和预警机制 ✅ 容量扩展策略和成本控制 🎯 学习收…

作者头像 李华