基于STM32F103的触摸屏驱动模块设计要点
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于STM32F103x的LCD触摸屏驱动的设计
姓名:______徐进东_______
学号:______10030227_____
班级:______10 计卓______
目录
1 概述 (3)
2 LCD液晶显示屏 (3)
2.1 LCD液晶显示屏原理 (3)
2.2 LCD液晶显示屏分类 (3)
3 触摸屏驱动原理概述 (4)
3.1 电阻触摸屏工作原理 (4)
3.2 触摸屏控制实现 (4)
4 设计目标 (4)
5 系统硬件设计 (5)
5.1 STM32微处理器FSMC接口 (5)
5.2 LCD液晶显示屏介绍 (7)
5.3 触摸屏控制板 (8)
6 系统软件设计 (10)
6.1 系统软件结构 (10)
6.2 头文件设计 (11)
6.2 硬件初始化程序 (11)
6.3 3寸LCD模块驱动程序 (14)
6.4 触摸坐标获取程序 (19)
6.5 LCD控制器控制程序 (22)
7 总结 (24)
1 概述
LCD液晶显示屏与触摸屏在嵌入式系统中的应用越来越普及。
他们是非常简单、方便、自然的人机交互方式,目前广泛应用于便携式仪器、智能家电、掌上设备等领域。
触摸屏与LCD液晶显示技术的紧密结合,成了主流配置。
LCD液晶显示屏(LCD Module , LCM)是一种将液晶显示器件、连接件、集成电路、PCB线路板、背光源以及结构件装配在仪器的组件。
触摸屏技术在我国的应用时间不是太长,但它已经成长为人们最为接受的输入方式。
利用这种技术人们只需触碰屏幕就可以对主机进行操作,是人机交互更为方便,直截了当。
本文档是对LCD液晶显示屏和触摸屏驱动的设计做深入介绍。
2 LCD液晶显示屏
2.1 LCD液晶显示屏原理
液晶(Liquid Crystal):是一种介于固态和液态之间的具有规则性分子排列,及晶体的光学各向异性的有机化合物,液晶在受热到一定温度的时候会呈现透明状的液体状态,而冷却则会出现结晶颗粒的混浊固体状态,因为物理上具有液体与晶体的特性,故称之为“液晶”。
液晶显示器LCD(Liquid Crystal Display):是新型平板显示器件。
显示器中的液晶体并不发光,而是控制外部光的通过量。
当外部光线通过液晶分子时,液晶分子的排列扭曲状态不同,使光线通过的多少就不同,实现了亮暗变化,可重现图像。
液晶分子扭曲的大小由加在液晶分子两边的电压差的大小决定。
因而可以实现电到光的转换。
即用电压的高低控制光的通过量,从而把电信号转换成光像。
2.2 LCD液晶显示屏分类
1.位段型液晶显示模块
位段型液晶显示模块是一种由位段型液晶显示器件与专用的集成电路组装成一体的功能部件。
2.字符型液晶显示模块
字符型液晶显示模块是由字符液晶显示器件与专用的行、列驱动器、控制器、必要的连接件以及结构件装配而成,可以显示数字和西文字符。
3.图形点阵型液晶显示模块
图形点阵型显示模块就是可以动态地显示字符和图片的LCD。
图形点阵液晶模块的点阵像素连续排列,行和列在拍布中均没有空隔,不仅可以显示字符,还可以显示连续完整的图像。
图形点阵型液晶显示模块有三种类型可供选择:行列驱动型,行列驱动控制型及行列控制型。
3触摸屏驱动原理概述
3.1 电阻触摸屏工作原理
电阻触摸屏是采用电阻模拟量技术。
它是一层玻璃作为基层,上面涂有一层透明氧化金属(ITO氧化铟)导电层,再盖有一层玻璃或是外表面硬化处理的光滑的塑料层;内表面也涂有一层ITO导电层。
它们之间有许多细小的透明隔离点把两导电层隔开绝缘,每当有笔或是手指按下时,两导电层就相互接触。
而形成电路。
导电层的两端都涂有一条银胶,称为该工作面的一对电极。
上下两个导电层一个是水平方向,一个是竖直方向,分别用来测量X 和Y的坐标位置。
在水平面上的电极称为X+电极和X-电极,在竖直平面的电极称为Y+电极和Y-电极。
工作时,两个电极根据测量需要提供参考电压或是作为测量端对接触点的位置进行测量。
当测量接触点X坐标的时候,导电层上的X+电极和X-电极分别上参考电压和地;Y 电极不加电压,那么X电极间会形成均匀的电压分布,用Y+电极作为测量点,得到的电压值通过A/D转换,就可对应地判断出接触点的X坐标。
Y坐标亦是类似,只需改成对Y电极加电压而X电极不加电压即可。
图4-1 电阻屏原理图
3.2 触摸屏控制实现
对触摸屏的控制有专用的控制芯片。
触摸屏的控制芯片主要完成两个任务:一是完成电极电压的切换,二是采集接触点处的电压值并实现A/D转换。
触摸屏控制芯片主要由触摸检测部件和触摸屏控制器组成。
触摸检测部件安装在显示器屏幕前面,用于检测用户触摸位置,接受位置信号后送至触摸屏控制器;而触摸屏控制器的主要作用是从触摸点检测装置上接收触摸信息,并将它转换成触点坐标,再送给MPU,同时它能接收MPU发来的命令并加以执行。
4 设计目标
基于STM32硬件开发平台与3寸液晶屏组成液晶显示与触摸屏人机交互系统。
5 系统硬件设计
本实验的主要硬件由STM32微处理器的FSMC 接口,3寸屏时序转换板以及触摸屏控制板组成。
图5-1 硬件系统结构图
5.1 STM32微处理器FSMC 接口
FSMC 模块能够与同步或异步的存储器和16位的PC 存储器卡接口,它的主要作用是: ● 将AHB 传输信号转换到适当的外部设备协议 ● 满足访问外部设备的时序要求,所有的外部存储器共享控制器输出的地址、数据和
控制信号,每个外部设备可以通过一个唯一的片选信号加以区分。
FSMC 在任一时刻只访问一个外部设备。
FSMC 具有下列主要功能:
● 具有静态存储器接口的器件包括:
——静态随机存储器(SRAM) ——只读存储器(ROM) ——NOR 闪存
——PSRAM(4个存储器块)
● 两个NAND 闪存块,支持硬件ECC 并可检测多达8K 字节数据 ● 16位的PC 卡
● 支持对同步器件的成组(Burst)访问模式,如NOR 闪存和PSRAM ● 8或16位数据总线
● 每一个存储器块都有独立的片选控制 ● 每一个存储器块都可以独立配置 ● 时序可编程以支持各种不同的器件:
——等待周期可编程(多达15个周期) ——总线恢复周期可编程(多达15个周期)
——输出使能和写使能延迟可编程(多达15周期)
——独立的读写时序和协议,可支持宽范围的存储器和时序
●PSRAM和SRAM器件使用的写使能和字节选择输出
●将32位的AHB访问请求,转换到连续的16位或8位的,对外部16位或8位器件
的访问
●具有16个字,每个字32位宽的写入FIFO,允许在写入较慢存储器时释放AHB进
行其它操作。
在开始一次新的FSMC操作前,FIFO要先被清空。
通常在系统复位或
上电时,应该设置好所有定义外部存储器类型和特性的FSMC寄存器,并保持它们
的内容不变;当然,也可以在任何时候改变这些设置。
FSMC包含四个主要模块:
●AHB接口(包含FSMC配置寄存器)
●NOR闪存和PSRAM控制器
●NAND闪存和PC卡控制器
●外部设备接口
FSMC框图如下:
图5-2 FSMC接口结构框图
当STM32微处理器使用FSMC接口模块来控制LCD液晶显示模块时,其接口信号用于驱动LCD的对应关系:
STM32微处理器使用FSMC接口模块与LCD英特尔8080(类似)接口示意图:
图5-3 FSMC接口模块与LCD英特尔8080接口示意图
5.2 LCD液晶显示屏介绍
本实验的LCD液晶显示器采用宇顺公司的3寸彩色液晶屏S95361,分辨率为240*400。
3TFT显示屏焊接在奋斗显示转接板上,在屏上贴有触摸屏,通过40芯的接口与V5连接。
40芯接口定义如下:
图5-4 40芯接口
40芯里包含了16位数据线,读写线,命令/数据控制线,片选线,LCD硬件复位线,背光控制线以及触摸控制线。
奋斗板V3和MINI就是通过这个接口来控制显示。
奋斗板MINI 和V3都是选用了具有16位FSMC接口STM32F103VET6作为MCU,FSMC接口也可以称为16位并行接口,时序同I8080接口。
按照显示屏驱动电路LGDP5420的手册,为了达到色彩与显示效率的平衡,奋斗板采用了16位64K色接口模式。
图5-5 16位RGB真彩图
在这个模式每个像素用5位红色6位绿色5位蓝色总共16位来表示,根据分辨率,一帧图像占用400*240*2=192000字节。
16位8080总线接口时序如下:
图5-6 总线读写时序图
5.3 触摸屏控制板
TSC2046是一款四线制触摸屏控制器,内涵12位分辨率125kHz转换速率逐步逼近型A/D转换器,它支持1.5V~5.25V范围的低电压I/O口。
TSC2046还具有一个片上2.5V的参考电压,可以用于辅助输入,电池监测,和温度测量模式。
TSC2046芯片主要功能如下:
●具有四线制触摸屏接口;
●可单电源工作,工作电压范围2.2V至5.25V;
●支持1.5V至5.25V的数字I / O口;
●内部自带2.5V参考电压源;
●能直接测量电源电压(0V至6V);
●片上温度测量;
●触摸压力测量;
●具有3线制SPI通信接口;
●自动省电;
●封装小,TSSOP-16,QFN-16封装,可在VFBGA-48封装;
其功能框图如下:
图5-7 TSC2046功能框图
TSC2046最常用封装TSSOP-16引脚排列如图9所示,对应的引脚功能定义如下表所示:
图5-8 TSC2046引脚排列图
6 系统软件设计
6.1 系统软件结构
图6-1 系统软件结构
本实验的触摸模块主要的软件设计任务按功能和层次可分为如下几个部分:
1、ucos系统建立任务,包括主任务,用户界面任务,CAN报文接收任务等。
2、ucGUI图形用户界面程序,设计相关操作界面。
3、中断服务程序,主要使用的中断处理函数为USB_HP_CAN_TX_IRQHandler(),执行
CAN总线接收的中断处理。
4、硬件平台初始化程序,包括时钟,CAN模块,触摸屏等等的初始化。
5、LCD的底层驱动函数。
6.2 头文件设计
本实验由于使用函数以及宏定义较多,自定义了头文件demo.hh。
demo.h内容如下:#ifdef GLOBALS
#define EXT
#else
#define EXT extern
#endif
#define Led_ON() GPIO_SetBits(GPIOB, GPIO_Pin_5); //LED1亮
#define Led_OFF() GPIO_ResetBits(GPIOB, GPIO_Pin_5); //LED1灭
#define TP_CS() GPIO_ResetBits(GPIOB,GPIO_Pin_7) //触摸SPI片选允许
#define TP_DCS() GPIO_SetBits(GPIOB,GPIO_Pin_7) //触摸SPI片选允许
#define PEN GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6) //触摸检测
#define RED 0XF800
#define GREEN 0X07E0
#define BLUE 0X001F
#define BRED 0XF81F
#define GRED 0XFFE0
#define GBLUE 0X07FF;
#define BLACK 0;
6.2 硬件初始化程序
硬件平台初始化主要包括系统时钟配置,FSMC接口的LCD初始化,SPI接口级触摸屏芯片初始化,GPIO初始化等系统常用配置。
触摸屏初始化配置通过调用tp_Config()函数实现,代码如下:
void tp_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
/* SPI1 时钟使能*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);
/* SPI1 SCK(PA5)、MISO(PA6)、MOSI(PA7) 设置*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //口线速度50MHZ
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用模式
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* SPI1 触摸芯片的片选控制设置PB7 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //口线速度50MHZ
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出模式
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* 由于SPI1总线上挂接了4个外设,所以在使用触摸屏时,需要禁止其余3个SPI1 外设,才能正常工作*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //SPI1 SST25VF016B片选
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //SPI1 VS1003片选
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //SPI1 网络模块片选
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOC, GPIO_Pin_4); //SPI CS1
GPIO_SetBits(GPIOB, GPIO_Pin_12); //SPI CS4
GPIO_SetBits(GPIOA, GPIO_Pin_4); //SPI NSS
/* SPI1总线配置*/
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主模式
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //8位
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //时钟极性空闲状态时,SCK保持低电平SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //时钟相位数据采样从第一个时钟边沿开始
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //软件产生NSS
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64; //波特率控制SYSCLK/64
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据高位在前
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC多项式寄存器初始值为7
SPI_Init(SPI1, &SPI_InitStructure);
/* SPI1 使能*/
SPI_Cmd(SPI1,ENABLE);
}
FSMC接口的LCD初始化通过调用FSMC_LCD_Init()函数实现信号引脚配置等功能。
函数代码如下:
/************************************************************************* * 名称:void FSMC_LCD_Init(void)
* 功能:基于FSMC接口的16位TFT接口初始化
* 入口参数:无
* 出口参数:无
* 说明:
* 调用方法:无
**************************************************************************/ void FSMC_LCD_Init(void)
{
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
FSMC_NORSRAMTimingInitTypeDef p;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); //使能FSMC接口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; //背光控制
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //通用推挽输出模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //输出模式最大速度50MHz
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_SetBits(GPIOD, GPIO_Pin_13); //打开背光
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //TFT 复位脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //通用推挽输出模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //输出模式最大速度50MHz
GPIO_Init(GPIOE, &GPIO_InitStructure);
/* 启用FSMC复用功能,定义FSMC D0---D15及nWE, nOE对应的引脚*/
/* 设置PD.00(D2), PD.01(D3), PD.04(nOE), PD.05(nWE), PD.08(D13), PD.09(D14), PD.10(D15),
PD.14(D0), PD.15(D1) 为复用上拉*/
GPIO_InitStructure.GPIO_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_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //最大速度50MHz
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用模式
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* 设置PE.07(D4), PE.08(D5), PE.09(D6), PE.10(D7), PE.11(D8), PE.12(D9), PE.13(D10), PE.14(D11), PE.15(D12) 为复用上拉*/
GPIO_InitStructure.GPIO_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;
GPIO_Init(GPIOE, &GPIO_InitStructure);
/* FSMC NE1 配置PD7 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* FSMC RS配置PD11-A16 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 ;
GPIO_Init(GPIOD, &GPIO_InitStructure);
p.FSMC_AddressSetupTime = 0x02;
p.FSMC_AddressHoldTime = 0x00;
p.FSMC_DataSetupTime = 0x05;
p.FSMC_BusTurnAroundDuration = 0x00;
p.FSMC_CLKDivision = 0x00;
p.FSMC_DataLatency = 0x00;
p.FSMC_AccessMode = FSMC_AccessMode_B;
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1;
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth =
FSMC_MemoryDataWidth_16b;
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode =
FSMC_BurstAccessMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive =
FSMC_WaitSignalActive_BeforeWaitState;
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
/* 使能FSMC BANK1_SRAM 模式*/
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);
}
6.3 3寸LCD模块驱动程序
/****************************************************************************
* 本例程在奋斗版STM32开发板V5上调试通过
* 文件名: Fun.c
* 内容简述:
* 文件历史:
* 版本号日期作者说明
* v1.0 2013-10 xjd
*****************************************************************************/ #include "fsmc_sram.h"
#include "font.h"
#include "demo.h"
#define Bank1_LCD_D ((uint32_t)0x60020000) //disp Data ADDR
#define Bank1_LCD_C ((uint32_t)0x60000000) //disp Reg ADDR
void LCD_Init(void);
void LCD_WR_REG(unsigned int index);
void LCD_WR_CMD(unsigned int index,unsigned int val);
void LCD_WR_Data(unsigned int val);
void LCD_test(void);
void LCD_clear(unsigned int p);
void Delay(__IO uint32_t nCount);
unsigned short LCD_RD_data(void);
extern void lcd_rst(void);
extern void Delay(__IO uint32_t nCount);
void TFT_CLEAR(u8 x,u16 y,u8 len,u16 wid);
void TFT_DrawPoint(u8 x,u16 y);
void TFT_ShowChar(u8 x,u16 y,u8 num);
void TFT_ShowNum(u8 x,u16 y,u32 num);
void TFT_ShowString(u8 x,u16 y,const u8 *p);
void TFT_ShowBmp(u8 x,u16 y,u8 lenth,u16 wide,const u8 *p);
u16 POINT_COLOR=RED; //默认红色
/**************************************************************************** * 名称:LCD_WR_REG(unsigned int index)
* 功能:FSMC写显示器寄存器地址函数
* 入口参数:无
* 出口参数:无
* 说明:
* 调用方法:无
****************************************************************************/ void LCD_WR_REG(unsigned int index)
{
*(__IO uint16_t *) (Bank1_LCD_C)= index;
}
/**************************************************************************** * 名称:void LCD_WR_CMD(unsigned int index,unsigned int val)
* 功能:FSMC写显示器寄存器数据函数
* 入口参数:无
* 出口参数:无
* 说明:
* 调用方法:无
****************************************************************************/
void LCD_WR_CMD(unsigned int index,unsigned int val)
{
*(__IO uint16_t *) (Bank1_LCD_C)= index;
*(__IO uint16_t *) (Bank1_LCD_D)= val;
}
/**************************************************************************** * 名称:unsigned short LCD_RD_data(void)
* 功能:FSMC读显示区16位数据函数
* 入口参数:无
* 出口参数:无
* 说明:
* 调用方法:无
****************************************************************************/ unsigned short LCD_RD_data(void){
unsigned int a=0;
a=*(__IO uint16_t *) (Bank1_LCD_D); //空操作
a=*(__IO uint16_t *) (Bank1_LCD_D); //读出的实际16位像素数据
return(a);
}
/**************************************************************************** * 名称:LCD_WR_Data(unsigned int val)
* 功能:FSMC写16位数据函数
* 入口参数:无
* 出口参数:无
* 说明:
* 调用方法:无
****************************************************************************/ void LCD_WR_Data(unsigned int val)
{
*(__IO uint16_t *) (Bank1_LCD_D)= val;
}
void LCD_WR_Data_8(unsigned int val)
{
*(__IO uint16_t *) (Bank1_LCD_D)= val;
}
/**************************************************************************** * 名称:void Delay(__IO uint32_t nCount)
* 功能:延时函数
* 入口参数:无
* 出口参数:无
* 说明:
* 调用方法:无
****************************************************************************/ void Delay(__IO uint32_t nCount)
{
for(; nCount != 0; nCount--);
}
//
/**************************************************************************** * 名称:void LCD_Init(void)
* 功能:2.4 寸TFT 初始化函数
* 入口参数:无
* 出口参数:无
* 说明:
* 调用方法:无
****************************************************************************/ void LCD_Init(void)
{ unsigned int i;
//lcd_rst();
GPIO_ResetBits(GPIOE, GPIO_Pin_1); //硬件复位
Delay(0x1AFFf);
GPIO_SetBits(GPIOE, GPIO_Pin_1 );
Delay(0x1AFFf);
LCD_WR_CMD(0x0000, 0x00000);
LCD_WR_CMD(0x0000, 0x00000);
LCD_WR_CMD(0x0000, 0x00000);
LCD_WR_CMD(0x0000, 0x00000);
//{time, 0010 ,ms}
LCD_WR_CMD(0x0400, 0x06200);
LCD_WR_CMD(0x0008, 0x00808);
LCD_WR_CMD(0x0300, 0x00C00);//gamma
LCD_WR_CMD(0x0301, 0x05A0B);
LCD_WR_CMD(0x0302, 0x00906);
LCD_WR_CMD(0x0303, 0x01017);
LCD_WR_CMD(0x0304, 0x02300);
LCD_WR_CMD(0x0305, 0x01700);
LCD_WR_CMD(0x0306, 0x06309);
LCD_WR_CMD(0x0307, 0x00C09);
LCD_WR_CMD(0x0308, 0x0100C);
LCD_WR_CMD(0x0309, 0x02232);
LCD_WR_CMD(0x0010, 0x00016);//69.5Hz
LCD_WR_CMD(0x0011, 0x00101);//
LCD_WR_CMD(0x0012, 0x00000);//
LCD_WR_CMD(0x0013, 0x00001);//
LCD_WR_CMD(0x0100, 0x00330);//BT,AP
LCD_WR_CMD(0x0101, 0x00237);//DC0,DC1,VC
LCD_WR_CMD(0x0103, 0x00F00);//VDV
LCD_WR_CMD(0x0280, 0x06100);//VCM
LCD_WR_CMD(0x0102, 0x0C1B0);//VRH,VCMR,PSON,PON
//{time, 0100 ,ms}
LCD_WR_CMD(0x0001, 0x00100);
LCD_WR_CMD(0x0002, 0x00100);
LCD_WR_CMD(0x0003, 0x01030);
LCD_WR_CMD(0x0009, 0x00001);
LCD_WR_CMD(0x000C, 0x00000);
LCD_WR_CMD(0x0090, 0x08000);
LCD_WR_CMD(0x000F, 0x00000);
LCD_WR_CMD(0x0210, 0x00000);
LCD_WR_CMD(0x0211, 0x000EF);
LCD_WR_CMD(0x0212, 0x00000);
LCD_WR_CMD(0x0213, 0x0018F);//432=1AF, 400=18F
LCD_WR_CMD(0x0500, 0x00000);
LCD_WR_CMD(0x0501, 0x00000);
LCD_WR_CMD(0x0502, 0x0005F);
LCD_WR_CMD(0x0401, 0x00001);
LCD_WR_CMD(0x0404, 0x00000);
//{time, 0100 ,ms}
LCD_WR_CMD(0x0007, 0x00100);//BASEE
//{time, 0100 ,ms}
LCD_WR_CMD(0x0200, 0x00000);
LCD_WR_CMD(0x0201, 0x00000);
LCD_WR_CMD(0x200, 0);
LCD_WR_CMD(0x201, 0);
*(__IO uint16_t *) (Bank1_LCD_C)= 0x202; //准备写数据显示区
for(i=0;i<96000;i++)
{
LCD_WR_Data(0xffff); //用黑色清屏
}
}
/**************************************************************************** * 名称:u32 abs(s32 res)
* 功能:取绝对值函数
* 入口参数:无
* 出口参数:无
* 说明:
* 调用方法:无
****************************************************************************/ u32 abs(s32 res)
{
if(res<0)return -res;
else return res;
}
/**************************************************************************** * 名称:u32 mn(u8 m,u8 n)
* 功能:
* 入口参数:无
* 出口参数:无
* 说明:
* 调用方法:无
****************************************************************************/ u32 mn(u8 m,u8 n)
{
u32 result=1;
while(n--)result*=m;
return result;
}
6.4 触摸坐标获取程序
TPReadX()和TPReadY()函数用于读取触摸屏X轴数据和触摸屏Y轴数据。
/**************************************************************************** * 名称:u16 TPReadX(void)
* 功能:触摸屏X轴数据读出
* 入口参数:无
* 出口参数:无
* 说明:
* 调用方法:
****************************************************************************/ u16 TPReadX(void)
{
u16 x=0;
TP_CS(); //选择XPT2046
Delay(20); //延时
SPI_WriteByte(0x90); //设置X轴读取标志
Delay(20); //延时
x=SPI_WriteByte(0x00); //连续读取16位的数据
x<<=8;
x+=SPI_WriteByte(0x00);
Delay(20); //禁止XPT2046
TP_DCS();
x = x>>3; //移位换算成12位的有效数据0-4095
return (x);
}
/**************************************************************************** * 名称:u16 TPReadY(void)
* 功能:触摸屏Y轴数据读出
* 入口参数:无
* 出口参数:无
* 说明:
* 调用方法:
****************************************************************************/ u16 TPReadY(void)
{
u16 y=0;
TP_CS(); //选择XPT2046
Delay(20); //延时
SPI_WriteByte(0xd0); //设置Y轴读取标志
Delay(20); //延时
y=SPI_WriteByte(0x00); //连续读取16位的数据
y<<=8;
y+=SPI_WriteByte(0x00);
Delay(20); //禁止XPT2046
TP_DCS();
y = y>>3; //移位换算成12位的有效数据0-4095
return (y);
}
/**************************************************************************** * 名称:void Read_XPT2046(void)
* 功能:读取触摸坐标,进行采样计算
* 入口参数:无
* 出口参数:无
* 说明:
* 调用方法:
****************************************************************************/ void Read_XPT2046(void)
{
float X1,Y1;
u8 t,t1,count=0;
u16 databuffer[2][30]; //触摸坐标过采样缓冲区
u16 temp=0;
do{ //循环读数30次X=TPReadX();
Y=TPReadY();
if(X>100&&X<4000&&Y>100&&Y<4000) //如果是在触摸显示有效区范围的值,标示此读数有效
{
databuffer[0][count]=X;
databuffer[1][count]=Y;
count++;
}
}while((PEN==0)&&count<30);
if(count==30) //每次度数一定要读到30次数据,否则丢弃
{
do //将数据X升序排列
{
t1=0;
for(t=0;t<count-1;t++)
{
if(databuffer[0][t]>databuffer[0][t+1])//升序排列
{
temp=databuffer[0][t+1];
databuffer[0][t+1]=databuffer[0][t];
databuffer[0][t]=temp;
t1=1;
}
}
}while(t1);
do //将数据Y升序排列
{
t1=0;
for(t=0;t<count-1;t++)
{
if(databuffer[1][t]>databuffer[1][t+1])//升序排列
{
temp=databuffer[1][t+1];
databuffer[1][t+1]=databuffer[1][t];
databuffer[1][t]=temp;
t1=1;
}
}
}while(t1);
}
/* 从排序过的数组里中间抽取连续的10组数据,进行取平均值,获得较高的精度*/ X1=0; Y1=0;
for(count=10;count<20; count++){
X1=X1+databuffer[0][count];
Y1=Y1+databuffer[1][count];
}
X1=X1/10; Y1=Y1/10;
}
6.5 LCD控制器控制程序
该部分程序主要包括LCD复位,画点,显示字符及图片等程序。
详细代码如下:
/************************************************************************** **
* 名称:void TFT_CLEAR(u8 x,u16 y,u8 len,u16 wid)
* 功能:2.4 寸TFT 清屏函数
* 入口参数:无
* 出口参数:无
* 说明:
* 调用方法:无
*************************************************************************** */
void TFT_CLEAR(u8 x,u16 y,u8 len,u16 wid)
{
u32 n,temp;
LCD_WR_CMD(0x0210, x); //窗口的起始X
LCD_WR_CMD(0x0211, x+len-1); //窗口的结束X
LCD_WR_CMD(0x0212, y); //窗口的起始Y
LCD_WR_CMD(0x0213, y+wid-1); //窗口的结束Y
LCD_WR_CMD(0x200, 0); //起始坐标X
LCD_WR_CMD(0x201, 30); //起始坐标Y
LCD_WR_REG(0x202);
temp=(u32)len*wid;
for(n=0;n<temp;n++)LCD_WR_Data(0xffff); //用白色清除
}
/************************************************************************** **
* 名称:void TFT_DrawPoint(u8 x,u16 y)
* 功能:2.4 寸TFT 画点函数
* 入口参数:无
* 出口参数:无
* 说明:
* 调用方法:无
*************************************************************************** */
void TFT_DrawPoint(u8 x,u16 y)
{
LCD_WR_CMD(0x0210, x); //窗口的起始X
LCD_WR_CMD(0x0211, x); //窗口的结束X
LCD_WR_CMD(0x0212, y); //窗口的起始Y
LCD_WR_CMD(0x0213, y); //窗口的结束Y
LCD_WR_CMD(0x200, x); //起始坐标X
LCD_WR_CMD(0x201, y); //起始坐标Y
LCD_WR_REG(0x202);
LCD_WR_Data(POINT_COLOR);
}
/************************************************************************** **
* 名称:u32 abs(s32 res)
* 功能:取绝对值函数
* 入口参数:无
* 出口参数:无
* 说明:
* 调用方法:无
*************************************************************************** */
u32 abs(s32 res)
{
if(res<0)return -res;
else return res;
}
/************************************************************************** **
* 名称:u32 mn(u8 m,u8 n)
* 功能:
* 入口参数:无
* 出口参数:无
* 说明:
* 调用方法:无
*************************************************************************** */
u32 mn(u8 m,u8 n)
{
u32 result=1;
while(n--)result*=m;
return result;
}
7 总结
本实验介绍了LCD液晶显示屏与触摸屏工作原理,实现了基于STM32微处理器的LCD 触摸驱动程序。