前言
随着物联网、智能家居、智能控制等行业的极速发展,小而美的且反应迅速且成本低的,模块化,定制化的嵌入式系统的需求越来越大,其中降低使用要求,提高用户体验,人机交互是一个非常好的方法,所以本文记录的是调试rtthread+lcd+emwin GUI的记录及流程
一、资源介绍
硬件是自行画的PCB板,资源如下
- MCU:STM32F407ZGT6
- LCD:3.2寸320*240分辨率,驱动芯片:ILI9341。 引脚除了RESET和背光控制引脚,其他引脚连接均和正点原子的STM32F407探索者开发板兼容
- 使用FSMC接口驱动
软件是使用rtthread studio1.1.5版本
二、配置过程
1.添加emwin软件包
使能示例保存之后工程的packges下就会有该软件包,其中该软件包是有LCD和OLED驱动的demo的,看了一下和正点原子的驱动是差不多的,可以直接拿来使用的,工程内是没有这个demo文件夹的,所以选中该软件包右击打开资源所在目录软件包里面有demo文件夹,我使用的是lcd驱动,所以把drv_lcd.h和drv_lcd.h两个文件拷贝到驱动drivers文件夹中如下
2.配置外部引脚
配置片外FSMC接口,本人的配置如下
static void HAL_FSMC_MspInit(void){
/* USER CODE BEGIN FSMC_MspInit 0 */
/* USER CODE END FSMC_MspInit 0 */
GPIO_InitTypeDef GPIO_InitStruct ={
0};
/* Peripheral clock enable */
__HAL_RCC_FSMC_CLK_ENABLE();
/*lcd IO config*/
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
//PD0,1,4,5,8,9,10,14,15
GPIO_InitStruct.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_8|\
GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_14|GPIO_PIN_15;
GPIO_InitStruct.Mode=GPIO_MODE_AF_PP; //ÍÆÍ츴ÓÃ
GPIO_InitStruct.Pull=GPIO_PULLUP; //ÉÏÀ
GPIO_InitStruct.Speed=GPIO_SPEED_HIGH; //¸ßËÙ
GPIO_InitStruct.Alternate=GPIO_AF12_FSMC; //¸´ÓÃΪFSMC
HAL_GPIO_Init(GPIOD,&GPIO_InitStruct); //³õʼ»¯
//PE7,8,9,10,11,12,13,14,15
GPIO_InitStruct.Pin=GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|\
GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
HAL_GPIO_Init(GPIOE,&GPIO_InitStruct);
//PF12
GPIO_InitStruct.Pin=GPIO_PIN_12;
HAL_GPIO_Init(GPIOF,&GPIO_InitStruct);
//PG12
GPIO_InitStruct.Pin=GPIO_PIN_12;
HAL_GPIO_Init(GPIOG,&GPIO_InitStruct);
/* USER CODE END FSMC_MspInit 1 */
}
stm32f4xx_hal_conf.h文件中使能以下宏定义
#define HAL_CRC_MODULE_ENABLED
#define HAL_SRAM_MODULE_ENABLED
由于RT-Thread studio创建的工程是没有LL库的源文件的,FSMC接口需要使用到stm32f4xx_ll_fsmc.c和stm32f4xx_ll_fmc.c这两个文件,所以需要将STM32CUBE生成的工程中的库文件拷贝这两个文件到工程中
打开drv_lcd.c文件修改LCD_BL定义,我在别处直接和其他IO一起驱动了,所以该文件下的关于这个LCD_BL引脚的操作全注释了
LCD屏幕接口的LCD_BL和LCD_RESET及电源PWR配置如下
提示:硬件是使用了MOS管进行对LCD的电源控制,下面是上电之后直接打开电源
#define PWR_PIN GET_PIN(C, 2)
#define LCD_BL GET_PIN(A, 6)
#define LCD_RESET GET_PIN(A, 4)
static int open_lcd_power(void)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
rt_pin_mode(PWR_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(LCD_BL, PIN_MODE_OUTPUT);
rt_pin_mode(LCD_RESET, PIN_MODE_OUTPUT);
rt_pin_write(PWR_PIN, PIN_HIGH);
rt_pin_write(LCD_BL, PIN_HIGH);
rt_pin_write(LCD_RESET, PIN_HIGH);
return RT_EOK;
}
INIT_BOARD_EXPORT(open_lcd_power);
注意:此时直接编译会报错,原因是该软件包的作者是使用keil制作和上传的,所以emwin的库是keil的
解决方法:官方库找一个GCC编译器的库使用,这里简单粗暴的直接将keil的库修改成GCC库的格式竟然也能使用,就先用着吧,后面再去找吧
此时编译仍然有错如下
未定义_sbrk函数,该函数需要使用libc,所以在软件包上使能这个libc就可以了
保存编译无误(警告都是因为库不兼容的问题,暂时可以不管,后面可以找到gcc编译的库进行替代)
emwin GUI是需要使用到硬件CRC的,所以需要打开CRC时钟,打开GUI_Test.c文件添加代码,按照严格一点使用cube生成HAL_CRC_MspInit函数,也可以简单粗暴在前面直接加__HAL_RCC_CRC_CLK_ENABLE()函数,既然测试程序是用函数调用那就按照标准来吧
提示:这里有个坑就是CrcHandle.State默认竟然不是HAL_CRC_STATE_RESET,导致无法打开这个时钟,所以强制先让他等于HAL_CRC_STATE_RESET状态(还是要粗暴一点)
void HAL_CRC_MspInit(CRC_HandleTypeDef* hcrc)
{
if(hcrc->Instance==CRC)
{
__HAL_RCC_CRC_CLK_ENABLE();
}
}
static void test_thread(void *param)
{
CRC_HandleTypeDef CrcHandle;
CrcHandle.Instance = CRC;
CrcHandle.State = HAL_CRC_STATE_RESET;
HAL_CRC_Init(&CrcHandle);
GUI_Init();
GUIDEMO_Main();
}
此时编译下载则正常运行
总结
- emwin一定是需要使能CRC的,我直接使用函数驱动在CRC状态这导致时钟没打开卡了好久
- LCD屏幕的RESET引脚一定要拉高,当时自己画板子的时候没有直接接到板子的引脚悬空导致屏幕无法工作
- 软件包的没有LCD引脚配置的,需要自己根据自己的接口进行配置
- emwin库文件和libc需要打开