ILI9341 8080接口1

来源:互联网 发布:列主元三角分解法C语言 编辑:程序博客网 时间:2024/06/03 15:55

由图可知,写命令时序由 CSX 信号线拉低开始,D/CX 信号线也置低电平表示写入的
是命令地址(可理解为命令编码,如软件复位命令:0x01),以 WRX 信号线为低,RDX 信
号为高表示数据传输方向为写入,同时,在数据线[17:0]输出命令地址,在第二个传输阶段
传送的为命令的参数,所以 D/CX 要置高电平,表示写入的是命令数据。
当我们需要向 GRAM 写入数据的时候,把 CSX 信号线拉低后,把 D/CX 信号线置为
高电平,这时由 D[17:0]传输的数据则会被 ILI9341 保存至它的 GRAM 中


我们是使用 FSMC 的 NOR\PSRAM 模式控制 LCD


的数据会被 ILI9341 芯片理解为数值;若向 0x6xxx xxx0 、0x6xxx xxx2、0x6xxx xxx4(最低
位都为 0)…这些地址写入数据时,配置好的 FSMC 外设会控制地址线 A0(D/CX)为低电
平,这个写入的数据会被 ILI9341 芯片理解为命令。
有了这个基础,只要我们在代码中利用指针变量,向不同的地址单元写入数据,就能
够由 FSMC 模拟出的 8080 接口向 ILI9341 写入控制命令或 GRAM 的数据了


本实验中用 FSMC 模拟 8080 接口,地址线 A16 提供 8080 的 D/CX 信号,实际上就只
使 用 了 这 一 条 地 址 线 , I\O 资 源 并 不 紧 张 , 所 以 把 本 成 员 配 置 为
FSMC_DataAddressMux_Disable (非复用模式)。


代码清单 9-5Lcd_init_conf()函数
1 /**
2 * @brief 配置 lcd 初始化寄存器
3 * @param 无
4 * @retval 无
5 */
6 void LCD_REG_Config(void)
7 {
8 /* Power control B (CFh) */
9 DEBUG_DELAY();
10 LCD_ILI9341_CMD(0xCF);
11 LCD_ILI9341_Parameter(0x00);
12 LCD_ILI9341_Parameter(0x81);
13 LCD_ILI9341_Parameter(0x30);

14
15 /* Power on sequence control (EDh) */
16 DEBUG_DELAY();
17 LCD_ILI9341_CMD(0xED);
18 LCD_ILI9341_Parameter(0x64);
19 LCD_ILI9341_Parameter(0x03);
20 LCD_ILI9341_Parameter(0x12);
21 LCD_ILI9341_Parameter(0x81);
22
23 /* Driver timing control A (E8h) */
24 DEBUG_DELAY();
25 LCD_ILI9341_CMD(0xE8);
26 LCD_ILI9341_Parameter(0x85);
27 LCD_ILI9341_Parameter(0x10);
28 LCD_ILI9341_Parameter(0x78);
29
30 /* Power control A (CBh) */
31 DEBUG_DELAY();
32 LCD_ILI9341_CMD(0xCB);
33 LCD_ILI9341_Parameter(0x39);
34 LCD_ILI9341_Parameter(0x2C);
35 //......此处省略几十行.......
本函数十分长,由于篇幅问题,以上只是该函数其中的一部分,省略部分的代码也是
这样的模板,只是写入的命令和参数不一样而已,这些命令和参数设置了像素点颜色格
式、屏幕扫描方式、横屏\竖屏等初始化配置,这些命令的意义从 ILI9341 的 datasheet 命令
列 表 中 可 以 查 到 。 该 函 数 通 过 调 用 LCD_ILI9341_CMD() 写 入 命 令 , 用
LCD_ILI9341_Parameter()写入参数。它们实质是两个宏,见代码清单 9-6。
代码清单 9-6LCD_ILI9341_CMD()和 LCD_ILI9341_Parameter()宏
1 /************************************************************************
2 2^26 =0X0400 0000 = 64MB,每个 BANK 有 4*64MB = 256MB
3 64MB:FSMC_Bank1_NORSRAM1:0X6000 0000 ~ 0X63FF FFFF
4 64MB:FSMC_Bank1_NORSRAM2:0X6400 0000 ~ 0X67FF FFFF
5 64MB:FSMC_Bank1_NORSRAM3:0X6800 0000 ~ 0X6BFF FFFF
6 64MB:FSMC_Bank1_NORSRAM4:0X6C00 0000 ~ 0X6FFF FFFF
7
8 选择 BANK1-BORSRAM4 连接 TFT,地址范围为 0X6C00 0000 ~ 0X6FFF FFFF
9 FSMC_A23 接 LCD 的 DC(寄存器/数据选择)脚
10 寄存器基地址 = 0X6C00 0000
11 RAM 基地址 = 0X6D00 0000 = 0X6C00 0000+2^23*2 = 0X6C00 0000 + 0X100 0000 =
0X6D00 0000
12 当选择不同的地址线时,地址要重新计算
13 *******************************************************************/
14
15
16 #define Bank4_LCD_C ((u32)0x6C000000) //Disp Reg ADDR
17 #define Bank4_LCD_D ((u32)0x6D000000) //Disp Data ADDR
18
19 /*选定 LCD 指定寄存器*/
20 #define LCD_WR_REG(index) ((*(__IO u16 *) (Bank4_LCD_C)) =
((u16)index))
21 /*往 LCD GRAM 写入数据*/
22 #define LCD_WR_Data(val) ((*(__IO u16 *) (Bank4_LCD_D)) =
((u16)(val)))
23
24 #define LCD_ILI9341_CMD(index) LCD_WR_REG(index)
25 #define LCD_ILI9341_Parameter(val) LCD_WR_Data(val)
这部分是 FSMC 模拟 8080 接口的精髓。

1.  读写参数、命令
先来看第 22 行的宏,LCD_WR_Data(val),这是一个带参宏,用于向 LCD 控制器写入
参数,参数为 val。它的宏展开为:
1 ((*(__IO u16 *) (Bank4_LCD_D)) = ((u16)(val)))
宏展开中的(Bank4_LCD_D)是一个在第 17 行定义的宏,它的值为 0x6D000000,实质
是一个地址,这个地址的计算在后面介绍。
(__IO u16 *) (Bank4_LCD_D)表示把(Bank4_LCD_D)强制转换成一个 16 位的地址。
((*(__IO u16 *) (Bank4_LCD_D))表示再对这个地址作“*”指针运算,取该指针对象的内
容,并把它的内容赋值为 = ((u16)(val)))。所以整个宏的操作就是:把参数 val 写入到地址
为 0x6D000000 的地址空间。
由于这个地址被 STM32 映射到外存储器,所以会由 FSMC 外设以访问 NOR FLASH
的形式、时序,在地址线上发出 0x6D000000 地址信号,在数据线上发出 val 数据信号,写
入参数到外存储器中。而 FSMC 接口又被我们模拟成了 8080 接口,最终 val 被 8080 接口
理解为参数,传输到 ILI9341 控制器中。
2.  计算地址
见图 9-9。计算地址前,再明确一下在本实验中,使用的是 FSMC_NE4 作为 8080_CS
片选信号,以 FSMC_A23 作为 8080_D/CX 数据/命令信号(图中为 RS,意义相同)。


按这种连接时,FSMC_NE4 为低电平、FSMC_A23 为高电平,表示通过 D[15:0]发送\
接收的数据被 8080 接口解释为参数(数值),当我们访问 0x6D000000 这个地址的时候,正
好符合这个条件。该地址的计算过程如下:
由于选择的是使用 FSMC_NE4 片选信号线,片选的为 BANK4,所以基地址为 0x6C00
0000。要把地址线 FSMC_A23 置为高电平,可以采用下列算式:
1. 0x6C00 0000 |= 1<<23; //结果 = 0x6C80 0000


但是,这样计算出来的地址只是数据线为 8Bit 模式下的字节地址。由于我们采用的是
16Bit 数据线,FSMC[24:0]与 HADDR[25:1]对齐,HADDR 地址要左移一位才是 FSMC 的
访问地址。因此为了把 FSMC 中的 FSMC_A16 (D/CX 线)置 1,实际上要对应到 HADDR 地
址(AHB 地址)的 HADDR_A24,即正确的计算地址公式应为:
1. 0x6C00 0000 |= 1<<(23+1); //此为正确结果 = 0x6D00 0000
对于 16 位数据线模式,能使 FSMC_NEX 为低电平,FSMC_A23 为高电平的地址,并
不只有 0x6D00 0000 一个,只要是属于 0x6C000000~0x6FFFFFFF 范围内(BANK4 地址范
围),HADDR_A24 位为高电平的地址均可,这是因为我们只采用了 FSMC_A23 用于 8080
的 D/CX 信号,所以地址线的电平状态并无影响。如 0x6D00 0001 地址,在本实验中是与
0x6D00 0000 等价的。
若修改这个地址,使 FSMC_NEX 为低电平,FSMC_A23 为低电平,即 D/CX 被置 0,
8080 会把由数据线传输的信号理解为命令。以同样的方式计算,符合这样要求的其中一个
地址为 0x6C00 0000 ,向这个地址空间赋值,这个值最终会被 8080 接口解释为命令。本程
序中用来向 LCD 写入命令的宏 LCD_WR_REG(index) 就是这样实现的。

0 0