21.1 stm32使用LTDC驱动LCD--配置说明
本文讲解如何配置LTDC驱动LCD的参数配置,以及CubeMx参数配置说明
本文使用的是淘宝买的一块带电容触摸的液晶显示屏:5寸TFT液晶显示屏高清800*480免驱40P通用RGBIPS全视角彩屏GT911
说实话,价格还是相对挺便宜的,值得入手,哈哈哈
这款屏幕采用的是RGB888格式
这里面也就是常用的引脚:
R0-R7、G0-G7、B0-B7
DCLK–时钟线
HSYNC\VSYNC–同步线
DE–数据使能
DISP是显示使能,控制屏幕的哈
背光是通过控制LED+\LED-的电流实现的
由此可以找到,LED需要流过20mA电流,下面是它的推荐电路
接着我就绘制了我的PCB,如下所示:我的是电容触摸屏,所以电阻触摸引脚位置悬空的
接下来,我们就来CubeMx配置LTDC驱动它吧
CubeMx配置LTDC
硬件相关参数设置
注意:这里的HSYNC、VSYNC、DE的有效极性需要和实际相反
由此图可以看出HSYNC、VSYNC、DE的有效极性都是高,clk的下降沿采样
上面我的LTDC配置取得都是典型值
Pulse Width对应的是HSW和VSW
引脚需要全部高速
然后就还有LTDC输出给LCD的时钟信号,由上面的数据手册给出的典型值配置25MHz,LTDC会由LTDC_PCLK引脚输出给LCD
到此,LTDC硬件相关的参数配置完毕
LTDC图像层配置
开启全局中断,并且优先级可以设置低点
DMA2D在代码里重新配置过得,可以按此设置
关于FMC的SDRAM存储属性设置可以参考如下:
调试
如何判定硬件问题:
在函数void MX_LTDC_Init(void)中的HAL_LTDC_Init()后如下处理:
如果LCD能显示红色说明硬件正常,否则有问题
lcd_base_backlight_set是开启屏幕背光
完整工程下载:(旧版本,不建议使用,LCD显示刷新没处理后续说的cache更新)
链接:https://pan.baidu.com/s/1g_VezTfR_-fgqSpPFlvtqQ
提取码:qqio
补充:
该屏幕GT911驱动:
需要注意的是INT引脚禁止上下拉,应配置为浮空输入
触摸屏手指触摸时会触摸70ms左右,这段时间其实坐标是同一点,INT引脚持续输出方波信号10ms间隔
所以应采集判定坐标避免重复点如下函数:
/**************************************************** @function:触摸芯片扫描 @param:(x,y)--点 @return:-1--无触摸,0--触摸 @note:只读取一个点,建议10ms执行一次 注意:此函数未处理重复触摸点,尤其是在两次点击相同像素点的情况下,但是概率不大 ****************************************************/ int GT911_Scan(uint16_t *x,uint16_t *y) { static uint16_t xlast = 0,ylast = 0; if(!gt911.Enable)return -1; if(!GT911_PenInt())return -1;//没有触摸 GT911_TouchPointRead(x,y); if((*x == xlast) && (*y == ylast))return -1;//移除重复点 xlast = *x; ylast = *y; return 0; }
完整驱动代码:
GT911_driver.c
GT911_driver.h
i2c_driver.c//模拟IIC
i2c_driver.h
delay_driver.c//定时器微秒精确延时
delay_driver.h
GT911_driver.h
#ifndef _GT911_driver_H_ #define _GT911_driver_H_ #ifdef __cplusplus extern "C" { #endif #include "stdint.h" uint16_t GT911_ScreenWidthGet(void); uint16_t GT911_ScreenHeigthGet(void); int GT911_Init(void); int GT911_Scan(uint16_t *x,uint16_t *y); #ifdef __cplusplus } #endif #endif
GT911_driver.c
/********************************************************************** *file:自己编写的GT911触摸检测 *author:残梦 *versions:V1.0 *date:2023.11.8 *note: 注意GT911的INT引脚会在触摸时出现10ms的方波信号,手指单次触摸维持在70ms左右, 持续触摸会一直到释放,默认高电平,触摸低电平,引脚应浮空严禁上下拉 **********************************************************************/ #include "GT911_driver.h" #include "i2c_driver.h" #include "delay_driver.h" #include "gpio.h" #include "stdio.h" /* 定义触笔中断INT的GPIO端口 */ #define TP_INT_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() #define TP_INT_GPIO_PORT GPIOD #define TP_INT_PIN GPIO_PIN_4 #define TP_RST_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() #define TP_RST_GPIO_PORT GPIOD #define TP_RST_PIN GPIO_PIN_5 //#define GT911_I2C_ADDR1 0xBA #define GT911_READ_XY_REG 0x814E /* 坐标寄存器 */ #define GT911_CLEARBUF_REG 0x814E /* 清除坐标寄存器 */ #define GT911_CONFIG_REG 0x8047 /* 配置参数寄存器 */ #define GT911_COMMAND_REG 0x8040 /* 实时命令 */ #define GT911_PRODUCT_ID_REG 0x8140 /* 芯片ID */ #define GT911_VENDOR_ID_REG 0x814A /* 当前模组选项信息 */ #define GT911_CONFIG_VERSION_REG 0x8047 /* 配置文件版本号 */ #define GT911_CONFIG_CHECKSUM_REG 0x80FF /* 配置文件校验码 */ #define GT911_FIRMWARE_VERSION_REG 0x8144 /* 固件版本号 */ typedef struct { //芯片参数 uint8_t i2cAddress;//i2c地址 uint16_t width;//屏幕宽度 uint16_t height;//屏幕高度 //用户变量 uint8_t Enable;//使能状态,初始化成功则为1,失败为0 }GT911_StructDef; static GT911_StructDef gt911 = \ { .Enable = 0, };//触摸屏结构体变量 static void GT911_WriteReg(uint16_t _usRegAddr, uint8_t *_pRegBuf, uint8_t _ucLen); static void GT911_ReadReg(uint16_t _usRegAddr, uint8_t *_pRegBuf, uint8_t _ucLen); static void GT911_ReadMaxXY(uint16_t *_X, uint16_t *_Y); static void GT911_InitPin(void); static uint32_t GT911_ReadID(void); static int GT911_DetectID(void); static uint8_t GT911_PenInt(void); static void GT911_TouchPointRead(uint16_t *x,uint16_t *y); /**************************************************** @function:写1个或连续的多个寄存器 @param: _usRegAddr : 寄存器地址 _pRegBuf : 寄存器数据缓冲区 _ucLen : 数据长度 @return:void @note: ****************************************************/ static void GT911_WriteReg(uint16_t _usRegAddr, uint8_t *_pRegBuf, uint8_t _ucLen) { uint8_t i; i2c_Start(); /* 总线开始信号 */ i2c_SendByte(gt911.i2cAddress); /* 发送设备地址+写信号 */ i2c_WaitAck(); i2c_SendByte(_usRegAddr >> 8); /* 地址高8位 */ i2c_WaitAck(); i2c_SendByte(_usRegAddr); /* 地址低8位 */ i2c_WaitAck(); for (i = 0; i > 8); /* 地址高8位 */ i2c_WaitAck(); i2c_SendByte(_usRegAddr); /* 地址低8位 */ i2c_WaitAck(); i2c_Start(); i2c_SendByte(gt911.i2cAddress + 0x01); /* 发送设备地址+读信号 */ i2c_WaitAck(); } for (i = 0; i OPFCCR = PixelFormat; /* 设置填充大小 */ DMA2D->NLR = (uint32_t)(xSize CR |= DMA2D_CR_START; /* 等待DMA2D传输完成 */ while (DMA2D->CR & DMA2D_CR_START) { } } /********************************************************************************************************** * 函 数 名: _DMA2D_Copy * 功能说明: 通过DMA2D从前景层复制指定区域的颜色数据到目标区域 * 形 参: pSrc 颜色数据源地址 * pDst 颜色数据目的地址 * xSize 目的区域的X轴大小,即每行像素数 * ySize 目的区域的Y轴大小,即行数 * OffLineSrc 前景层图像的行偏移 * OffLineDst 输出的行偏移 * PixelFormat 目标区颜色格式 * 返 回 值: 无 **********************************************************************************************************/ static void lcd_base_DMA2D_Copy(void * pSrc, void * pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLineSrc, uint32_t OffLineDst, uint32_t PixelFormat) { /* DMA2D采用存储器到存储器模式, 这种模式是前景层作为DMA2D输入 */ DMA2D->CR = 0x00000000UL | (1 FGMAR = (uint32_t)pSrc; DMA2D->OMAR = (uint32_t)pDst; DMA2D->FGOR = OffLineSrc; DMA2D->OOR = OffLineDst; /* 前景层和输出区域都采用的RGB565颜色格式 */ DMA2D->FGPFCCR = LTDC_PIXEL_FORMAT_RGB565; DMA2D->OPFCCR = LTDC_PIXEL_FORMAT_RGB565; DMA2D->NLR = (uint32_t)(xSize CR |= DMA2D_CR_START; /* 等待DMA2D传输完成 */ while (DMA2D->CR & DMA2D_CR_START) {} } /**************************************************** @function:通过DMA2D对于指定区域进行颜色复制(图像复制) @param: LayerIndex 图层 pDst 颜色数据目的地址 xSize 要复制区域的X轴大小,即每行像素数 ySize 要复制区域的Y轴大小,即行数 OffLine 前景层图像的行偏移 ColorIndex 要填充的颜色值 @return:void @note:只支持横屏 ****************************************************/ void lcd_base_DMA2D_CopyBuffer(uint16_t x,uint16_t y,uint32_t xSize, uint32_t ySize,void * color) { if((color == NULL) || (xSize == 0) || (ySize == 0))return; lcd_base_DMA2D_Copy((uint32_t *)color, /* 位图地址 */ (uint32_t *)(s_CurrentFrameBuffer + g_LcdWidth*y*2 + x*2), /* 显示起始地址(328, 20) */ xSize, /* 位图长 */ ySize, /* 位图高 */ 0, /* 位图行偏移 */ g_LcdWidth-xSize,/* 目标区行偏移 */ LTDC_PIXEL_FORMAT_RGB565); /* 目标区颜色格式 */ }
完整工程:(最新)
链接:https://pan.baidu.com/s/1I64wD4Ft7PBI0cIogGp45A
提取码:qpxx