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

[复制链接]
1621|0
 楼主| gaoyang9992006 发表于 2025-2-5 11:59 | 显示全部楼层 |阅读模式
该工程所在位置   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. }



编译工程烧录
8996767a2e1ce5ef9f.jpg

795967a2e1e05fd52.png

效果不错,这个工程里出现了函数指针结构体,比较难的一个知识点。
  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;



您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:如果你觉得我的分享或者答复还可以,请给我点赞,谢谢。

2052

主题

16403

帖子

222

粉丝
快速回复 在线客服 返回列表 返回顶部