显示屏的移植
GUIX需要的底层接口函数已经全部集成在gx_display_driver_stm32f4_24xrgb.c文件和gx_display_driver_stm32f4_565rgb.c里面。对于这两个文件,用户仅需学会使用里面的两个宏配置以及LTDC涉及到的引脚和时序配置函数,这个是需要用户自己去实现的,配置方法已经在本章节的7.7小节进行讲解。
另外还有一个显示屏背光调节函数LCD_SetBackLight的调用,其它都不用做任何修改。这三个地方都设置了,GUIX的显示屏移植就完成了。
触摸的移植
电容触摸的移植比较容易,因为电容触摸芯片可以自动触摸校准,所以仅需配置完触摸芯片后将触摸芯片返回的触摸坐标(电容触摸芯片返回的就是实际的坐标值),按下,松手和移动三种状态发送给GUIX即可。
电阻触摸的移植要稍麻烦些,由于电阻触摸板的线性度不是很好,如果不做触摸校准和滤波处理会有点击不准确和飞点问题。当前配套2点和4点触摸校准算法,大家可以根据需要选择,默认是用的2点触摸校准算法。其中触摸滤波方法是检测到触摸后先延迟30ms,消除抖动,然后采集10组坐标值做升序排列,去掉最大的几组坐标和最小的几组坐标,对中间的几组求平均作为最终的数值(电容触摸芯片返回的是ADC数值,不是实际坐标值)。然后将最终的数值代入通过触摸校准建立的线性公式来获得实际的坐标值,此时就可以将触摸坐标和触摸按下,松手和移动状态发送给GUIX。
7.2 移植前的准备工作以及移植GUIX的流程
移植前注意以下两个问题:
本章节的IDE开发环境务必是MDK5.30及其以上版本,镜像下载地址
准备一个简单的ThreadX工程,越简单越好,我们就在这个简单的工程上面移植即可:
配套模板名称:V6-2004_ThreadX Kernel Template
GUIX的移植通过以下8步完成,下面各个小节详细讲解每一步:
第1步:ThreadX内核模板框架设计
第2步:GUIX模板框架设计(重要)
第3步:下载GUIX库并添加到ThreadX内核工程模板
第4步:SDRAM驱动的实现
第5步:LTDC涉及到的引脚配置和时序配置
第6步:电阻屏和电容屏触摸驱动的实现
第7步:GUIX底层接口函数和配置
第8步:添加GUI应用进行测试。
7.3 第1步:了解ThreadX内核模板框架设计
移植GUIX前,我们优先了解下ThreadX内核模板程序的框图。
7.3.1 准备一个ThreadX内核工程模板
首先准备好一个简单的ThreadX工程模板,工程模板的制作在ThreadX内核教程里面有详细说明,这里的重点是教大家移植GUIX,对应的例子名称:V6-2004_ThreadX Kernel Template。准备好的工程模板如下图所示(特别注意,我们这个模板已经添加裸机LCD操作所需的文件)。
7.3.2 内核框架整体把控(重要)
为了帮助大家更好的理解ThreadX内核例子模板,专门制作了一个框图,可以让大家整体把控模板设计:
下面把几个关键点逐一为大家做个说明。
7.3.3 各种头文件汇总includes.h
这个文件主要实现工程中各种头文件的汇总,大家用到的都可以将其放到这个头文件里面。其它应用源文件有调用到的,直接调用这个头文件includes.h即可。
使用这个头文件主要是方便各种头文件的管理。
7.3.4 TheadX配置文件tx_user.h
此文件主要用于ThreadX内核的配置,内核相关的几个宏配置基本都已经整理到这个文件里面。
7.3.5 系统时钟节拍配置tx_initialize_low_level.s
这个汇编文件里面有个重要参数需要大家配置,即芯片主频和系统时钟节拍。
SYSTEM_CLOCK EQU 168000000
SYSTICK_CYCLES EQU ((SYSTEM_CLOCK / 1000) -1)
168000000是系统时钟主频,1000对应的就是系统时钟节拍,这里1000就表示1000Hz。
7.3.6 TheadX任务管理main.c
ThreadX所有任务基本都在main.c里面创建,方便统一管理。如果有GUIX,FileX等组件的任务需要运行,实际运行函数会在其它源文件里面,并将这个函数extern到main.C文件里面,放到相应的任务里面执行。
另外,任务优先级,任务栈大小,任务控制块等也都放到main.C文件里面,方便管理
7.3.7 TheadX启动任务
启动任务里面主要做了四个工作:
优先执行一次任务统计OSStatInit。
外设初始化bsp_Init。
任务创建AppTaskCreate和通信组件创建AppObjCreate。
需要周期性处理的程序bsp_ProPer1ms,对应裸机工程调用的SysTick_ISR。这个的实现非常重要,这样之前裸机里面使用的API,就可以直接在ThreadX里面直接调用。
7.3.8 HAL库时间基准stm32f4xx_hal_timbase_tim.c
ThreadX系统时钟节拍默认是用的滴答定时器,STM32的HAL库时间基准也是用的滴答定时器。对于这种情况,我们一般的情况下是使用其他的通用定时器替代,不过要额外的占用一点系统性能。简单的处理办法是重新实现下面两个函数即可,让HAL库和ThreadX都使用滴答定时器
7.3.9 ThreadX使能硬件浮点
这个是移植的坑王,大家移植后,可以测试下多任务的FPU计算是否有异常。比如两个任务运行相同的浮点运算和刷新速度,看看两个任务的输出是否同步变化,这个测试非常重要:
那么问题来了,正确的使能姿势是什么?务必保证C和汇编的预定义宏里面都使能。
C里面对应的使能:
汇编里面对应的使能:
7.4 第2步:了解GUIX模板框架设计
以往我们做教程都是先介绍如何移植,然后看最后的移植效果。这次我们反过来,先看移植完成的效果,然后移植。
7.4.1 GUIX工程模板
GUIX工程模板移植完成后,大体是下面这种效果:
7.4.2 GUIX框架整体把控(重要)
为了帮助大家更好的理解GUIX内核例子模板,专门制作了一个框图,可以让大家整体把控模板设计:
下面把几个关键点逐一为大家做个说明。
7.4.3 GUIX配置文件gx_user.h
此文件主要用于GUIX的配置,GUIX相关的宏定义配置非常多,当前先把这个文件预留出来,随着后面章节的进行,用到那些宏定义了再添加。
7.4.4 外设驱动初始化文件bsp.c
使用GUIX,主要涉及到SDRAM初始化,触摸初始化,LTDC初始化(放到了GUIX底层驱动接口文件里面了),背光开启和EEPROM初始化(用于存储电阻触摸屏校准参数)
7.4.5 外设驱动头文件汇总bsp.h
此文件主要用于添加了那些外设驱动文件后,使能相应头文件,特别工程GUIX工程里面添加的一批LCD驱动和触摸驱动文件,支持的头文件如下
7.4.6 LCD裸机驱动文件
STM32F429的LCD控制器LTDC控制有两个相关的驱动文件,即bsp_tft_429.c和bsp_tft_lcd.c。移植GUIX时,这两个文件基本用不上了,已经把这两个文件实现的LTDC配置全部集成到了GUIX的底层接口驱动文件里面,方便大家移植。
7.4.7 电阻和电容触摸驱动文件
电阻和电容触摸主要用的以下几个文件:
总触摸文件,用于识别各种触摸:bsp_ts_touch.c
电容触摸文件bsp_ts_ft5x06.c
电容触摸文件bsp_ts_gt811.c
电容触摸文件bsp_ts_gt911.c
电阻触摸文件bsp_ts_stmpe811
7.4.8 电阻触摸校准参数存储到EEPROM
EEPROM的驱动主要涉及到两个文件:
bsp_i2c_gpio.c
配置EEPROM用到的两个引脚。
bsp_i2c_eeprom_24xx.c
EEPROM的读写API。
而触摸校准参数的实现是在bsp_ts_touch.c文件末尾封装好的两个函数里面
7.4.9 GUIX底层驱动接口文件
当前制作了两个底层驱动接口文件:
gx_display_driver_stm32h7_565rgb.c 对应硬件RGB565接口。
gx_display_driver_stm32h7_24xrgb.c 对应硬件RGB888接口。
大家可以根据需要选择相应驱动。
7.4.10 GUIX源码文件
GUIX的源码文件非常多,一个文件一个API,有1200个左右,大家移植的时候最好都加上。
7.4.11 GUIX应用文件
几个应用文件的作用如下:
随着后面的章节的学习,逐渐就熟练了。
7.5 第3步:添加GUIX库所有相关文件到ThreadX内核工程模板
了解了ThreadX内核框架和GUIX框架后,介绍下如何将GUIX移植到ThreadX内核工程模板里面。我们这里一步到位,直接把所有相关的文件都加上,然后再介绍如何修改,方便大家移植到自己的板子上。
7.5.1 第3.1步,下载GUIX源码包
按照第2章2.3.1小节讲解的方法下载GUIX软件包guix-6.0.1_rel(如果软件包升级了,数字6.0.1略有不同),下面是GUIX软件包内容:
主要用到两个文件夹:
common文件夹里面是源码文件。
ports文件夹里面是移植文件。
7.5.2 第3.2步,创建GUIX文件夹到工程模板
在工程模板创建GUIX文件夹
GUIX的M4内核port文件夹里面只有一个GNU(对应路径portscortex_m4),为了方便我们管理,再创建IAR,AC5和AC6三个文件夹,文件夹里面的内容和GNU里面的一样,并且再添加一个src文件夹,整体效果就是下面这样:
新建的src文件夹是用来存放GUIX底层驱动接口文件用。
7.5.3 第3.3步,添加底层驱动接口文件
添加驱动接口文件到第3.2步创建的ac5-》src和ac5-inc文件夹里面(h文件添加到inc文件夹,c文件放到src文件夹)
为了移植方便,大家直接复制本周教程配套例子在此文件夹下的文件即可。
7.5.4 第3.4步,添加Port文件和源码文件到工程
将源码文件和ports文件添加到MDK的工程项目中,添加后的效果如下:
推荐使用下面的方法添加,否则MDK会非常卡:
7.5.5 第3.5步,添加配置文件gx_user.h
在User文件夹下添加文件gx_user.h,直接从本章节教程配套例子的User文件夹复制即可。此文件主要用于GUIX配置。
为了方便管理,我们这里将路径GUIXportscortex_m4ac5inc里面的gx_port.h文件也添加进来了。
7.5.6 第3.5步,添加GUIX应用文件
在User文件夹添加文件夹GUIX,直接从本章节教程配套例子的User文件夹复制即可,此文件夹主要是GUIX的应用部分,内容如下
7.5.7 第3.6步,添加BSP驱动文件
需要添加的BSP驱动文件如下:
除了SDRAM,LTDC,EEPROM和触摸两个的文件以外,还要添加bsp_tim_pwm.c,这个是用于设置PWM背光用的。
另外注意一点,bsp_tft_lcd.c文件还关联了一些字库文件,大家最好也将其添加到工程里面。这些字库文件位于本章配套例子的User文件夹下,大家直接复制到自己工程的工程里面添加即可,添加后效果如下:
7.5.8 第3.7步,添加HAL库文件
相关BSP驱动关联到的HAL库文件都添加了进来,简单省事些,大家也可以把HAL库所有文件都添加进来:
7.5.9 第3.8步,添加预定义宏
C/C++文件中添加的预定义宏如下:
USE_HAL_DRIVER
STM32F429xx
USE_FULL_LL_DRIVER
TX_ENABLE_FPU_SUPPORT 用于支持硬件FPU
TX_ENABLE_STACK_CHECKING 用于栈检测
TX_INCLUDE_USER_DEFINE_FILE 用于包含tx_user.h
GX_INCLUDE_USER_DEFINE_FILE 用于包含gx_user.h
ASM汇编文件里面添加的宏定义:
TX_ENABLE_FPU_SUPPORT
7.5.10 第3.9步,添加头文件路径
需要添加的路径如下:
至此,我们需要的GUIX文件都已经添加完毕。下面为大家介绍如何修改用于自己的板子。
7.6 第4步:SDRAM驱动实现(用于显存,动态内存和画布)
一定要保证SDRAM大批量读写数据时是正常的,SDRAM的测试可以自己专门做一个工程测试下。对于SDRAM的驱动实现,可以学习我们写的BSP驱动教程第39章
不管你使用的是镁光的,海力士的,三星的,ISSI的或者华邦的,基本实现方法都是一样的。教程配套的板子使用的是镁光的32位带宽的SDRAM,如果想最大限度发挥STM32F429驱动SDRAM的性能,强烈建议使用32位带宽的SDRAM,或者两个16位SDRAM组成32位带宽的SDRAM也是可以的。那SDRAM主要起到什么作用呢?作用有二:
用作显示屏的显存
STM32F429的LTDC外接RGB接口屏是没有显存的,所以需要SDRAM用作显存。如果用户选择STM32F429 LTDC的颜色格式是32位色ARGB8888,那么所需要显存大小(单位字节)是:显示屏宽 * 显示屏高 * (32/8), 其中32/8是表示这种颜色格式的一个像素点需要4个字节来表示。又比如配置颜色格式是16位色的RGB565,那么需要的显存大小是:显示屏宽 * 显示屏高 * (16/8),其中16/8是表示这种颜色格式的一个像素点需要2个字节来表示。其它的颜色格式,依此类推。
用作GUIX动态内存和canvas幕布
GUIX要做的炫酷,是比较消耗动态内存的,所以用户可以将SDRAM除了用于显存以外的所有内存全部用作GUIX动态内存和canvas幕布。
如果SDRAM的驱动测试已经没有问题了,就可以将其添加到工程里面了,开发板使用的SDRAM驱动文件是bsp_fmc_sdram.c。
添加到工程里面后要分配SDRAM的使用,教程配套开发板使用的是16MB,32位带宽的SDRAM。
7.7 第5步:LTDC涉及到的引脚配置和时序配置
7.7.1 LTDC时序配置
用户仅需配置LTDC涉及到的引脚和时序即可,配置函数封装到下面两个接口文件的末尾。
gx_display_driver_stm32f4_565rgb.c 对应硬件RGB565接口。
gx_display_driver_stm32f4_24xrgb.c 对应硬件RGB888接口。
另外,由于开发板配套了4.3寸,5寸和7寸屏显示屏,所以要对这几种尺寸的显示屏做自适应,每个屏的时序配置都是不一样的,具体实现在gx_display_driver_stm32f4_565rgb.c和gx_display_driver_stm32f4_24xrgb.c接口文件末尾的,即函数LCD_LL_Init。大家在给自己的显示屏移植时主要修改这个函数即可,引脚配置需要在这个函数里面实现。下面我们再结合函数LCD_LL_Init的实现,讲解下配置时要注意的一些问题,具体代码如下
第89到123行,主要是GPIO配置,注意DMA2D时钟和LTDC时钟别忘使能。
第133到263行,这部分程序的实现在本教程第4章的4.4.4小节里面有详细说明。
第133行,六种面板的识别是在bsp_ts_touch.c文件中实现的。大家自己配置时用不到这个,仅需提供一组时序参数和输出时钟即可,除非项目中需要切换不同显示屏。
第246到247行,全局变量g_LcdWidth和g_LcdHeight在文件bsp_tft_lcd.c文件定义。如果大家自己移植时用不到文件bsp_tft_lcd.c的话,需要自行定义这两个全局变量(另外,此文件里面的背光设置函数也要自行实现),因为这两个变量要被文件gx_display_driver_stm32f4_565rgb.c和gx_display_driver_stm32f4_24xrgb.c所调用
第266到268行,STM32F429的图层是由背景层,图层1和图层2组成,这里配置的是背景层的颜色值,分别配置了R,G,B三原色的数值,范围都是0-255。
第274到300行,主要是配置图层。
第280行,如果使用RGG565颜色格式要配置为LTDC_PIXEL_FORMAT_RGB565。
如果使用ARGB8888颜色格式要配置为LTDC_PIXEL_FORMAT_ARGB8888。
7.7.2 如何验证LTDC的时序配置是否正确
下面说一个最重要的问题,配置好时序了,怎么检查自己的配置是否成功了?用户仅需在函数LCD_LL_Init里面的如下代码后面加上两个函数:
/* 配置LTDC */ if (HAL_LTDC_Init(&hltdc_F) != HAL_OK){ /* 初始化错误 */ Error_Handler(__FILE__, __LINE__);}/* 下面是添加的 */LCD_SetBackLight(BRIGHT_DEFAULT);while(1); 加上这两行代码后,再将背景层设置为一个合适的颜色,建议设置成红色,方便观察:
/* 配置背景层颜色 */hltdc_F.Init.Backcolor.Blue = 0;hltdc_F.Init.Backcolor.Green = 0;hltdc_F.Init.Backcolor.Red = 0xFF; 如果背景层可以正常显示红色,说明引脚和时序配置都是没有问题的。如果不成功要从以下几个方面着手检查:
首先要清楚一点,当前的配置是否成功与SDRAM没有任何关系,因为背景层还用不到SDRAM,图层1和图层2才需要SDRAM做显存使用。
从硬件着手检查,保证STM32F429芯片焊接没问题,TFT接口一定要牢固,防止接触不良,特别是使用FPC软排线的时候,测试阶段,软排线越短越好。有时候也可能是显示屏有问题,最好可以备两个显示屏测试。
从软件配置着手检查,查看LTDC涉及到的所有引脚是否配置,引脚时钟是否使能。有时候无法显示也有可能是板子硬件设计不规范导致干扰较大造成的,此时,可以降低LTDC所涉及到GPIO的速度等级。
如果显示了,但是显示的位置不正确,可以重新调整时序参数即可。
7.8 第6步:电阻屏和电容屏触摸驱动的实现
本小节的实现基于本教程的第5章,当前驱动对电阻触摸芯片STMPE811和电容触摸芯片FT5X06、GT911和GT811的显示屏都进行了支持。
实现比较简单,因为GUIX的触摸分按下,松手和移动三个事件,正好这几款触摸芯片的驱动也是分这三个事件,所以仅需修改下函数TOUCH_PutKey,所有显示屏触摸就都可以完美融合了。
7.8.1 添加GUIX的按下,松手和移动三个事件
文件bsp_ts_touch.c里的函数TOUCH_PutKey修改如下
特别注意0xC0000000,这个不是随便写的一个值,要与本章7.8.1小节设置STM32_SCREEN_HANDLE数值一致。
7.8.2 周期性调用触摸扫描函数
电阻触摸和电容触摸的扫描函数是TOUCH_Scan和TOUCH_CapScan,为了实现使用了ThreadX和裸机时的一样的调用方式,专门在启动任务里面周期性的调用函数bsp_ProPer1ms(SysTick_ISR),而SysTick_ISR里面调用了bsp_RunPer1ms,然后bsp_RunPer1ms里面调用扫描函数,即如下的调用关系:
7.8.3 如何将触摸驱动移植到自己的板子
通过前面的讲解,移植触摸驱动到自己的板子上,最简单的办法是将开发板与触摸相关的文件全部移植过来,然后在这些文件的基础上进行修改。下面分两种情况进行说明:
电容屏触摸的移植比较简单,如果用户用的触摸IC跟开发板一样,直接拿来用即可,如果不一样,需要先将触摸IC的驱动实现,然后按照开发板提供的GT911,GT811或者FT5X06的触摸扫描函数,照葫芦画瓢实现一个即可。
电阻屏的移植稍麻烦些,如果用户用的触摸IC跟开发板一样,直接拿来用即可,如果不一样,需要先将触摸IC的驱动实现,然后仿照bsp_ts_stmpe811.c文件提供触摸按下状态函数,X轴,Y轴的ADC数值读取函数和清除触摸中断标志函数。最后用重新实现的这几个函数替换bsp_ts_touch.c文件中的原函数即可。另外要注意一点,这种方式实现后,虽然触摸校准依然可以使用,但是开发板的触摸校准参数是保存在EEPROM中的,用户可以根据自己的实际情况选择存储介质。另外,触摸参数的保存和读取在bsp_ts_touch.c文件末尾的函数TOUCH_SaveParam和TOUCH_LoadParam实现。
如果大家不想用开发板实现的方案,想自己重新实现一个,也是没问题的,注意跟GUIX关联的方式。
7.9 第7步:GUIX底层接口函数和配置
GUI的底层接口函数和配置的实现在我们第1步中添加的底层驱动接口文件中:
gx_display_driver_stm32f4_565rgb.c 对应硬件RGB565接口。
gx_display_driver_stm32f4_24xrgb.c 对应硬件RGB888接口。
这两个文件的实现套路是一样的,我们这里以gx_display_driver_stm32f4_565rgb文件为例进行说明。
7.9.1 DMA2D使能宏定义GX_CHROMEART_ENABLE
文件开头的宏定义GX_CHROMEART_ENABLE用于使能DMA2D加速,测试阶段可以将其关闭掉,关闭方法就是注释掉宏定义#define GX_CHROMEART_ENABLE即可。
7.9.2 显存地址宏定义FrameBufer
LCD的显存地址设置是通过宏定义配置:
#define FrameBufer
SDRAM_LCD_BUF1
其中SDRAM_LCD_BUF1的定义是在bsp_fmc_sdram.h,即
7.9.3 接口函数stm32f4_graphics_driver_setup_565rgb
这个函数是GUIX连接底层最直接的函数,也是配置的关键。实现代码如下
第11行,GPIO和LTDC初始化。
第13行,为GUIX和LTDC建立关联。特别注意参数STM32_SCREEN_HANDLE,宏定义如下:
#define STM32_SCREEN_HANDLE 0xC0000000
本章7.8.1小节里面的用到的0xC0000000就是从这里来的,务必保证匹配。
第16到22行,对一些底层函数做重定向,从而实现DMA2D加速。
7.9.4 通过DMA2D加速的几个函数
通过DMA2D加速的几个函数如下(这几个函数,大家做移植的话,仅需注意变量g_LcdWidth和g_LcdHeight正确赋值了):
gx_chromeart_horizontal_line_draw
gx_chromeart_vertical_line_draw
gx_chromeart_canvas_copy
gx_chromeart_pixelmap_draw
gx_chromeart_pixelmap_blend
gx_chromeart_glyph_8bit_draw
这里我们以函数gx_chromeart_horizontal_line_draw为例进行说明
这里主要实现了一个水平线的DMA2D加速,功能比较好理解。DMA2D的详细介绍在本教程的第6章进行了非常详细的说明,大家如下想了解每个配置语句的功能,可以深入学习第6章。
7.9.5 更新画布canvas内容到LCD显存
当前GUIX的显示是采用的画布机制,即GUIX先在画布上把界面绘制好,然后将画布中需要更新的区域绘制到LCD。这部分代码是移植成功与否的关键(如果大家是用于F429平台,下面的代码无需任何修改可以直接使用):
7.10 第8步:添加GUIX应用进行测试
介绍完了前面几步,剩下就是添加应用代码了。为了方便起见,大家直接使用本章教程配套例子里面整理好的即可
7.10.1 添加应用文件MainTask.C和MainTask.h
MainTask.h是GUIX相关的头文件和函数声明,MainTask.c文件里面主要是GUIX的初始化
第20行,为了避免上电时瞬间的撕裂感,这里先关闭LCD背光,等首界面绘制完毕后再打开。
第26到30行,触摸校准函数默认是注释掉的,电阻屏需要校准,电容屏无需校准。如果用户需要校准电阻屏的话,执行此函数即可,会将触摸校准参数保存到EEPROM里面,以后系统上电会自动从EEPROM里面加载。
第36到第49行,主要是GUIX的初始化,初始化完毕后打开背光。
7.10.2 添加动态内存配置和Canvas画布配置文件
动态内存和Canvas画布配置都放在了文件App_SysFunctions.c文件里面实现。
第6到第9行,设置动态内存地址和画布的地址。
教程配套的STM32F429板子有16MB的SDRAM空间。
前4MB空间用于显存,地址0xC0000000。
中间4MB空间用于Canvas画布,地址0xC0000000 + 1024*1024*4 = 0xC0400000。
最后8MB空间用动态内存,地址0xC0000000 + 1024*1024*8 = 0xC0800000。
第17行,这个是在GUIX Studio生成的xxxxx_resources.c文件里面。注意要匹配。
第25到39行,动态内存的申请和释放函数。然后通过gx_system_memory_allocator_set进行注册。
第61到78行,实现了个简单的不同显示屏自适应。
第80行,设置Canvas画布地址。
7.10.3 添加GUIX Studio生成的文件
使用GUIX Studio生成了4个文件:
guiapp_resources.h
guiapp_resources.c
guiapp_specifications.h
guiapp_specifications.c
后面章节再为大家介绍GUIX Studio生成的这几个文件。作为移植,大家进行将其加到移植工程里面验证是否正常即可。
7.10.4 BSP初始化并创建GUIX任务
BSP初始化主要涉及到SDRAM初始化,触摸初始化,LTDC初始化(放到了GUIX底层驱动接口文件里面了),背光开启和EEPROM初始化(用于存储电阻触摸屏校准参数)
7.10.5 自动创建的GUIX系统任务。
初始化了GUIX后,会自动创建一个GUIX任务,对于这点,大家移植的使用要特别注意。此任务的优先级和任务堆栈大小是在gx_port.h文件里面定义的。
7.11 显示屏闪烁问题解决方法
如果大家调试状态下或者刚下载GUIX的程序到STM32H7/STM32F429里面时,出现屏幕会闪烁,或者说抖动,这个是正常现象。详见此贴的说明:
如果显示屏长时间处于抖动状态,说明LTDC的时钟配置高了或者低了(高的概率居多),可以将LTDC时钟降低一半或者提高一倍进行测试。配置方法看本教程第4章的4.4.3小节。
7.12 避免显示屏上电瞬间高亮和撕裂感
大家使用显示屏的时候,这两个问题很容易遇到,这里为大家提供个解决办法,提升用户体验。
7.12.1 上电瞬间高亮解决办法
这个问题并不是软件配置造成的,通过条件PWM背光也是无法解决的。解决办法是板子上后,先不要开启PWM,延迟200ms后再打开LCD的背光即可,注意时间不可以太短,太短没效果,大家可以根据实际情况做条件。本章配套程序是放在bsp.c文件的函数bsp_Init里面做了处理。
7.12.2 上电瞬间撕裂感解决办法
有时候界面设计比较复杂时,开机后不能保证所有的控件同时加载出来,界面会有种撕裂的感觉,这个时候有个比较好的解决思路,GUIX初始化配置前关闭背光,初始化完毕并且首界面绘制完毕后再打开背光,用户体验就会好很多。本章配套程序是放在MainTask.c文件的函数MainTask里面做了处理。
7.13 实验例程
(注,如果是电阻屏,需要做触摸校准,校准方法看本教程附件章节A)
本章节配套了如下几个例子供大家移植参考:
V6-2004_Threadx Kernel Template
ThreadX内核模板,用于大家移植GUIX的参考Demo,含有GCC,IAR,MDK AC5和AC6四个版本工程。
V6-2005_GUIX Template(RGB565)
GUIX模板例子,采用的硬件RGB565接口,含有GCC,IAR,MDK AC5和AC6四个版本工程。
V6-2006_GUIX Template(ARGB8888)
GUIX模板例子,采用的硬件ARGB8888接口,含有GCC,IAR,MDK AC5和AC6四个版本工程。
V6-2007_GUIX Studio Template
GUIX Studio工程模板,设计界面后,生成的文件可直接添加到MDK,IAR和GCC软件平台使用。
显示效果如下,800*480分辨率:
IAR,MDK AC5和AC6工程可以串口打印任务执行情况:按开发板的按键K1可以打印,波特率 115200,数据位 8,奇偶校验位无,停止位 1:
Embedded Studio(GCC)平台的串口打印是通过其调试组件SEGGER RTT做的串口打印,速度也非常快,打印效果如下:
展示里面有乱码是因为Embedded Studio不支持中文。
7.14 总结
本章节为大家讲解的内容涉及到的知识较多,信息量较大,部分知识点没有弄明白是没有关系的,但是一定要掌握ThreadX内核和ThreadX GUIX工程的框架设计,掌握后再分析细节,事半功倍。
如果可以的话,最好移植一个与教程配套开发板不一样的显示屏和触摸IC,这样对于本章的认识将更加全面。
显示屏的移植
GUIX需要的底层接口函数已经全部集成在gx_display_driver_stm32f4_24xrgb.c文件和gx_display_driver_stm32f4_565rgb.c里面。对于这两个文件,用户仅需学会使用里面的两个宏配置以及LTDC涉及到的引脚和时序配置函数,这个是需要用户自己去实现的,配置方法已经在本章节的7.7小节进行讲解。
另外还有一个显示屏背光调节函数LCD_SetBackLight的调用,其它都不用做任何修改。这三个地方都设置了,GUIX的显示屏移植就完成了。
触摸的移植
电容触摸的移植比较容易,因为电容触摸芯片可以自动触摸校准,所以仅需配置完触摸芯片后将触摸芯片返回的触摸坐标(电容触摸芯片返回的就是实际的坐标值),按下,松手和移动三种状态发送给GUIX即可。
电阻触摸的移植要稍麻烦些,由于电阻触摸板的线性度不是很好,如果不做触摸校准和滤波处理会有点击不准确和飞点问题。当前配套2点和4点触摸校准算法,大家可以根据需要选择,默认是用的2点触摸校准算法。其中触摸滤波方法是检测到触摸后先延迟30ms,消除抖动,然后采集10组坐标值做升序排列,去掉最大的几组坐标和最小的几组坐标,对中间的几组求平均作为最终的数值(电容触摸芯片返回的是ADC数值,不是实际坐标值)。然后将最终的数值代入通过触摸校准建立的线性公式来获得实际的坐标值,此时就可以将触摸坐标和触摸按下,松手和移动状态发送给GUIX。
7.2 移植前的准备工作以及移植GUIX的流程
移植前注意以下两个问题:
本章节的IDE开发环境务必是MDK5.30及其以上版本,镜像下载地址
准备一个简单的ThreadX工程,越简单越好,我们就在这个简单的工程上面移植即可:
配套模板名称:V6-2004_ThreadX Kernel Template
GUIX的移植通过以下8步完成,下面各个小节详细讲解每一步:
第1步:ThreadX内核模板框架设计
第2步:GUIX模板框架设计(重要)
第3步:下载GUIX库并添加到ThreadX内核工程模板
第4步:SDRAM驱动的实现
第5步:LTDC涉及到的引脚配置和时序配置
第6步:电阻屏和电容屏触摸驱动的实现
第7步:GUIX底层接口函数和配置
第8步:添加GUI应用进行测试。
7.3 第1步:了解ThreadX内核模板框架设计
移植GUIX前,我们优先了解下ThreadX内核模板程序的框图。
7.3.1 准备一个ThreadX内核工程模板
首先准备好一个简单的ThreadX工程模板,工程模板的制作在ThreadX内核教程里面有详细说明,这里的重点是教大家移植GUIX,对应的例子名称:V6-2004_ThreadX Kernel Template。准备好的工程模板如下图所示(特别注意,我们这个模板已经添加裸机LCD操作所需的文件)。
7.3.2 内核框架整体把控(重要)
为了帮助大家更好的理解ThreadX内核例子模板,专门制作了一个框图,可以让大家整体把控模板设计:
下面把几个关键点逐一为大家做个说明。
7.3.3 各种头文件汇总includes.h
这个文件主要实现工程中各种头文件的汇总,大家用到的都可以将其放到这个头文件里面。其它应用源文件有调用到的,直接调用这个头文件includes.h即可。
使用这个头文件主要是方便各种头文件的管理。
7.3.4 TheadX配置文件tx_user.h
此文件主要用于ThreadX内核的配置,内核相关的几个宏配置基本都已经整理到这个文件里面。
7.3.5 系统时钟节拍配置tx_initialize_low_level.s
这个汇编文件里面有个重要参数需要大家配置,即芯片主频和系统时钟节拍。
SYSTEM_CLOCK EQU 168000000
SYSTICK_CYCLES EQU ((SYSTEM_CLOCK / 1000) -1)
168000000是系统时钟主频,1000对应的就是系统时钟节拍,这里1000就表示1000Hz。
7.3.6 TheadX任务管理main.c
ThreadX所有任务基本都在main.c里面创建,方便统一管理。如果有GUIX,FileX等组件的任务需要运行,实际运行函数会在其它源文件里面,并将这个函数extern到main.C文件里面,放到相应的任务里面执行。
另外,任务优先级,任务栈大小,任务控制块等也都放到main.C文件里面,方便管理
7.3.7 TheadX启动任务
启动任务里面主要做了四个工作:
优先执行一次任务统计OSStatInit。
外设初始化bsp_Init。
任务创建AppTaskCreate和通信组件创建AppObjCreate。
需要周期性处理的程序bsp_ProPer1ms,对应裸机工程调用的SysTick_ISR。这个的实现非常重要,这样之前裸机里面使用的API,就可以直接在ThreadX里面直接调用。
7.3.8 HAL库时间基准stm32f4xx_hal_timbase_tim.c
ThreadX系统时钟节拍默认是用的滴答定时器,STM32的HAL库时间基准也是用的滴答定时器。对于这种情况,我们一般的情况下是使用其他的通用定时器替代,不过要额外的占用一点系统性能。简单的处理办法是重新实现下面两个函数即可,让HAL库和ThreadX都使用滴答定时器
7.3.9 ThreadX使能硬件浮点
这个是移植的坑王,大家移植后,可以测试下多任务的FPU计算是否有异常。比如两个任务运行相同的浮点运算和刷新速度,看看两个任务的输出是否同步变化,这个测试非常重要:
那么问题来了,正确的使能姿势是什么?务必保证C和汇编的预定义宏里面都使能。
C里面对应的使能:
汇编里面对应的使能:
7.4 第2步:了解GUIX模板框架设计
以往我们做教程都是先介绍如何移植,然后看最后的移植效果。这次我们反过来,先看移植完成的效果,然后移植。
7.4.1 GUIX工程模板
GUIX工程模板移植完成后,大体是下面这种效果:
7.4.2 GUIX框架整体把控(重要)
为了帮助大家更好的理解GUIX内核例子模板,专门制作了一个框图,可以让大家整体把控模板设计:
下面把几个关键点逐一为大家做个说明。
7.4.3 GUIX配置文件gx_user.h
此文件主要用于GUIX的配置,GUIX相关的宏定义配置非常多,当前先把这个文件预留出来,随着后面章节的进行,用到那些宏定义了再添加。
7.4.4 外设驱动初始化文件bsp.c
使用GUIX,主要涉及到SDRAM初始化,触摸初始化,LTDC初始化(放到了GUIX底层驱动接口文件里面了),背光开启和EEPROM初始化(用于存储电阻触摸屏校准参数)
7.4.5 外设驱动头文件汇总bsp.h
此文件主要用于添加了那些外设驱动文件后,使能相应头文件,特别工程GUIX工程里面添加的一批LCD驱动和触摸驱动文件,支持的头文件如下
7.4.6 LCD裸机驱动文件
STM32F429的LCD控制器LTDC控制有两个相关的驱动文件,即bsp_tft_429.c和bsp_tft_lcd.c。移植GUIX时,这两个文件基本用不上了,已经把这两个文件实现的LTDC配置全部集成到了GUIX的底层接口驱动文件里面,方便大家移植。
7.4.7 电阻和电容触摸驱动文件
电阻和电容触摸主要用的以下几个文件:
总触摸文件,用于识别各种触摸:bsp_ts_touch.c
电容触摸文件bsp_ts_ft5x06.c
电容触摸文件bsp_ts_gt811.c
电容触摸文件bsp_ts_gt911.c
电阻触摸文件bsp_ts_stmpe811
7.4.8 电阻触摸校准参数存储到EEPROM
EEPROM的驱动主要涉及到两个文件:
bsp_i2c_gpio.c
配置EEPROM用到的两个引脚。
bsp_i2c_eeprom_24xx.c
EEPROM的读写API。
而触摸校准参数的实现是在bsp_ts_touch.c文件末尾封装好的两个函数里面
7.4.9 GUIX底层驱动接口文件
当前制作了两个底层驱动接口文件:
gx_display_driver_stm32h7_565rgb.c 对应硬件RGB565接口。
gx_display_driver_stm32h7_24xrgb.c 对应硬件RGB888接口。
大家可以根据需要选择相应驱动。
7.4.10 GUIX源码文件
GUIX的源码文件非常多,一个文件一个API,有1200个左右,大家移植的时候最好都加上。
7.4.11 GUIX应用文件
几个应用文件的作用如下:
随着后面的章节的学习,逐渐就熟练了。
7.5 第3步:添加GUIX库所有相关文件到ThreadX内核工程模板
了解了ThreadX内核框架和GUIX框架后,介绍下如何将GUIX移植到ThreadX内核工程模板里面。我们这里一步到位,直接把所有相关的文件都加上,然后再介绍如何修改,方便大家移植到自己的板子上。
7.5.1 第3.1步,下载GUIX源码包
按照第2章2.3.1小节讲解的方法下载GUIX软件包guix-6.0.1_rel(如果软件包升级了,数字6.0.1略有不同),下面是GUIX软件包内容:
主要用到两个文件夹:
common文件夹里面是源码文件。
ports文件夹里面是移植文件。
7.5.2 第3.2步,创建GUIX文件夹到工程模板
在工程模板创建GUIX文件夹
GUIX的M4内核port文件夹里面只有一个GNU(对应路径portscortex_m4),为了方便我们管理,再创建IAR,AC5和AC6三个文件夹,文件夹里面的内容和GNU里面的一样,并且再添加一个src文件夹,整体效果就是下面这样:
新建的src文件夹是用来存放GUIX底层驱动接口文件用。
7.5.3 第3.3步,添加底层驱动接口文件
添加驱动接口文件到第3.2步创建的ac5-》src和ac5-inc文件夹里面(h文件添加到inc文件夹,c文件放到src文件夹)
为了移植方便,大家直接复制本周教程配套例子在此文件夹下的文件即可。
7.5.4 第3.4步,添加Port文件和源码文件到工程
将源码文件和ports文件添加到MDK的工程项目中,添加后的效果如下:
推荐使用下面的方法添加,否则MDK会非常卡:
7.5.5 第3.5步,添加配置文件gx_user.h
在User文件夹下添加文件gx_user.h,直接从本章节教程配套例子的User文件夹复制即可。此文件主要用于GUIX配置。
为了方便管理,我们这里将路径GUIXportscortex_m4ac5inc里面的gx_port.h文件也添加进来了。
7.5.6 第3.5步,添加GUIX应用文件
在User文件夹添加文件夹GUIX,直接从本章节教程配套例子的User文件夹复制即可,此文件夹主要是GUIX的应用部分,内容如下
7.5.7 第3.6步,添加BSP驱动文件
需要添加的BSP驱动文件如下:
除了SDRAM,LTDC,EEPROM和触摸两个的文件以外,还要添加bsp_tim_pwm.c,这个是用于设置PWM背光用的。
另外注意一点,bsp_tft_lcd.c文件还关联了一些字库文件,大家最好也将其添加到工程里面。这些字库文件位于本章配套例子的User文件夹下,大家直接复制到自己工程的工程里面添加即可,添加后效果如下:
7.5.8 第3.7步,添加HAL库文件
相关BSP驱动关联到的HAL库文件都添加了进来,简单省事些,大家也可以把HAL库所有文件都添加进来:
7.5.9 第3.8步,添加预定义宏
C/C++文件中添加的预定义宏如下:
USE_HAL_DRIVER
STM32F429xx
USE_FULL_LL_DRIVER
TX_ENABLE_FPU_SUPPORT 用于支持硬件FPU
TX_ENABLE_STACK_CHECKING 用于栈检测
TX_INCLUDE_USER_DEFINE_FILE 用于包含tx_user.h
GX_INCLUDE_USER_DEFINE_FILE 用于包含gx_user.h
ASM汇编文件里面添加的宏定义:
TX_ENABLE_FPU_SUPPORT
7.5.10 第3.9步,添加头文件路径
需要添加的路径如下:
至此,我们需要的GUIX文件都已经添加完毕。下面为大家介绍如何修改用于自己的板子。
7.6 第4步:SDRAM驱动实现(用于显存,动态内存和画布)
一定要保证SDRAM大批量读写数据时是正常的,SDRAM的测试可以自己专门做一个工程测试下。对于SDRAM的驱动实现,可以学习我们写的BSP驱动教程第39章
不管你使用的是镁光的,海力士的,三星的,ISSI的或者华邦的,基本实现方法都是一样的。教程配套的板子使用的是镁光的32位带宽的SDRAM,如果想最大限度发挥STM32F429驱动SDRAM的性能,强烈建议使用32位带宽的SDRAM,或者两个16位SDRAM组成32位带宽的SDRAM也是可以的。那SDRAM主要起到什么作用呢?作用有二:
用作显示屏的显存
STM32F429的LTDC外接RGB接口屏是没有显存的,所以需要SDRAM用作显存。如果用户选择STM32F429 LTDC的颜色格式是32位色ARGB8888,那么所需要显存大小(单位字节)是:显示屏宽 * 显示屏高 * (32/8), 其中32/8是表示这种颜色格式的一个像素点需要4个字节来表示。又比如配置颜色格式是16位色的RGB565,那么需要的显存大小是:显示屏宽 * 显示屏高 * (16/8),其中16/8是表示这种颜色格式的一个像素点需要2个字节来表示。其它的颜色格式,依此类推。
用作GUIX动态内存和canvas幕布
GUIX要做的炫酷,是比较消耗动态内存的,所以用户可以将SDRAM除了用于显存以外的所有内存全部用作GUIX动态内存和canvas幕布。
如果SDRAM的驱动测试已经没有问题了,就可以将其添加到工程里面了,开发板使用的SDRAM驱动文件是bsp_fmc_sdram.c。
添加到工程里面后要分配SDRAM的使用,教程配套开发板使用的是16MB,32位带宽的SDRAM。
7.7 第5步:LTDC涉及到的引脚配置和时序配置
7.7.1 LTDC时序配置
用户仅需配置LTDC涉及到的引脚和时序即可,配置函数封装到下面两个接口文件的末尾。
gx_display_driver_stm32f4_565rgb.c 对应硬件RGB565接口。
gx_display_driver_stm32f4_24xrgb.c 对应硬件RGB888接口。
另外,由于开发板配套了4.3寸,5寸和7寸屏显示屏,所以要对这几种尺寸的显示屏做自适应,每个屏的时序配置都是不一样的,具体实现在gx_display_driver_stm32f4_565rgb.c和gx_display_driver_stm32f4_24xrgb.c接口文件末尾的,即函数LCD_LL_Init。大家在给自己的显示屏移植时主要修改这个函数即可,引脚配置需要在这个函数里面实现。下面我们再结合函数LCD_LL_Init的实现,讲解下配置时要注意的一些问题,具体代码如下
第89到123行,主要是GPIO配置,注意DMA2D时钟和LTDC时钟别忘使能。
第133到263行,这部分程序的实现在本教程第4章的4.4.4小节里面有详细说明。
第133行,六种面板的识别是在bsp_ts_touch.c文件中实现的。大家自己配置时用不到这个,仅需提供一组时序参数和输出时钟即可,除非项目中需要切换不同显示屏。
第246到247行,全局变量g_LcdWidth和g_LcdHeight在文件bsp_tft_lcd.c文件定义。如果大家自己移植时用不到文件bsp_tft_lcd.c的话,需要自行定义这两个全局变量(另外,此文件里面的背光设置函数也要自行实现),因为这两个变量要被文件gx_display_driver_stm32f4_565rgb.c和gx_display_driver_stm32f4_24xrgb.c所调用
第266到268行,STM32F429的图层是由背景层,图层1和图层2组成,这里配置的是背景层的颜色值,分别配置了R,G,B三原色的数值,范围都是0-255。
第274到300行,主要是配置图层。
第280行,如果使用RGG565颜色格式要配置为LTDC_PIXEL_FORMAT_RGB565。
如果使用ARGB8888颜色格式要配置为LTDC_PIXEL_FORMAT_ARGB8888。
7.7.2 如何验证LTDC的时序配置是否正确
下面说一个最重要的问题,配置好时序了,怎么检查自己的配置是否成功了?用户仅需在函数LCD_LL_Init里面的如下代码后面加上两个函数:
/* 配置LTDC */ if (HAL_LTDC_Init(&hltdc_F) != HAL_OK){ /* 初始化错误 */ Error_Handler(__FILE__, __LINE__);}/* 下面是添加的 */LCD_SetBackLight(BRIGHT_DEFAULT);while(1); 加上这两行代码后,再将背景层设置为一个合适的颜色,建议设置成红色,方便观察:
/* 配置背景层颜色 */hltdc_F.Init.Backcolor.Blue = 0;hltdc_F.Init.Backcolor.Green = 0;hltdc_F.Init.Backcolor.Red = 0xFF; 如果背景层可以正常显示红色,说明引脚和时序配置都是没有问题的。如果不成功要从以下几个方面着手检查:
首先要清楚一点,当前的配置是否成功与SDRAM没有任何关系,因为背景层还用不到SDRAM,图层1和图层2才需要SDRAM做显存使用。
从硬件着手检查,保证STM32F429芯片焊接没问题,TFT接口一定要牢固,防止接触不良,特别是使用FPC软排线的时候,测试阶段,软排线越短越好。有时候也可能是显示屏有问题,最好可以备两个显示屏测试。
从软件配置着手检查,查看LTDC涉及到的所有引脚是否配置,引脚时钟是否使能。有时候无法显示也有可能是板子硬件设计不规范导致干扰较大造成的,此时,可以降低LTDC所涉及到GPIO的速度等级。
如果显示了,但是显示的位置不正确,可以重新调整时序参数即可。
7.8 第6步:电阻屏和电容屏触摸驱动的实现
本小节的实现基于本教程的第5章,当前驱动对电阻触摸芯片STMPE811和电容触摸芯片FT5X06、GT911和GT811的显示屏都进行了支持。
实现比较简单,因为GUIX的触摸分按下,松手和移动三个事件,正好这几款触摸芯片的驱动也是分这三个事件,所以仅需修改下函数TOUCH_PutKey,所有显示屏触摸就都可以完美融合了。
7.8.1 添加GUIX的按下,松手和移动三个事件
文件bsp_ts_touch.c里的函数TOUCH_PutKey修改如下
特别注意0xC0000000,这个不是随便写的一个值,要与本章7.8.1小节设置STM32_SCREEN_HANDLE数值一致。
7.8.2 周期性调用触摸扫描函数
电阻触摸和电容触摸的扫描函数是TOUCH_Scan和TOUCH_CapScan,为了实现使用了ThreadX和裸机时的一样的调用方式,专门在启动任务里面周期性的调用函数bsp_ProPer1ms(SysTick_ISR),而SysTick_ISR里面调用了bsp_RunPer1ms,然后bsp_RunPer1ms里面调用扫描函数,即如下的调用关系:
7.8.3 如何将触摸驱动移植到自己的板子
通过前面的讲解,移植触摸驱动到自己的板子上,最简单的办法是将开发板与触摸相关的文件全部移植过来,然后在这些文件的基础上进行修改。下面分两种情况进行说明:
电容屏触摸的移植比较简单,如果用户用的触摸IC跟开发板一样,直接拿来用即可,如果不一样,需要先将触摸IC的驱动实现,然后按照开发板提供的GT911,GT811或者FT5X06的触摸扫描函数,照葫芦画瓢实现一个即可。
电阻屏的移植稍麻烦些,如果用户用的触摸IC跟开发板一样,直接拿来用即可,如果不一样,需要先将触摸IC的驱动实现,然后仿照bsp_ts_stmpe811.c文件提供触摸按下状态函数,X轴,Y轴的ADC数值读取函数和清除触摸中断标志函数。最后用重新实现的这几个函数替换bsp_ts_touch.c文件中的原函数即可。另外要注意一点,这种方式实现后,虽然触摸校准依然可以使用,但是开发板的触摸校准参数是保存在EEPROM中的,用户可以根据自己的实际情况选择存储介质。另外,触摸参数的保存和读取在bsp_ts_touch.c文件末尾的函数TOUCH_SaveParam和TOUCH_LoadParam实现。
如果大家不想用开发板实现的方案,想自己重新实现一个,也是没问题的,注意跟GUIX关联的方式。
7.9 第7步:GUIX底层接口函数和配置
GUI的底层接口函数和配置的实现在我们第1步中添加的底层驱动接口文件中:
gx_display_driver_stm32f4_565rgb.c 对应硬件RGB565接口。
gx_display_driver_stm32f4_24xrgb.c 对应硬件RGB888接口。
这两个文件的实现套路是一样的,我们这里以gx_display_driver_stm32f4_565rgb文件为例进行说明。
7.9.1 DMA2D使能宏定义GX_CHROMEART_ENABLE
文件开头的宏定义GX_CHROMEART_ENABLE用于使能DMA2D加速,测试阶段可以将其关闭掉,关闭方法就是注释掉宏定义#define GX_CHROMEART_ENABLE即可。
7.9.2 显存地址宏定义FrameBufer
LCD的显存地址设置是通过宏定义配置:
#define FrameBufer
SDRAM_LCD_BUF1
其中SDRAM_LCD_BUF1的定义是在bsp_fmc_sdram.h,即
7.9.3 接口函数stm32f4_graphics_driver_setup_565rgb
这个函数是GUIX连接底层最直接的函数,也是配置的关键。实现代码如下
第11行,GPIO和LTDC初始化。
第13行,为GUIX和LTDC建立关联。特别注意参数STM32_SCREEN_HANDLE,宏定义如下:
#define STM32_SCREEN_HANDLE 0xC0000000
本章7.8.1小节里面的用到的0xC0000000就是从这里来的,务必保证匹配。
第16到22行,对一些底层函数做重定向,从而实现DMA2D加速。
7.9.4 通过DMA2D加速的几个函数
通过DMA2D加速的几个函数如下(这几个函数,大家做移植的话,仅需注意变量g_LcdWidth和g_LcdHeight正确赋值了):
gx_chromeart_horizontal_line_draw
gx_chromeart_vertical_line_draw
gx_chromeart_canvas_copy
gx_chromeart_pixelmap_draw
gx_chromeart_pixelmap_blend
gx_chromeart_glyph_8bit_draw
这里我们以函数gx_chromeart_horizontal_line_draw为例进行说明
这里主要实现了一个水平线的DMA2D加速,功能比较好理解。DMA2D的详细介绍在本教程的第6章进行了非常详细的说明,大家如下想了解每个配置语句的功能,可以深入学习第6章。
7.9.5 更新画布canvas内容到LCD显存
当前GUIX的显示是采用的画布机制,即GUIX先在画布上把界面绘制好,然后将画布中需要更新的区域绘制到LCD。这部分代码是移植成功与否的关键(如果大家是用于F429平台,下面的代码无需任何修改可以直接使用):
7.10 第8步:添加GUIX应用进行测试
介绍完了前面几步,剩下就是添加应用代码了。为了方便起见,大家直接使用本章教程配套例子里面整理好的即可
7.10.1 添加应用文件MainTask.C和MainTask.h
MainTask.h是GUIX相关的头文件和函数声明,MainTask.c文件里面主要是GUIX的初始化
第20行,为了避免上电时瞬间的撕裂感,这里先关闭LCD背光,等首界面绘制完毕后再打开。
第26到30行,触摸校准函数默认是注释掉的,电阻屏需要校准,电容屏无需校准。如果用户需要校准电阻屏的话,执行此函数即可,会将触摸校准参数保存到EEPROM里面,以后系统上电会自动从EEPROM里面加载。
第36到第49行,主要是GUIX的初始化,初始化完毕后打开背光。
7.10.2 添加动态内存配置和Canvas画布配置文件
动态内存和Canvas画布配置都放在了文件App_SysFunctions.c文件里面实现。
第6到第9行,设置动态内存地址和画布的地址。
教程配套的STM32F429板子有16MB的SDRAM空间。
前4MB空间用于显存,地址0xC0000000。
中间4MB空间用于Canvas画布,地址0xC0000000 + 1024*1024*4 = 0xC0400000。
最后8MB空间用动态内存,地址0xC0000000 + 1024*1024*8 = 0xC0800000。
第17行,这个是在GUIX Studio生成的xxxxx_resources.c文件里面。注意要匹配。
第25到39行,动态内存的申请和释放函数。然后通过gx_system_memory_allocator_set进行注册。
第61到78行,实现了个简单的不同显示屏自适应。
第80行,设置Canvas画布地址。
7.10.3 添加GUIX Studio生成的文件
使用GUIX Studio生成了4个文件:
guiapp_resources.h
guiapp_resources.c
guiapp_specifications.h
guiapp_specifications.c
后面章节再为大家介绍GUIX Studio生成的这几个文件。作为移植,大家进行将其加到移植工程里面验证是否正常即可。
7.10.4 BSP初始化并创建GUIX任务
BSP初始化主要涉及到SDRAM初始化,触摸初始化,LTDC初始化(放到了GUIX底层驱动接口文件里面了),背光开启和EEPROM初始化(用于存储电阻触摸屏校准参数)
7.10.5 自动创建的GUIX系统任务。
初始化了GUIX后,会自动创建一个GUIX任务,对于这点,大家移植的使用要特别注意。此任务的优先级和任务堆栈大小是在gx_port.h文件里面定义的。
7.11 显示屏闪烁问题解决方法
如果大家调试状态下或者刚下载GUIX的程序到STM32H7/STM32F429里面时,出现屏幕会闪烁,或者说抖动,这个是正常现象。详见此贴的说明:
如果显示屏长时间处于抖动状态,说明LTDC的时钟配置高了或者低了(高的概率居多),可以将LTDC时钟降低一半或者提高一倍进行测试。配置方法看本教程第4章的4.4.3小节。
7.12 避免显示屏上电瞬间高亮和撕裂感
大家使用显示屏的时候,这两个问题很容易遇到,这里为大家提供个解决办法,提升用户体验。
7.12.1 上电瞬间高亮解决办法
这个问题并不是软件配置造成的,通过条件PWM背光也是无法解决的。解决办法是板子上后,先不要开启PWM,延迟200ms后再打开LCD的背光即可,注意时间不可以太短,太短没效果,大家可以根据实际情况做条件。本章配套程序是放在bsp.c文件的函数bsp_Init里面做了处理。
7.12.2 上电瞬间撕裂感解决办法
有时候界面设计比较复杂时,开机后不能保证所有的控件同时加载出来,界面会有种撕裂的感觉,这个时候有个比较好的解决思路,GUIX初始化配置前关闭背光,初始化完毕并且首界面绘制完毕后再打开背光,用户体验就会好很多。本章配套程序是放在MainTask.c文件的函数MainTask里面做了处理。
7.13 实验例程
(注,如果是电阻屏,需要做触摸校准,校准方法看本教程附件章节A)
本章节配套了如下几个例子供大家移植参考:
V6-2004_Threadx Kernel Template
ThreadX内核模板,用于大家移植GUIX的参考Demo,含有GCC,IAR,MDK AC5和AC6四个版本工程。
V6-2005_GUIX Template(RGB565)
GUIX模板例子,采用的硬件RGB565接口,含有GCC,IAR,MDK AC5和AC6四个版本工程。
V6-2006_GUIX Template(ARGB8888)
GUIX模板例子,采用的硬件ARGB8888接口,含有GCC,IAR,MDK AC5和AC6四个版本工程。
V6-2007_GUIX Studio Template
GUIX Studio工程模板,设计界面后,生成的文件可直接添加到MDK,IAR和GCC软件平台使用。
显示效果如下,800*480分辨率:
IAR,MDK AC5和AC6工程可以串口打印任务执行情况:按开发板的按键K1可以打印,波特率 115200,数据位 8,奇偶校验位无,停止位 1:
Embedded Studio(GCC)平台的串口打印是通过其调试组件SEGGER RTT做的串口打印,速度也非常快,打印效果如下:
展示里面有乱码是因为Embedded Studio不支持中文。
7.14 总结
本章节为大家讲解的内容涉及到的知识较多,信息量较大,部分知识点没有弄明白是没有关系的,但是一定要掌握ThreadX内核和ThreadX GUIX工程的框架设计,掌握后再分析细节,事半功倍。
如果可以的话,最好移植一个与教程配套开发板不一样的显示屏和触摸IC,这样对于本章的认识将更加全面。
举报