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

相关文章

Python中pywin32 常用窗口操作的实现

《Python中pywin32常用窗口操作的实现》本文主要介绍了Python中pywin32常用窗口操作的实现,pywin32主要的作用是供Python开发者快速调用WindowsAPI的一个... 目录获取窗口句柄获取最前端窗口句柄获取指定坐标处的窗口根据窗口的完整标题匹配获取句柄根据窗口的类别匹配获取句

Linux之systemV共享内存方式

《Linux之systemV共享内存方式》:本文主要介绍Linux之systemV共享内存方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、工作原理二、系统调用接口1、申请共享内存(一)key的获取(二)共享内存的申请2、将共享内存段连接到进程地址空间3、将

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

Python位移操作和位运算的实现示例

《Python位移操作和位运算的实现示例》本文主要介绍了Python位移操作和位运算的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 位移操作1.1 左移操作 (<<)1.2 右移操作 (>>)注意事项:2. 位运算2.1

如何在 Spring Boot 中实现 FreeMarker 模板

《如何在SpringBoot中实现FreeMarker模板》FreeMarker是一种功能强大、轻量级的模板引擎,用于在Java应用中生成动态文本输出(如HTML、XML、邮件内容等),本文... 目录什么是 FreeMarker 模板?在 Spring Boot 中实现 FreeMarker 模板1. 环

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义

SpringMVC 通过ajax 前后端数据交互的实现方法

《SpringMVC通过ajax前后端数据交互的实现方法》:本文主要介绍SpringMVC通过ajax前后端数据交互的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价... 在前端的开发过程中,经常在html页面通过AJAX进行前后端数据的交互,SpringMVC的controll

Spring Security自定义身份认证的实现方法

《SpringSecurity自定义身份认证的实现方法》:本文主要介绍SpringSecurity自定义身份认证的实现方法,下面对SpringSecurity的这三种自定义身份认证进行详细讲解,... 目录1.内存身份认证(1)创建配置类(2)验证内存身份认证2.JDBC身份认证(1)数据准备 (2)配置依

利用python实现对excel文件进行加密

《利用python实现对excel文件进行加密》由于文件内容的私密性,需要对Excel文件进行加密,保护文件以免给第三方看到,本文将以Python语言为例,和大家讲讲如何对Excel文件进行加密,感兴... 目录前言方法一:使用pywin32库(仅限Windows)方法二:使用msoffcrypto-too