1 使用STM32F103VET6+ILI9341驱动
1.1 硬件部分
使用STM32F103VET6的FSMC驱动ILI9341
在查看stm32f103的数据手册,我们可以在P30-P35上找到如下内容(截图为100管脚的):
在stm32数据手册上,在P156上找到一张图:
ILI9341硬件引脚如下:
硬件接线:
下引脚:
硬件引脚 | 功能 |
---|---|
PD14 | FSMC_D0 |
PD15 | FSMC_D1 |
PD0 | FSMC_D2 |
PD1 | FSMC_D3 |
PE7 | FSMC_D4 |
PE8 | FSMC_D5 |
PE9 | FSMC_D6 |
PE10 | FSMC_D7 |
PE11 | FSMC_D8 |
PE12 | FSMC_D9 |
PE13 | FSMC_D10 |
PE14 | FSMC_D11 |
PE15 | FSMC_D12 |
PD8 | FSMC_D13 |
PD9 | FSMC_D14 |
PD10 | FSMC_D15 |
PD4 | FSMC_NOE (RD) |
PD5 | FSMC_NWE (WR) |
PD7 | FSMC_NE1/FSMC_NCE2(CS) |
PD11 | FSMC_A16 (D/CX) |
PE1 | FSMC_NBL1 (复位) |
PD13 | FSMC_A18 (backlight) |
其他引脚 | 其他功能 |
---|---|
PA5 | SPI1-SCK |
PA7 | SPI1-MOSI |
PA6 | SPI1-MISO |
PB7 | I2C1-SDA |
PB6 | I2C1-SCL |
ILI9341支持多种接口,但是在stm32上只能使用它的8080-I/8080-II接口。
在stm32f103vet6的数据手册上,P61-P63上找到如图所示:
读取数据波形:
从这里可以找到STM32-ILI9341的对应关系:
STM32引脚 | ILI9341 | 功能 |
---|---|---|
FSMC_NEx | CSx | 数据使能管脚 |
FSMC_NOE | RDX | 读数据管脚 |
FSMC_NWE | WRx | 写数据管脚 |
FSMC_A[25:0] | D/Cx | 地址命令区分 |
FSMC_NBL[1:0] | 略 | 略 |
FSMC_D[15:0] | D[17:0] | 数据管脚 |
FSMC_NADV | 略 | 略 |
这里还要谈一谈NADV的作用
NADV是地址和数据的锁存。如果使用锁存器,则地址和数据嫩天同时传输。而如果使用锁存,则是有先后顺序。在stm32上,不使用锁存功能。
STM32访问FSMC的地址空间:
1.2 ILI9341介绍
1.2.1 ILI9341参数
硬件参数
1.分辨率:240(H)x320(V)
2.TFT LCD驱动,显示缓存:172800字节(32024018 / 8)。
3.系统接口支持:a.支持8080-I/8080-II系列CPU的8位,9位,16位,18位接口。b.有图形控制的6位,16位,18位的RGB接口。c.3线/4线串行接口。
4.显示模式:a.全彩色模式(空闲模式关闭):(262K彩色深度)。b.减少的彩色模式(空闲模式开启):8位彩色深度。
2.整体架构
1.2.2 ILI9341技术分析
在整体时序上,8080-I时序如下:
8080-II时序如下:
1.3 FSMC介绍
其实,在前面的文章中说过,在嵌入式开发中,数字电路最重要的就是时序。那么,为什么ILI9341能适用于使用FSMC来驱动,就是因为FSMC模式下驱动Nor Flash的时序能匹配到ILI9341的8080时序。
同样,因为ILI9341支持SPI驱动方式,所以,如果能达到SPI时序的要求,当然也可以驱动ILI9341了。
由于SPI方式不在讨论范围之内,而且FSMC驱动方式明显比SPI驱动方式有优势。
在STM32上,数据手册P473-P474上有FSMC的说明:
从这里可以看出,CPU访问HADDR,HADDR产生FSMC_A[24:0],所以,对于目前的16-bit的应用来说,我们使用的是HADDR[25:1]这个部分。
按照这个说法,我们访问的格式为:0x6000 0000 + (硬件地址)<<1。目前使用的是FSMC_A16,所以访问的地址为:0x6000 0000 + (1<<16) << 1。
1.4 液晶屏应用
在液晶屏上做开发,其步骤逃不了这么几项事情:
- 画图,例如:点,线,矩形,圆等。
- 显示ASCII,中文等。
- 显示图片。
- 加上UCGUI等,做控件等的显示。
1.4.1 画点,线,矩形,圆等
这部分的内容,是下面几项内容的基础和关键点。
我先说说基本的思路:
1.画点
需要控制液晶(CPU向液晶发送指令),设定该点的起始位置和终点位置,然后向缓存中填充数据即可。
我展示一个基本的代码示例:
LCD_open_windows(12,12,1,1);
LCD_WR_Data(0xffff);
2.画线
画线的原理和画点的原理是一样的。画线就是将一个一个的点拼起来即可。需要注意的就是,在液晶上,可以按照x轴增长方式,也可以按照y轴增长方式来计算下一个点。
3.矩形
这个就没什么好讲的,画四条线就能组成一个矩形了。
4 画圆
画圆的方法可以使用四分法。
1.4.2 显示ASCII,中文等
1 显示ASCII
显示ASCII,只需要一个数组即可,而显示中文,就需要外挂相应的存储设备。
我给出相应的示例性代码,在液晶上显示字符'L',如下:
void draw_font(int x1,int y1)
{
int i,j;
unsigned char *p = ll;
unsigned char c_data;
for(i=y1;i<y1+8;i++)
{
c_data = *p++;
for(j=0;j<8;j++)
{
if((c_data<<j) & 0x80)
{
LCD_open_windows(x1+j,i,1,1);
LCD_WR_Data(0xffff);
}
}
}
}
2 显示中文
暂时不写显示中文。
1.4.3 显示图片等
显示图片,也是需要将图片从存储设备中读取出来,然后放到液晶上即可。内容比较简单,只需要知道图片的存储格式,存储顺序,然后再放到液晶上。
1.4.4 控件显示等
这个就需要添加上ucgui。
1.5 触摸应用
有液晶的显示,移植上ucgui,没有触摸,用起来也是不舒服的。所以这个必须要加上去。
触摸芯片使用的是TSC2046。
1.5.1 TSC2046简介
- 使用的是压力感应
- 3线SPI
1.5.2 MCU与TSC2046硬件接线
管脚 | 作用 |
---|---|
PA5 | SPI1_SCK |
PA7 | SPI1_MOSI |
PA6 | SPI1_MISO |
PB7 | SPI1_CS |
PB6 | INT |
1.5.2 TSC2046控制方法
谈到控制,需要知道通过SPI怎么去操作TSC2046。
列出了上面几张图,就需要对这几张图做相对详细的说明:
首先是BIT7,MSB中的S位:
控制字是以S作为起始,在AD使用12位转换模式中,可以在每15个时钟周期,开始下一个新的控制字。或者AD使用8位转换模式,则可以每11个时钟周期,开始下一个新的控制字。
A2-A0:
这个是通道选择位,可以选择采集x通路还是y通路。这个位是和SER/DFR配合在一起使用的,表示是在差分还是单端模式下采集x或者y的值。
MODE:
这个表示的是AD采用的是12位采样精度还是8位的采样精度,精度不同,则准确度不同。
PD1-PD0:
主要是关于省电的。没有什么好说的。
根据上面的说明,那么可以获取x轴或者y轴的数据:
如果是差分模式下,可以配置:
测量X通道,则为1101 0000 = 0xd0
测量Y通道,则为1001 0000 = 0x90
讲到了这里,就要说明一下触摸屏,对于计算x,y上的缺陷:
- 触摸屏不能保证同一个触摸点,每次采集的数据值都是相同的。
科普一下:
触摸屏有如下4类:
红外线触摸屏、电容型触摸屏、电阻型触摸屏、表面声波触摸屏。
所以,对于触摸屏,需要进行校准。校准方法有三种:两点校准,三点校准,四点校准等。
这里再定义两个概念,分为液晶屏坐标和触摸屏坐标。液晶屏坐标是实际上的像素点的坐标位置,而触摸屏坐标是AD值。
电阻型触摸屏两点校准算法:
- 取触摸屏左上角和右下角的两个点来校准触摸屏。
1)先触摸获取触摸屏左上角的坐标,记为(x1,y1)
2)再触摸获取触摸屏右下角的坐标,记为(x2,y2)
3)计算水平方向的比率k1和垂直方向的比率k2,比率值都是浮点数。k1=(x2-x1)/触摸屏宽度,k2=(y2-y1)/触摸屏高度。
4)计算出当前点的液晶屏(X,Y),X=(x(触摸屏值)-x1)/k1,Y=(y(触摸屏值)-y1)/k2
电阻型触摸屏三点校准算法:
- 如果液晶屏和触摸屏的角度差很小,也就是说它们之间存在线性关系,可以做成如下关系式,液晶坐标为(XL,YL),触摸屏坐标为(X,Y)。
取了三个点做校准,这样就不可避免的需要3*2=6个变量来参与计算:
XL=AX+BY+C,YL=DX+EY+F。
故:
XL1=AX1+BY1+C,XL2=AX2+BY2+C,XL3=AX3+BY3+C
YL1=DY1+EY1+F,YL2=DY2+EY2+F,YL3=DY3+EY3+F
这样就可以计算出A,B,C,D,E,F。
2 使用STM32F429IGT6 RGB LCD驱动
2.1 硬件部分
引脚 | 功能 |
---|---|
DE(数据允许信号) | |
VS | |
HS | |
DCLK | |
PH9 | LCD_R3 |
PH10 | LCD_R4 |
PH11 | LCD_R5 |
PH12 | LCD_R6 |
PG6 | LCD_R7 |
PH13 | LCD_G2 |
PH14 | LCD_G3 |
PH15 | LCD_G4 |
PI0 | LCD_G5 |
PI1 | LCD_G6 |
PI2 | LCD_G7 |
PG11 | LCD_B3 |
PI4 | LCD_B4 |
PI5 | LCD_B5 |
PI6 | LCD_B6 |
PI7 | LCD_B7 |
使用的芯片是原子的ATK-4342-RGBLCD_V1.4 液晶屏。还是要吐个槽,原子的资料里面,并没有标明该屏使用的驱动芯片的名字,还要对照找一篇,让人十分无语。
这是原子提供的资料:
这是在讲解的资料:
所以不对应的内容,没加任何说明。让人确实无奈。
后面看了一些代码,在液晶资料.png上的芯片,属于tft的液晶占大多数。
在链接上找到了一些描述,从而知道id为0x4342的液晶,使用的芯片为GT9147,相关的参数也复制一下,罗列出来:
- 并行24位RGB接口
- 分辨率 480x272
- 颜色深度:最大24位,RGB888,也可以使用RGB565。
- 电容触摸屏
- 最多5点同时触摸
2.2 LTDC介绍
2.2.1 简介
2.2.2 总图
如下为LTDC的功能描述图: