历史上的今天
今天是:2025年03月16日(星期日)
2020年03月16日 | FSMC驱动TFT显示屏(和驱动触摸屏)
2020-03-16 来源:eefocus
我所使用的是3.5寸电容触摸显示屏
所谓电容触摸显示屏其实是两个屏幕的叠加:
显示屏,其驱动芯片为ILI9488。
触摸屏,其驱动芯片为FT6336
一、显示屏
首先驱动显示屏,买到屏幕之后问卖家拿到驱动程序、原理图和技术文档。
这个屏幕有七种驱动方式:
表一 TFT驱动方式

TFT几种接口:
MCU接口所用引脚:/RES , /CS , RS(寄存器选择) , /WR , /RD , DB0 ~ DB17 (18bit)
RGB接口所用引脚:DE , VSYNC , HSYNC , PCLK , R0~R5 , G0~G5 , B0~B5 (18bit)
(RGB接口和MPU接口区别)
SPI接口所用引脚:/RST、/CS、SDO、SDI、SCL、RS
MCU模式:目前最常用的连接模式,一般是80系统(68系统已经不存在了)。数据位传输有8位,9位,16位和18位。
优点是:控制简单方便,无需时钟和同步信号。
缺点是:要耗费GRAM,所以难以做到大屏。
RGB模式:大屏采用较多的模式,数据位传输也有6位,16位和18位之分。连线一般有:VSYNC,HSYNC ,DOTCLK,VLD,ENABLE,剩下就是数据线。
它的优缺点正好和MCU模式相反。
SPI模式:相对上面接口所用线较少,但速度也相对较慢,对于小屏来说用起来方便。
这里的三线和四线SPI的区别:
三线SPI: SDI(接MOSI)、CS、SCL
四线SPI: SDI、CS、SCL、RS(data/command,用于数据还是指令)
三线SPI通过发送9位data的第1位决定该data是数据还是指令,其余的D1到D8相对应是data/command
SPI总线也是一种事实标准,它没有被任何的国际委员会承认。
有的三线SPI指的是类似半双工的SISO,即将MISO和MOSI合并为一根线;有的则是直接将片选省略(直接拉低),即不需要片选(不共享SPI总线),一直都选择这一设备。
SPI 三线与四线区别总结
(一)FSMC介绍
可变静态存储控制器FSMC是STM32系列采用的一种新型存储器扩展技术,这种控制器被设
置在芯片内部集成超过256 KB Flash并且名字后缀为xC、xD以及xE的大容量产品所特有的存储控制机制。它可以方便地控制诸如SRAM/PSRAM/NOR/NAND/ROM/PC卡等存储器,只需要将对应管脚相连,芯片内部就能处理时序逻辑问题,操作起来十分方便。
FSMC地址映射及支持的存储器类型如图所示。FSMC管理1GB的映射地址,划分为4个大小都为4x64MB的存储块Bank,每个大存储块又划分为4个64MB的子Bank即Sector。由于驱动的是屏幕,而驱动NOR/PSRAM的方式和8080接口差不多,故FSMC选择Bank1,其地址映射为0x6000 0000至0x6FFF FFFF。

图一 FSMC内存划分
下面介绍8080接口和FSMC在时序和所用引脚的相似之处,从下面图二可以看到8080接口有这几种信号线:数据/命令信号(RS)、片选信号(CS)、写数据信号(WR)、数据信号(D[17:0])、读数据信号(RD)。而从图三可以看到FSMC主要有这些信号线:区块片选信号(FSMC_NEx)、读数据信号(FSMC_NOE)、写数据信号(FSMC_NWE)、地址信号(FSMC_A[25:0])、数据信号(FSMC_D[15:0])。

图二 8080时序图

图三 FSMC时序图
对比来看这两者很相似但却并不完全相同,由于FSMC没有数据/命令信号,所以利用它的地址线充当这种信号。假如使用地址线的FSMC_A0充当数据命令信号,并且使用第一个Bank的第四个Sector即FSMC_Bank1_NORSRAM4,如表3-3所示可知需要将寄存器基地址设置为0x6C00 0000,RAM基地址就设置为0x6C00 0000+(1<<(0+1))=0x6C00 0002,简单来说寄存器基地址就为命令操作的地址,而RAM基地址就是数据操作的地址。需要注意的是由于我们选择的是16位宽度的SRAM,FSMC在设置这些地址时STM32内部会自动它们右移1位对齐,方便用户操作。
表二 FSMC地址选择

(二)FSMC配置
表三 FSMC引脚配置连接表

之后需要配置FSMC_NORSRAMInitTypeDef和FSMC_NORSRAMTimingInitTypeDef结构体,代码如下:
static void LCD_FSMC_Config ( void )
{
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
FSMC_NORSRAMTimingInitTypeDef fsmc_lcd;
/* 使能FSMC时钟*/
RCC_AHBPeriphClockCmd ( RCC_AHBPeriph_FSMC, ENABLE );
fsmc_lcd.FSMC_AddressSetupTime = 0x02; //地址建立时间
fsmc_lcd.FSMC_AddressHoldTime = 0x00; //地址保持时间
fsmc_lcd.FSMC_DataSetupTime = 0x05; //数据建立时间
fsmc_lcd.FSMC_BusTurnAroundDuration = 0x00;
fsmc_lcd.FSMC_CLKDivision = 0x00;
fsmc_lcd.FSMC_DataLatency = 0x00;
fsmc_lcd.FSMC_AccessMode = FSMC_AccessMode_B; //模式B比较适用于LCD
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_LCD_BACKx;
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 = & fsmc_lcd;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = & fsmc_lcd;
FSMC_NORSRAMInit ( & FSMC_NORSRAMInitStructure );
/* 使能 FSMC_Bank1_NORSRAM4 */
FSMC_NORSRAMCmd ( FSMC_LCD_BACKx, ENABLE );
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
需要说明的是FSMC读写数据是对FSMC映射的地址进行操作的,具体宏定义如下:
#define FSMC_LCD_CMD ((uint32_t)0x6C000000) //FSMC_Bank1_NORSRAM1用于LCD命令操作的地址
#define FSMC_LCD_DATA ((uint32_t)0x6C000002) //FSMC_Bank1_NORSRAM1用于LCD数据操作的地址
#define LCD_WRITE_CMD(x) *(__IO uint16_t *)FSMC_LCD_CMD = x
#define LCD_WRITE_DATA(x) *(__IO uint16_t *)FSMC_LCD_DATA = x
#define LCD_READ_DATA() *(__IO uint16_t *)FSMC_LCD_DATA
#define FSMC_LCD_BACKx FSMC_Bank1_NORSRAM4
1
2
3
4
5
6
下面给出ILI9488的参考驱动代码:
static void ILI9488_REG_Config ( void )
{
//************* Start Initial Sequence **********//
/* PGAMCTRL (Positive Gamma Control) (E0h) */
LCD_WRITE_CMD(0xE0);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x07);
LCD_WRITE_DATA(0x10);
LCD_WRITE_DATA(0x09);
LCD_WRITE_DATA(0x17);
LCD_WRITE_DATA(0x0B);
LCD_WRITE_DATA(0x41);
LCD_WRITE_DATA(0x89);
LCD_WRITE_DATA(0x4B);
LCD_WRITE_DATA(0x0A);
LCD_WRITE_DATA(0x0C);
LCD_WRITE_DATA(0x0E);
LCD_WRITE_DATA(0x18);
LCD_WRITE_DATA(0x1B);
LCD_WRITE_DATA(0x0F);
/* NGAMCTRL (Negative Gamma Control) (E1h) */
LCD_WRITE_CMD(0XE1);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x17);
LCD_WRITE_DATA(0x1A);
LCD_WRITE_DATA(0x04);
LCD_WRITE_DATA(0x0E);
LCD_WRITE_DATA(0x06);
LCD_WRITE_DATA(0x2F);
LCD_WRITE_DATA(0x45);
LCD_WRITE_DATA(0x43);
LCD_WRITE_DATA(0x02);
LCD_WRITE_DATA(0x0A);
LCD_WRITE_DATA(0x09);
LCD_WRITE_DATA(0x32);
LCD_WRITE_DATA(0x36);
LCD_WRITE_DATA(0x0F);
/* Adjust Control 3 (F7h) */
LCD_WRITE_CMD(0XF7);
LCD_WRITE_DATA(0xA9);
LCD_WRITE_DATA(0x51);
LCD_WRITE_DATA(0x2C);
LCD_WRITE_DATA(0x82);/* DSI write DCS command, use loose packet RGB 666 */
/* Power Control 1 (C0h) */
LCD_WRITE_CMD(0xC0);
LCD_WRITE_DATA(0x11);
LCD_WRITE_DATA(0x09);
/* Power Control 2 (C1h) */
LCD_WRITE_CMD(0xC1);
LCD_WRITE_DATA(0x41);
/* VCOM Control (C5h) */
LCD_WRITE_CMD(0XC5);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x0A);
LCD_WRITE_DATA(0x80);
/* Frame Rate Control (In Normal Mode/Full Colors) (B1h) */
LCD_WRITE_CMD(0xB1);
LCD_WRITE_DATA(0xB0);
LCD_WRITE_DATA(0x11);
/* Display Inversion Control (B4h) */
LCD_WRITE_CMD(0xB4);
LCD_WRITE_DATA(0x02);
/* Display Function Control (B6h) */
LCD_WRITE_CMD(0xB6);
LCD_WRITE_DATA(0x02);
LCD_WRITE_DATA(0x22);
/* Entry Mode Set (B7h) */
LCD_WRITE_CMD(0xB7);
LCD_WRITE_DATA(0xc6);
/* HS Lanes Control (BEh) */
LCD_WRITE_CMD(0xBE);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x04);
/* Set Image Function (E9h) */
LCD_WRITE_CMD(0xE9);
LCD_WRITE_DATA(0x00);
/* 设置屏幕方向和尺寸 */
LCD_SetDirection(LCD_DIRECTION);
/* Interface Pixel Format (3Ah) */
LCD_WRITE_CMD(0x3A);
LCD_WRITE_DATA(0x55);/* 0x55 : 16 bits/pixel */
/* Sleep Out (11h) */
LCD_WRITE_CMD(0x11);
LCD_DELAY(120*2000);
/* Display On */
LCD_WRITE_CMD(0x29);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
之后就可以根据屏幕操作函数进行显示操作啦!
代码参考来源:硬石嵌入式开发团队
二、触摸屏
我使用的是IIC总线驱动的触摸屏,IIC的程序都一样,主要是由于驱动芯片和厂家不同所导致的驱动程序不同。实际操作中直接读写寄存器即可,下面给出屏幕按键扫描参考代码。
void FT6236_Scan(void)
{
u8 i=0;
u8 sta = 0;
u8 buf[4] = {0};
FT6236_RD_Reg(0x02,&sta,1);//读取触摸点的状态
if(sta & 0x0f) //判断是否有触摸点按下,0x02寄存器的低4位表示有效触点个数
{
TPR_Structure.TouchSta = ~(0xFF << (sta & 0x0F)); //~(0xFF << (sta & 0x0F))将点的个数转换为触摸点按下有效标志
for(i=0;i<5;i++) //分别判断触摸点1-5是否被按下
{
if(TPR_Structure.TouchSta & (1< { //被按下则读取对应触摸点坐标数据
FT6236_RD_Reg(FT6236_TPX_TBL[i],buf,4); //读取XY坐标值
TPR_Structure.x[i]=((u16)(buf[0]&0X0F)<<8)+buf[1];
TPR_Structure.y[i]=((u16)(buf[2]&0X0F)<<8)+buf[3];
if((buf[0]&0XC0)!=0X80)
{
TPR_Structure.x[i]=TPR_Structure.y[i]=0;//必须是contact事件,才认为有效
return;
}
}
}
TPR_Structure.TouchSta |= TP_PRES_DOWN; //触摸按下标记
}
else
{
if(TPR_Structure.TouchSta &TP_PRES_DOWN) //之前是被按下的
TPR_Structure.TouchSta &= ~0x80; //触摸松开标记
else
{
TPR_Structure.x[0] = 0;
TPR_Structure.y[0] = 0;
TPR_Structure.TouchSta &=0xe0; //清除触摸点有效标记
}
}
}
史海拾趣
|
[ip]塑封料发展状况及其工艺选择 上海常祥实业有限公司 刘志:13611616628 引言 塑封料,又称环氧塑封料(EMC,Epoxy Molding Compound)以其高可靠性、低成本、生产工艺简单、适合大规模生产等特点,占据了整个微电子封装材料97%以上的市场。 ...… 查看全部问答> |
|
我在学校读的是应付用电子,会画点PCB,懂得电子基础,学过一点C,一点单片机,一点汇编,一点VB,都是学了一点,谈不上熟,出来工作有五年了,基本上没怎么接触这一块,现在想学嵌入式系统,自己搞点项目,对于我这种情况还能学不,各位大哥出个注意!… 查看全部问答> |
|
在STVD(调试STM8)里watch变量有"ON THE FLY"可以实时查看变量的变化。 在IAR5.XX调试STM32F103XXX不知道有没有这样的功能??? 或者类似的功能也行啊??? 请IAR EARM 高手指点!!!… 查看全部问答> |
|
关于NE555的问题。当输入高电平,输出低电平不够低怎么办?量出来2.7。 做单稳电路。高电平3.7,低电平2.7。 [ 本帖最后由 huang91 于 2011-11-10 15:49 编辑 ]… 查看全部问答> |
|
Master or slave Master runs up to sys_clk/2 (25Mb @ 50MHz) Slave runs up to sys_clk/12 (4.1667Mb @ 50MHz) … 查看全部问答> |




