STM32CubeIDE TFT-LCD移植STemWin,FlexColor(间接访问)两种实现方式

本文主要是介绍STM32CubeIDE TFT-LCD移植STemWin,FlexColor(间接访问)两种实现方式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

随言:

STemWin、emWin 与ucGUI其实都师出同门,都是是Segger 公司之手。

STemWin 是Segger 公司为ST公司定制的图形软件库;uC/GUI 是Segger 公司为Micrium 公司定制的图形软件库;

与其说是花钱定制的版本,其实都是正统emWin的别名版本,微改动。

但是在STM32芯片上面使用STemWin是免费的。当然ST公司也不会给其他芯片使用STemWin的机会,

故在库函数里使用了ST芯片内部CRC32寄存器进行校验是否为ST的芯片,若是则工作正常,否则反之。

像STemWin这个平台通用GUI库来说,就是按要求填充底层接口,然后程序调用库上层API接口。

初接触STemWin强力推荐官方手册《AN4323 应用笔记 STemWin 库入门指南》!!!

去官网搜索:AN4323 即可。

1.STemWin:

先写好一份TFTLCD显示和支持触摸的代码(以前文章写过)。

然后打开Cube库文件安装路径,找到与硬件对应的库文件,比如我用的是STM32F407对应F4系列。

C:\Users\admin\STM32Cube\Repository\STM32Cube_FW_F4_V1.25.1\Middlewares\ST\STemWin

其实各个文件夹下放的文件,只看文件夹名字大概都猜到了大概对应文件功能。

1.1Config:

包含库和LCD驱动程序的配置文件

首先显示驱动方式有两种,一种是画点,另一种是操作显存。画点是万能的,适用于所有屏幕。操作显存适用于RGB屏幕。

GUIConf.c:主要作用是分配STemWin内部缓存。

LCDConf_Lin_Template.c: 屏幕显示驱动底层填充接口,以显存方式。

LCDConf_FlexColor_Template.c:屏幕显示驱动底层填充接口,以画点方式

                                       画点有两种做法:使用自定义画点和STemWin自带画点函数(依据MCU屏幕IC)。

GUIDRV_Template.c: 里面是自定义画点填充底层函数,通过画点读点方式,适用于所有的屏幕。

1.2 Documentation:

包含emWin“用户和参考指南”英文版STemWin544.pdf用户手册,其实就是emWin544手册。

 但是网上有emWIN5.12中文手册,虽不是最新,但是够用,比看英文手册舒服。

1.3 inc:

存放STemWin库组件的头文件。

1.4 Lib

存放在STemWin的静态库文件,不开源。

命名格式为STemWin_CM x _ YY_wc_ot_zzzz .a,其中

         x:CMx核心类别(CM0,CM3,CM4或CM7)
         YY:操作系统支持
         wc:  Wchar_t类型大小(wc16或wc32。根据编译器选择,先随便选一个报错再换)
         ot: 高速优化生成的二进制文件
         zzzz:支持ARGB

上面内容来源于文件夹中的Release_Notes.html。

1.5 OS

根据用户程序是否带RTOS选择哪个文件。带了RTOS就选名字带OS的。

其实带着RTOS选择使用GUI_X.c也没关系。

2.环境

我用的是STM32CubeIDE开发,硬件是STM32F407 + TFT LCD,分辨率800 *480.

由于我使用的是TFT MCU屏幕,故只实现FlexColor方式中的两种画点做法

使能STM32F4的CRC寄存器。

2.1 STemWin初始化流程图

3.FlexColor自定义画点

3.1 选择STemWin源文件

在写好TFTLCD的工程中把上面cube库中的STemWin的Config、inc、Lib和OS复制到新建文件夹,并命名为STemWin。

1、打开工程中的STemWin文件夹中Config,把LCDConf_Lin_Template.c、LCDConf_Lin_Template.h和SIMConf.c删除,LCDConf_FlexColor_Template.h重命名为LCDConf.h

2、打开工程中的STemWin文件夹中Lib,我选择使用STemWin_CM4_wc32.a,其他的文件删除。若出错就选STemWin_CM4_wc16.a,和编译器有关。

3、打开工程中的STemWin文件夹中OS,我没有带系统,删除GUI_X_OS.c。

3.2 设置STM32CubeIDE工程

打开STM32CubeIDE工程,或者刷新一下。出现了刚才新增的文件。

1、右键工程,比如我这是F407 TFT-LCD STemWin。选择属性。

2、添加头文件。 

3、添加静态库。需要注意的是添加静态库名字前面需要添加一个: 

最后编译一下,就会通过。如果不通过检测一下步骤。我是边写边做。

3.3 编程

1、先打开GUIConfig.c,修改STemWin内部缓存大小。我先设置50Kb大小作为缓存。

#define GUI_NUMBYTES  (50*1024)

2、打开GUIDRV_Template.c修改底层填充函数。

分别是:画点函数_SetPixelIndex()、读点函数_GetPixelIndex()和 填充色块函数_FillRect()。

static void _SetPixelIndex(GUI_DEVICE * pDevice, int x, int y, int PixelIndex) {LCD_Fast_DrawPoint(x, y, PixelIndex);
}static unsigned int _GetPixelIndex(GUI_DEVICE * pDevice, int x, int y) {return LCD_ReadPoint(x,y);
}static void _FillRect(GUI_DEVICE * pDevice, int x0, int y0, int x1, int y1) {LCD_PIXELINDEX PixelIndex;PixelIndex = LCD__GetColorIndex();LCD_Fill(x0, y0, x1, y1, PixelIndex);
}

3、打开LCDConf_FlexColor_Template.c

先修改屏幕分辨率,我的屏幕分辨率是480 x 800.

#define XSIZE_PHYS  480 // To be adapted to x-screen size
#define YSIZE_PHYS  800 // To be adapted to y-screen size

修改LCD显示驱动配置函数LCD_X_Config()

GUIDRV_Template_API是会调用上面配置的LCD驱动,画点。

GUICC_M565是LCD调色板。颜色是RRRRRGGGGGGBBBBB,与GUICC_565颜色顺序相反。

void LCD_X_Config(void) {//// Set display driver and color conversion//GUI_DEVICE_CreateAndLink(&GUIDRV_Template_API , GUICC_M565, 0, 0);//// Display driver configuration, required for Lin-driver//LCD_SetSizeEx (0, XSIZE_PHYS , YSIZE_PHYS);LCD_SetVSizeEx(0, VXSIZE_PHYS, VYSIZE_PHYS);
}

LCD_X_DisplayDriver()显示驱动程序出于多种目的调用此函数。添加LCD初始化函数LCD_Init()。

int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData) {int r;(void) LayerIndex;(void) pData;switch (Cmd) {case LCD_X_INITCONTROLLER: {LCD_Init();return 0;}default:r = -1;}return r;
}

还有打开stm32f4xx_it.c,添加GUI内部延时计数,修改如下:

#include "GUI.h"extern volatile GUI_TIMER_TIME OS_TimeMS;void SysTick_Handler(void)
{HAL_IncTick();OS_TimeMS++;
}

最后修改main函数:

GUI_Init(); 初始化STemWin。

WM_SetCreateFlags(WM_CF_MEMDEV);

把屏幕显示内容暂时缓存,再复制到显示屏。主要作用是避免闪变效应,提升速度。

#include "GUI.h"
#include "WM.h"int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_FSMC_Init();MX_USART1_UART_Init();MX_CRC_Init();/* Init the STemWin GUI Library */GUI_Init();/* Activate the use of memory device feature */WM_SetCreateFlags(WM_CF_MEMDEV);GUI_Clear();GUI_SetFont(&GUI_Font20_1);GUI_DispStringAt("Hello world!", (LCD_GetXSize()-100)/2, (LCD_GetYSize()-20)/2);while (1){}
}

3.4 效果

4.FlexColor自带IC驱动

刚好我的MCU TFT LCD屏幕的IC不在STemWin自带的IC里面,下面只能把过程写出来,抱歉了~。

有机会如果能借到一块手册中有的IC的话我再补上吧,哎~。

首先先确保所使用的MCU LCD IC在STemWin 544版本的手册中。

4.1 准备

把上面的程序复制一份。config文件夹重新去cube库里面复制如下文件

4.2 编程

1、现将堆栈空间改大。防止运行时堆栈不足导致错误。

2、打开GUIConf.c,修改缓存大小。根据实况自行修改。

#define GUI_NUMBYTES  (100* 1024)void GUI_X_Config(void) {static U32 aMemory[GUI_NUMBYTES / 4];GUI_ALLOC_AssignMemory(aMemory, GUI_NUMBYTES);GUI_SetDefaultFont(GUI_FONT_6X8);
}

3、打开LCDConf_FlexColor_Template.c

#define XSIZE_PHYS  480 // To be adapted to x-screen size
#define YSIZE_PHYS  800 // To be adapted to y-screen size

4、修改LCD显示驱动配置函数LCD_X_Config()

GUIDRV_Template_API是会调用上面配置的LCD驱动,画点。

void LCD_X_Config(void) {GUI_DEVICE * pDevice;CONFIG_FLEXCOLOR Config = {0};GUI_PORT_API PortAPI = {0};pDevice = GUI_DEVICE_CreateAndLink(GUIDRV_FLEXCOLOR, GUICC_M565, 0, 0);LCD_SetSizeEx (0, XSIZE_PHYS , YSIZE_PHYS);LCD_SetVSizeEx(0, VXSIZE_PHYS, VYSIZE_PHYS);Config.Orientation = GUI_SWAP_XY | GUI_MIRROR_Y;GUIDRV_FlexColor_Config(pDevice, &Config);PortAPI.pfWrite16_A0  = LcdWriteReg;PortAPI.pfWrite16_A1  = LcdWriteData;PortAPI.pfWriteM16_A1 = LcdWriteDataMultiple;PortAPI.pfReadM16_A1  = LcdReadDataMultiple;GUIDRV_FlexColor_SetFunc(pDevice, &PortAPI, GUIDRV_FLEXCOLOR_F66708, GUIDRV_FLEXCOLOR_M16C0B16);
}

主要注意的是这个函数GUIDRV_FlexColor_SetFunc()的参数.

GUIDRV_FLEXCOLOR_F66708:表示对应手册上自己使用的LCD MCU一致。如下图。

GUIDRV_FLEXCOLOR_M16C0B16:表示16位总线无缓存。

5、填充下面四个函数

LcdWriteReg()设置寄存器地址函数。这个函数一般设置x、y、写RAM和读RAM 寄存器地址。

如果花屏了,百分98%是这里设置问题,打印数据排查。

LcdWriteData()写数据函数。

LcdWriteDataMultiple()连续写数据函数。

LcdReadDataMultiple()连续读数据函数。

static void LcdWriteReg(U16 Data) {// ... TBD by userLCD_WR_REG(Data);
}static void LcdWriteData(U16 Data) {// ... TBD by userLCD_WR_DATA(Data);
}static void LcdWriteDataMultiple(U16 * pData, int NumItems) {while (NumItems--) {// ... TBD by userLCD_WR_DATA(*pData);pData++;}
}static void LcdReadDataMultiple(U16 * pData, int NumItems) {while (NumItems--) {// ... TBD by user}
}

LCD_X_DisplayDriver()显示驱动程序出于多种目的调用此函数。添加LCD初始化函数LCD_Init()。

int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData) {int r;(void) LayerIndex;(void) pData;switch (Cmd) {case LCD_X_INITCONTROLLER: {LCD_Init();return 0;}default:r = -1;}return r;
}

还有打开stm32f4xx_it.c,添加GUI内部延时计数,修改如下:

#include "GUI.h"extern volatile GUI_TIMER_TIME OS_TimeMS;void SysTick_Handler(void)
{HAL_IncTick();OS_TimeMS++;
}

main函数就不写。

5. STemWin_SampleDemo

TFT STemWin_哔哩哔哩_bilibili

TFT STemWin

6. 问题记录

6.1 关于STemWin内部缓存大小

关于STemWin内部缓存大小分配问题,主要取决程序使用了内部什么功能而定。

官方手册《AN4323 应用笔记 STemWin 库入门指南》提及。

6.2 关于动画部分背景黑屏

如果出现下面两种鼠标指针移动过程中背景黑色和动画移动过程黑屏。

那就是你的读点函数_GetPixelIndex()出现问题了,读到的值不正确。

6.3 使用FlexColor自带驱动出现花屏

如果花屏了,首先先确定函数GUIDRV_FlexColor_SetFunc()的参数.设置是否和硬件IC一致。

LcdWriteReg()设置寄存器地址函数。

这个函数一般设置x、y、写RAM和读RAM 寄存器地址。

如果花屏了,百分98%是这里设置问题,打印数据排查。

LcdWriteData()写数据函数。也要打印设置寄存器的数据。

拿到对应的数据后,与厂商给的驱动设置x、y、写RAM和读RAM代码进行对比。

  全篇完。

本人是一个嵌入式未入门小白,博客仅仅代表我个人主观见解,记录成长笔记。
笔记是以最简单的方式,只展示最核心的原理。
若有与 大神大大 见解有歧义,我绝对坚信 大神大大 见解是对的,我的是错的。
若无积分等无法下载源码,可加入QQ群657407920下载交流经验。感谢~!

 

 

这篇关于STM32CubeIDE TFT-LCD移植STemWin,FlexColor(间接访问)两种实现方式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/697374

相关文章

Linux线程之线程的创建、属性、回收、退出、取消方式

《Linux线程之线程的创建、属性、回收、退出、取消方式》文章总结了线程管理核心知识:线程号唯一、创建方式、属性设置(如分离状态与栈大小)、回收机制(join/detach)、退出方法(返回/pthr... 目录1. 线程号2. 线程的创建3. 线程属性4. 线程的回收5. 线程的退出6. 线程的取消7.

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

Linux下删除乱码文件和目录的实现方式

《Linux下删除乱码文件和目录的实现方式》:本文主要介绍Linux下删除乱码文件和目录的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux下删除乱码文件和目录方法1方法2总结Linux下删除乱码文件和目录方法1使用ls -i命令找到文件或目录

SpringBoot+EasyExcel实现自定义复杂样式导入导出

《SpringBoot+EasyExcel实现自定义复杂样式导入导出》这篇文章主要为大家详细介绍了SpringBoot如何结果EasyExcel实现自定义复杂样式导入导出功能,文中的示例代码讲解详细,... 目录安装处理自定义导出复杂场景1、列不固定,动态列2、动态下拉3、自定义锁定行/列,添加密码4、合并

mybatis执行insert返回id实现详解

《mybatis执行insert返回id实现详解》MyBatis插入操作默认返回受影响行数,需通过useGeneratedKeys+keyProperty或selectKey获取主键ID,确保主键为自... 目录 两种方式获取自增 ID:1. ​​useGeneratedKeys+keyProperty(推

Spring Boot集成Druid实现数据源管理与监控的详细步骤

《SpringBoot集成Druid实现数据源管理与监控的详细步骤》本文介绍如何在SpringBoot项目中集成Druid数据库连接池,包括环境搭建、Maven依赖配置、SpringBoot配置文件... 目录1. 引言1.1 环境准备1.2 Druid介绍2. 配置Druid连接池3. 查看Druid监控

Linux在线解压jar包的实现方式

《Linux在线解压jar包的实现方式》:本文主要介绍Linux在线解压jar包的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux在线解压jar包解压 jar包的步骤总结Linux在线解压jar包在 Centos 中解压 jar 包可以使用 u

Jenkins分布式集群配置方式

《Jenkins分布式集群配置方式》:本文主要介绍Jenkins分布式集群配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1.安装jenkins2.配置集群总结Jenkins是一个开源项目,它提供了一个容易使用的持续集成系统,并且提供了大量的plugin满

c++ 类成员变量默认初始值的实现

《c++类成员变量默认初始值的实现》本文主要介绍了c++类成员变量默认初始值,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录C++类成员变量初始化c++类的变量的初始化在C++中,如果使用类成员变量时未给定其初始值,那么它将被

Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式

《Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式》本文详细介绍如何使用Java通过JDBC连接MySQL数据库,包括下载驱动、配置Eclipse环境、检测数据库连接等关键步骤,... 目录一、下载驱动包二、放jar包三、检测数据库连接JavaJava 如何使用 JDBC 连接 mys