====>>> 文章汇总(有代码汇总) <<<====
本章节会采用两种不同的方式驱动LCD屏。
第一种:FSMC接口
所用开发板:普中-准瑞-Z100 STM32F103开发板,主控STM32F103ZET6。
第二种:软件模拟 8080通信协议
所用开发板:正点原子Mini开发板,主控STM32F103RCT6。
所用显示屏:正点原子 2.8英寸 TFTLCD屏。
8080 并行接口由 INTEL 发明,被广泛应用于各类液晶显示器。
该接口可以选择 8位 或 16位数据线通信。
如果选择 8位数据线通信,则需要以下信号线,一共 13根线:
如果选择 16位数据线通信,则需要以下信号线,一共 21根线:
8080 并口 读 / 写的过程为:
时序图(8位和16为除了数据位数不一样,其他的都一样)
这里LCD采用的存储芯片是 ILI9341 液晶控制器,自带显存,其显存总大小为 172800 字节(240 * 320 * 18 / 8)
。
但实际上,我们采用的是 16位
模式,在该模式下, ILI9341 采用 RGB565
格式存储颜色数据,此时 ILI9341 的 18 位数据线与 MCU 的 16 位数据线以及 LCD GRAM 的对应关系如图:
9341总线 | D17 | D16 | D15 | D14 | D13 | D12 | D11 | D10 | D9 | D8 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
MCU数据线(16位) | D15 | D14 | D13 | D12 | D11 | NC | D10 | D9 | D8 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | NC |
LCD GRAM(16位) | R[4] | R[3] | R[2] | R[1] | R[0] | NC | G[5] | G[4] | G[3] | G[2] | G[1] | G[0] | B[4] | B[3] | B[2] | B[1] | B[0] | NC |
可以看出,对于 ILI9341 芯片来说,有用的数据线是:D17-D13 和 D11-D1。但是,把有用的16根数据线引出来之后,刚好可以对应到 D0-D15。
然后看 LCD模块 的原理图。
不管模块的内部结构,直接看这个引出来的引脚(红框中间的标号),最下面的29-34号引脚是触摸屏相关的,这里先不管:
BL_VDD是电源输入,BL的输入电压大小决定亮度,可以用PWM控制,也可以直接输入高电平拉满即可。
注意:这里方框中间的标号,是以上面表格中MCU的数据位进行标注的。可以按照上面的表格对应到 ILI9341 芯片上。
简单来说用的是8080通信接口,不算RESET线的话,一共需要21根线。其他的内部原理不重要。
指令(简单看几个,了解了解意思就行,不用深究,挺多的也记不住):
FSMC(Flexible Static Memory Controller,可变静态存储控制器):是STM32系列采用的一种新型的存储器扩展技术。能够与同步或异步存储器和 16 位 PC 存储器卡连接。在外部存储器扩展方面具有独特的优势,可根据系统的应用需要,方便地进行不同类型大容量静态存储器的扩展。
一般引脚数大于100的芯片才会有 FSMC 接口。
FSMC框图
可以看出,STM32 的 FSMC 将外部设备分为 3 类:
他们共用地址数据总线等信号,他们具有不同的 CS 以区分不同的设备。也可以将TFTLCD 当成 SRAM 来控制,实现LCD显示的效果。
STM32 的 FSMC 将外部存储器划分为固定大小为 256M 字节的四个存储块,共有1G。
选择开发板上对应的主控即可。
ZET6 有 FSMC接口,可以使用FSMC进行驱动,软件模拟8080接口也行(但是何必呢)。
RCT6 没有 FSMC接口的,只能使用软件模拟8080接口。
配置时钟源
配置debug模式(如果需要ST-Link下载及调试可以勾选)
配置时钟树(可以直接在HCLK那里输入72,然后敲回车会自动配置)
再看一下LCD引出的引脚的原理图,里面的标号已经说过了。
外面的标号是开发板上插座的 Label,对应到主控相应的接口引脚。
背光引脚设置,直接保持高电平即可,也可以配置为PWM调节亮度。
生成工程。
在工程目录添加 icode
文件夹,在文件夹中创建LCD
文件夹,在文件夹中创建lcd.c
、lcd.h
、font.h
三个文件。
全部的代码文件在文章开头
添加源文件
添加头文件路径
全部的代码文件在文章开头
#include "lcd.h"
// 其他的初始化完成之后
LCD_Init();
POINT_COLOR = RED; // 画笔颜色
LCD_ShowString(0, 0, 120, 20, 24, "Haozi");
LCD_ShowNum(0, 24, 1234567, 7, 24);
LCD_ShowChar(0, 48, 'A', 24, 0);
LCD_Draw_Circle(100, 100, 20);
LCD_DrawRectangle(80, 80, 40, 40);
LCD_DrawLine(60, 60, 70, 70);
全部的代码文件在文章开头
针对没有配备 FSMC 的主控,就只能采用软件模拟的方式进行驱动了。
看一下正点原子手册LCD的原理图,在官方手册上,方框中间的标号是对应到 ILI9341 控制器上的标号。
但是我们不看这个,和上面保持一致,我把原理图重新画一下。
然后我们看看每个引脚都接到哪了,这里不管触摸功能,和上一章节一样,只需要看1-28号引脚,最下面的六个是 触摸功能有关的,先不管。
然后在CubeMX中配置这些引脚。PB0 - PB15、PC6 - PC10.
全部都是 推挽输出,上拉,输出速度High。
一共21个引脚。
在工程目录添加 icode
文件夹,在文件夹中创建LCD
文件夹,在文件夹中创建lcd.c
、lcd.h
、font.h
三个文件。
并在keil中添加.c文件和头文件。
其实,这里的驱动和上面的驱动,在对外的接口上基本都是一样的,只是函数内传输数据的实现方式不一样。
全部的代码文件在文章开头
测试程序和上面的一样。
#include "lcd.h"
// 其他的初始化完成之后
LCD_Init();
POINT_COLOR = RED; // 画笔颜色
LCD_ShowString(0, 0, 120, 20, 24, "Haozi");
LCD_ShowNum(0, 24, 1234567, 7, 24);
LCD_ShowChar(0, 48, 'A', 24, 0);
LCD_Draw_Circle(100, 100, 20);
LCD_DrawRectangle(80, 80, 40, 40);
LCD_DrawLine(60, 60, 70, 70);
全部的代码文件在文章开头
经过更改,两种驱动方式的工程,只有 lcd.c 和 lcd.h 中函数的内部实现不一样,不管你采用哪种驱动方式,在其他程序中调用的接口是一样一样的。
比如,在8080模拟驱动的程序中,写寄存器函数是这样的。
而在,FSMC驱动的代码中是这样的。
可以看到,函数名称是一样的,可以用相同的方式进行调用。其余的函数也都是一样的。
因此,在移植的时候也不用想太多,都可以一样的用。
最后,后面会用这个LCD屏做一个简易的示波器项目,只需要一个开发板,和这个LCD屏即可实现,
代码也开源,欢迎去主页置顶文章中查看。