- static void SystemHardwareInit(void)
- {
- /* Init LEDs */
- if (LedInitialized != SET)
- {
- if (BSP_LED_Init(LED9) != BSP_ERROR_NONE)
- {
- Error_Handler();
- }
- if (BSP_LED_Init(LED10) != BSP_ERROR_NONE)
- {
- Error_Handler();
- }
- LedInitialized = SET;
- }
- /* Init User push-button in EXTI Mode */
- if (ButtonInitialized != SET)
- {
- if (BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI) != BSP_ERROR_NONE)
- {
- Error_Handler();
- }
- ButtonInitialized = SET;
- }
- /* Initialize the LCD */
- if (LcdInitialized != SET)
- {
- LCD_UTILS_Drv_t lcdDrv;
- /* Initialize the LCD */
- if (BSP_LCD_Init(0, LCD_ORIENTATION_PORTRAIT) != BSP_ERROR_NONE)
- {
- Error_Handler();
- }
- /* Set UTIL_LCD functions */
- lcdDrv.DrawBitmap = BSP_LCD_DrawBitmap;
- lcdDrv.FillRGBRect = BSP_LCD_FillRGBRect;
- lcdDrv.DrawHLine = BSP_LCD_DrawHLine;
- lcdDrv.DrawVLine = BSP_LCD_DrawVLine;
- lcdDrv.FillRect = BSP_LCD_FillRect;
- lcdDrv.GetPixel = BSP_LCD_ReadPixel;
- lcdDrv.SetPixel = BSP_LCD_WritePixel;
- lcdDrv.GetXSize = BSP_LCD_GetXSize;
- lcdDrv.GetYSize = BSP_LCD_GetYSize;
- lcdDrv.SetLayer = BSP_LCD_SetActiveLayer;
- lcdDrv.GetFormat = BSP_LCD_GetFormat;
- UTIL_LCD_SetFuncDriver(&lcdDrv);
- /* Clear the LCD */
- UTIL_LCD_Clear(UTIL_LCD_COLOR_WHITE);
- /* Set the display on */
- if (BSP_LCD_DisplayOn(0) != BSP_ERROR_NONE)
- {
- Error_Handler();
- }
- LcdInitialized = SET;
- }
- /* Initialize the TouchScreen */
- if (TsInitialized != SET)
- {
- TS_Init_t TsInit;
- /* Initialize the TouchScreen */
- TsInit.Width = 240;
- TsInit.Height = 240;
- TsInit.Orientation = TS_ORIENTATION_PORTRAIT;
- TsInit.Accuracy = 10;
- if (BSP_TS_Init(0, &TsInit) != BSP_ERROR_NONE)
- {
- Error_Handler();
- }
- /* Configure TS interrupt */
- if (BSP_TS_EnableIT(0) != BSP_ERROR_NONE)
- {
- Error_Handler();
- }
- TsInitialized = SET;
- }
- }
该函数对LED 、按钮、LCD屏幕、触摸屏进行初始化,并由初始化完成标志位变量进行置位。
LED的初始化函数如下
- int32_t BSP_LED_Init(Led_TypeDef Led)
- {
- int32_t status = BSP_ERROR_NONE;
- GPIO_InitTypeDef GPIO_Init;
- /* Enable the GPIO_LED Clock */
- if (Led == LED9)
- {
- LED9_GPIO_CLK_ENABLE();
- }
- else /* Led = LED10 */
- {
- /* Enable VddIO2 for GPIOG */
- __HAL_RCC_PWR_CLK_ENABLE();
- HAL_PWREx_EnableVddIO2();
- LED10_GPIO_CLK_ENABLE();
- }
- /* configure the GPIO_LED pin */
- GPIO_Init.Pin = LED_PIN[Led];
- GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_Init.Pull = GPIO_PULLUP;
- GPIO_Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
- HAL_GPIO_Init(LED_PORT[Led], &GPIO_Init);
- HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_SET);
- return status;
- }
该函数对IO所在的时钟进行了启用,并对IO进行配置,配置为输出高电平。
按钮的配置,如下
- int32_t BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode)
- {
- int32_t status = BSP_ERROR_NONE;
- GPIO_InitTypeDef GPIO_Init;
- uint32_t BSP_BUTTON_IT_PRIO[BUTTONn] = {BSP_BUTTON_USER_IT_PRIORITY};
- uint32_t BUTTON_EXTI_LINE[BUTTONn] = {BUTTON_USER_EXTI_LINE};
- BSP_EXTI_LineCallback ButtonCallback[BUTTONn] = {BUTTON_USER_EXTI_Callback};
- /* Enable the BUTTON clock */
- BUTTON_USER_GPIO_CLK_ENABLE();
- GPIO_Init.Pin = BUTTON_PIN[Button];
- GPIO_Init.Pull = GPIO_NOPULL;
- GPIO_Init.Speed = GPIO_SPEED_FREQ_HIGH;
- if (ButtonMode == BUTTON_MODE_GPIO)
- {
- /* Configure Button pin as input */
- GPIO_Init.Mode = GPIO_MODE_INPUT;
- HAL_GPIO_Init(BUTTON_PORT[Button], &GPIO_Init);
- }
- if (ButtonMode == BUTTON_MODE_EXTI)
- {
- /* Configure Button pin as input with External interrupt */
- GPIO_Init.Mode = GPIO_MODE_IT_RISING;
- HAL_GPIO_Init(BUTTON_PORT[Button], &GPIO_Init);
- if (HAL_EXTI_GetHandle(&hpb_exti[Button], BUTTON_EXTI_LINE[Button]) == HAL_OK)
- {
- if (HAL_EXTI_RegisterCallback(&hpb_exti[Button], HAL_EXTI_RISING_CB_ID, ButtonCallback[Button]) == HAL_OK)
- {
- /* Enable and set Button EXTI Interrupt to the lowest priority */
- HAL_NVIC_SetPriority(BUTTON_IRQn[Button], BSP_BUTTON_IT_PRIO[Button], 0x00);
- HAL_NVIC_EnableIRQ(BUTTON_IRQn[Button]);
- }
- else
- {
- status = BSP_ERROR_PERIPH_FAILURE;
- }
- }
- else
- {
- status = BSP_ERROR_PERIPH_FAILURE;
- }
- }
- return status;
- }
可配置为IO模式和中断模式
- <div>static void BUTTON_USER_EXTI_Callback(void)</div><div>{</div><div> BSP_PB_Callback(BUTTON_USER);</div><div>}</div><div>
- </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>
- </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的硬件接口初始化采用如下函数
- int32_t BSP_LCD_Init(uint32_t Instance, uint32_t Orientation)
- {
- int32_t status = BSP_ERROR_NONE;
- if ((Instance >= LCD_INSTANCES_NBR) || (Orientation > LCD_ORIENTATION_LANDSCAPE_ROT180))
- {
- status = BSP_ERROR_WRONG_PARAM;
- }
- else
- {
- /* Power up LCD */
- ST7789H2_PowerUp();
- /* Probe the LCD driver */
- if (ST7789H2_Probe(Orientation) != BSP_ERROR_NONE)
- {
- status = BSP_ERROR_COMPONENT_FAILURE;
- }
- }
- return status;
- }
根据函数定义到定义引脚的宏,知道了供电控制引脚、复位引脚、背光引脚,
- #define LCD_POWER_GPIO_PORT GPIOH
- #define LCD_POWER_GPIO_PIN GPIO_PIN_0
- #define LCD_POWER_GPIO_CLOCK_ENABLE() __HAL_RCC_GPIOH_CLK_ENABLE()
- #define LCD_RESET_GPIO_PORT GPIOF
- #define LCD_RESET_GPIO_PIN GPIO_PIN_14
- #define LCD_RESET_GPIO_CLOCK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE()
- #define LCD_BACKLIGHT_GPIO_PORT GPIOE
- #define LCD_BACKLIGHT_GPIO_PIN GPIO_PIN_1
- #define LCD_BACKLIGHT_GPIO_CLOCK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
上电函数就是对LCD供电、复位、以及打开背光
- static void ST7789H2_PowerUp(void)
- {
- GPIO_InitTypeDef GPIO_InitStruct;
- /* Initialize and configure the ST7789H2 power pin */
- LCD_POWER_GPIO_CLOCK_ENABLE();
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
- GPIO_InitStruct.Pin = LCD_POWER_GPIO_PIN;
- HAL_GPIO_Init(LCD_POWER_GPIO_PORT, &GPIO_InitStruct);
- /* Power on the ST7789H2 */
- HAL_GPIO_WritePin(LCD_POWER_GPIO_PORT, LCD_POWER_GPIO_PIN, GPIO_PIN_RESET);
- /* Initialize and configure the ST7789H2 reset pin */
- LCD_RESET_GPIO_CLOCK_ENABLE();
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
- GPIO_InitStruct.Pin = LCD_RESET_GPIO_PIN;
- HAL_GPIO_Init(LCD_RESET_GPIO_PORT, &GPIO_InitStruct);
- /* Reset the ST7789H2 */
- HAL_GPIO_WritePin(LCD_RESET_GPIO_PORT, LCD_RESET_GPIO_PIN, GPIO_PIN_RESET);
- HAL_Delay(1); /* wait at least 10us according ST7789H2 datasheet */
- HAL_GPIO_WritePin(LCD_RESET_GPIO_PORT, LCD_RESET_GPIO_PIN, GPIO_PIN_SET);
- HAL_Delay(120); /* wait maximum 120ms according ST7789H2 datasheet */
- /* Initialize GPIO for backlight control and enable backlight */
- LCD_BACKLIGHT_GPIO_CLOCK_ENABLE();
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
- GPIO_InitStruct.Pin = LCD_BACKLIGHT_GPIO_PIN;
- HAL_GPIO_Init(LCD_BACKLIGHT_GPIO_PORT, &GPIO_InitStruct);
- HAL_GPIO_WritePin(LCD_BACKLIGHT_GPIO_PORT, LCD_BACKLIGHT_GPIO_PIN, GPIO_PIN_SET);
- }
该LCD采用了并口发送数据
- /** @defgroup STM32L562E-DK_LCD_Private_Functions STM32L562E-DK LCD Private Functions
- * @{
- */
- /**
- * [url=home.php?mod=space&uid=247401]@brief[/url] Probe the ST7789H2 LCD driver.
- * @param Orientation LCD_ORIENTATION_PORTRAIT, LCD_ORIENTATION_LANDSCAPE,
- * LCD_ORIENTATION_PORTRAIT_ROT180 or LCD_ORIENTATION_LANDSCAPE_ROT180.
- * @retval BSP status.
- */
- static int32_t ST7789H2_Probe(uint32_t Orientation)
- {
- int32_t status;
- ST7789H2_IO_t IOCtx;
- uint32_t st7789h2_id;
- static ST7789H2_Object_t ST7789H2Obj;
- uint32_t lcd_orientation;
- /* Configure the LCD driver */
- IOCtx.Address = LCD_FMC_ADDRESS;
- IOCtx.Init = LCD_FMC_Init;
- IOCtx.DeInit = LCD_FMC_DeInit;
- IOCtx.ReadReg = LCD_FMC_ReadReg16;
- IOCtx.WriteReg = LCD_FMC_WriteReg16;
- IOCtx.SendData = LCD_FMC_Send;
- IOCtx.GetTick = LCD_FMC_GetTick;
- if (ST7789H2_RegisterBusIO(&ST7789H2Obj, &IOCtx) != ST7789H2_OK)
- {
- status = BSP_ERROR_BUS_FAILURE;
- }
- else if (ST7789H2_ReadID(&ST7789H2Obj, &st7789h2_id) != ST7789H2_OK)
- {
- status = BSP_ERROR_COMPONENT_FAILURE;
- }
- else if (st7789h2_id != ST7789H2_ID)
- {
- status = BSP_ERROR_UNKNOWN_COMPONENT;
- }
- else
- {
- Lcd_CompObj[0] = &ST7789H2Obj;
- Lcd_Drv[0] = (LCD_Drv_t *) &ST7789H2_Driver;
- if (Orientation == LCD_ORIENTATION_PORTRAIT)
- {
- lcd_orientation = ST7789H2_ORIENTATION_PORTRAIT;
- }
- else if (Orientation == LCD_ORIENTATION_LANDSCAPE)
- {
- lcd_orientation = ST7789H2_ORIENTATION_LANDSCAPE;
- }
- else if (Orientation == LCD_ORIENTATION_PORTRAIT_ROT180)
- {
- lcd_orientation = ST7789H2_ORIENTATION_PORTRAIT_ROT180;
- }
- else
- {
- lcd_orientation = ST7789H2_ORIENTATION_LANDSCAPE_ROT180;
- }
- if (Lcd_Drv[0]->Init(Lcd_CompObj[0], ST7789H2_FORMAT_RBG565, lcd_orientation) < 0)
- {
- status = BSP_ERROR_COMPONENT_FAILURE;
- }
- else
- {
- status = BSP_ERROR_NONE;
- }
- }
- return status;
- }
采用FMC地址给屏幕发送数据
- #define LCD_REGISTER_ADDR FMC_BANK1_1
- #define LCD_DATA_ADDR (FMC_BANK1_1 | 0x00000002UL)
- #define LCD_FMC_ADDRESS 1U
- static void Display_DemoDescription(void)
- {
- char desc[60];
- /* Set font */
- UTIL_LCD_SetFont(&Font20);
- /* Clear the LCD */
- UTIL_LCD_Clear(UTIL_LCD_COLOR_WHITE);
- /* Set the LCD Text Color */
- UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_DARKBLUE);
- UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_WHITE);
- /* Display LCD messages */
- UTIL_LCD_DisplayStringAt(0, 10, (uint8_t *)"STM32L562E-DK BSP", CENTER_MODE);
- UTIL_LCD_DisplayStringAt(0, 35, (uint8_t *)"drivers example", CENTER_MODE);
- /* Draw Bitmap */
- UTIL_LCD_DrawBitmap(80, 65, (uint8_t *)st**);
- UTIL_LCD_SetFont(&Font8);
- UTIL_LCD_DisplayStringAt(0, 220, (uint8_t *)"Copyright (c) STMicroelectronics 2019", CENTER_MODE);
- UTIL_LCD_SetFont(&Font12);
- UTIL_LCD_FillRect(0, 145, 240, 50, UTIL_LCD_COLOR_BLUE);
- UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_WHITE);
- UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_BLUE);
- UTIL_LCD_DisplayStringAt(0, 150, (uint8_t *)"Press User push-button", CENTER_MODE);
- UTIL_LCD_DisplayStringAt(0, 165, (uint8_t *)"to start :", CENTER_MODE);
- sprintf(desc,"%s example", BSP_examples[DemoIndex].DemoName);
- UTIL_LCD_DisplayStringAt(0, 180, (uint8_t *)desc, CENTER_MODE);
- }
编译工程烧录
效果不错,这个工程里出现了函数指针结构体,比较难的一个知识点。
- typedef int32_t (*ST7789H2_Write_Func)(void *, uint16_t, uint8_t *, uint32_t);
- typedef int32_t (*ST7789H2_Read_Func)(void *, uint16_t, uint8_t *, uint32_t);
- typedef int32_t (*ST7789H2_Send_Func)(void *, uint8_t *, uint32_t);
- typedef struct
- {
- ST7789H2_Write_Func WriteReg;
- ST7789H2_Read_Func ReadReg;
- ST7789H2_Send_Func SendData;
- void *handle;
- } ST7789H2_ctx_t;