当前位置: 首页 > news >正文

12.LCD、FSMC和ILI9341芯片

目录

LCD 屏幕讲解 

常见的输入输出设备

        常见的 LCD 输出设备 

        常见的触摸屏输入设备 

LCD 屏幕的作用

LCD 屏幕简介

显示器的名词参数

常见 LCD 屏幕的构成

液晶显示器的控制信号线 -- RGB 接口

显存

液晶屏控制芯片—ILI9341--显卡芯片

ILI9341 接口的选择

液晶屏的信号线及 8080 时序 

        8080 的写命令和写数据

        8080 的写命令和读数据

        ILI9341 的命令

如何实现 8080 接口

FSMC 模拟 8080 时序信号

FSMC 的介绍--灵活的静态存储器控制器

FSMC 的作用—拓展单片机存储空间

FSMC 的地址映射

FSMC 如何模拟 8080 时序

FSMC 的初始化

LCD 屏幕代码实现

实现封装颜色字节

实现显示

        显示点 

        显示字符 

        显示中文

        显示图片 


LCD 屏幕讲解 

常见的输入输出设备

        显示屏和触摸屏是两个独立的屏幕 

        常见的 LCD 输出设备 

                LED 灯 广告点阵屏 LCD 屏(1602 12864 TFT) OLED 屏 串口屏 

                显示屏:是一种显示设备,输出设备 

        常见的触摸屏输入设备 

                触摸屏:输入设备,包括电阻屏和电容屏 

                电阻屏:通过压力使上下导电层接触,电流变化确定位置。用指甲盖点的那种 

                电容屏:利用人体电场形成耦合电容,通过电流变化定位触摸点。现在手机屏幕 

LCD 屏幕的作用

        显示设备:给我们提供信息 

LCD 屏幕简介

        液晶显示器,简称 LCD(Liquid Crystal Display),相对于上一代 CRT 显示器(阴极射线管显示器), LCD 显示器具有功耗低、体积小、承载的信息量大及不伤眼的优点,因而它成为了现在的主流电子显示设备,其中包括电视、电脑显示器、手机屏幕及各种嵌入式设备的显示器。液晶是一种介于固体和液体之间的特殊物质,它是一种有机化合物,常态下呈液态,但是它的分子排列却和固体晶体一样非常规则,因此取名液晶。 如果给液晶施加电场,会改变它的分子排列, 从而改变光线的传播方向, 配合偏振光片,它就具有控制光线透过率的作用,再配合彩色滤光片,改变加给液晶电压大小,就能改变某一颜色透光量的多少。 利用这种原理,做出可控红、绿、蓝光输出强度的显示结构,把三种显示结构组成一个显示单位,通过控制红绿蓝的强度,可以使该单位混合输出不同的色彩,这样的一个显示单位被称为像素。 

显示器的名词参数

        像素:像素是组成图像的最基本单元要素,显示器的像素指它成像最小的点,即一个显示单元。 

        分辨率:一些嵌入式设备的显示器常常以“行像素值 x 列像素值”表示屏幕的分辨率。如分辨率 800x480 表示该显示器的每一行有 800 个像素点,每一列有 480 个像素点,也可理解为有 800 列, 480 行

        色彩深度:色彩深度指显示器的每个像素点能表示多少种颜色,一般用“位” (bit)来表示。如单色屏的每个像素点能表示亮或灭两种状态(即实际上能显示 2 种颜色),用 1 个数据位就可以表示像素点的所有状态,所以它的色彩深度为 1bit,其它常见的显示屏色深为 16bit、 24bit。

        三原色: RGB 红绿蓝 这三种颜色可以组合出来任意颜色 

        16 位色彩深度:RGB565 可以表示 2^16 种颜色 

                每个像素点的颜色信息,需要用 16 位 也就是两个字节来表示 

                假如显示屏分辨率: 240*320 

                表示所有像素点信息:240*320*2 字节 

        24 位色彩深度:RGB888 可以表示 2^24 种颜色 

                每个像素点的颜色信息,需要用 24 位 也就是三个字节来表示 

                假如显示屏分辨率: 240*320 

                表示所有像素点信息: 240*320*3 字节 

        16 位和 24 位色彩深度,都叫做真彩色。 

        显示器尺寸:显示器的大小一般以英寸表示,如 5 英寸、 21 英寸、 24 英寸等,这个长度是指屏幕对角线的长度, 通过显示器的对角线长度及长宽比可确定显示器的实际长宽尺寸。 

        点距:点距指两个相邻像素点之间的距离, 它会影响画质的细腻度及观看距离,相同尺寸的屏幕,若分辨率越高,则点距越小,画质越细腻。如现在有些手机的屏幕分辨率比电脑显示器的还大,这是手机屏幕点距小的原因; LED 点阵显示屏的点距一般都比较大,所以适合远距离观看。

常见 LCD 屏幕的构成

        显示屏由液晶显示面板以及 PCB 底板构成。 

        图中的触摸面板带有触摸控制芯片,该芯片处理触摸信号并通过引出的信号线与外部器件通讯,触摸面板中间是透明的,它贴在液晶面板上面,一起构成屏幕的主体,触摸面板与液晶面板引出的排线连接到 PCB 底板上,根据实际需要,PCB 底板上可能会带有“液晶控制器芯片”,因为控制液晶面板需要比较多的资源,所以大部分低级微控制器都不能直接控制液晶面板,需要额外配套一个专用液晶控制器来处理显示过程,外部微控制器只要把它希望显示的数据直接交给液晶控制器即可。而不带液晶控制器的 PCB 底板,只有小部分的电源管理电路,液晶面板的信号线与外部微控制器相连,直接控制。

        有些芯片不需要额外的液晶控制器,也就是说芯片把专用液晶控制器的功能集成到内部了,可以理解为电脑的 CPU 集成显卡,它节约了额外的控制器成本。而 STM32F1 系列的芯片由于没有集成液晶控制器到芯片内部,所以它只能驱动自带控制器的屏幕,可以理解为电脑的外置显卡。

液晶显示器的控制信号线 -- RGB 接口

        已实现RGB接口和屏幕通信

液晶面板的控制信号线液晶面板引出的 FPC 排线,液晶面板通过这些信号线与液晶控制器通讯,使用这种通讯信号的被称为 RGB 接口(RGB Interface)。

        RGB 信号线:RGB 信号线各有 8 根,分别用于表示液晶屏一个像素点的红、绿、蓝颜色分量。使用红绿蓝颜色分量来表示颜色是一种通用的做法。常见的颜色表示会在“RGB”后面附带各个颜色分量值的数据位数,如RGB565 表示红绿蓝的数据线数分别为 5、 6、 5 根,一共为 16 个数据位,可表示 2^16 种颜色;而有些液晶屏的种颜色分量的数据线都有 8 根,所以它支持 RGB888 格式,一共 24 位数据线,可表示的颜色为 2^24种。

        同步时钟信号 CLK:液晶屏与外部使用同步通讯方式,以 CLK 信号作为同步时钟,在同步时钟的驱动下,每个时钟传输一个像素点数据。

        水平同步信号 HSYNC:水平同步信号 HSYNC(Horizontal Sync)用于表示液晶屏一行像素数据的传输结束,每传输完成液晶屏的一行像素数据时, HSYNC 会发生电平跳变,如分辨率为 800x480 的显示屏(800 列, 480行),传输一帧的图像 HSYNC 的电平会跳变 480 次。

        垂直同步信号 VSYNC:垂直同步信号 VSYNC(Vertical Sync)用于表示液晶屏一帧像素数据的传输结束,每传输完成一帧像素数据时, VSYNC 会发生电平跳变。其中“帧”是图像的单位,一幅图像称为一帧,在液晶屏中,一帧指一个完整屏液晶像素点。人们常常用“帧/秒”来表示液晶屏的刷新特性,即液晶屏每秒可以显示多少帧图像,如液晶屏以 60 帧/秒的速率运行时, VSYNC 每秒钟电平会跳变 60 次。

        数据使能信号 DE:数据使能信号 DE(Data Enable)用于表示数据的有效性,当 DE 信号线为高电平时,RGB信号线表示的数据有效。

显存

        电脑上独立显卡的大小

        液晶屏中的每个像素点都是数据,在实际应用中需要把每个像素点的数据缓存起来,再传输给液晶屏,一般会使用 SRAM 或 SDRAM 性质的存储器,而这些专门用于存储显示数据的存储器, 则被称为显存。显存一般至少要能存储液晶屏的一帧显示数据,如分辨率为 800x480 的 液 晶 屏 , 使 用 RGB888 格 式 显 示 , 它的 一 帧 显 示 数 据 大 小 为 :3x800x480=1152000 字 节 ; 若 使 用 RGB565 格 式 显 示 ,一 帧 显示 数 据 大 小 为 :2x800x480=768000 字节。        

        RGB565 分辨率 240*320

        显存大小:240*320*2=153600 字节

        显存放在 ILI9341 中 

液晶屏控制芯片—ILI9341--显卡芯片

        ILI9341 一端和单片机通信 另一端和液晶面板通信(RGB 接口) 

        液晶屏内部包含有一个液晶控制芯片 ILI9341。该芯片最主核心部分是位于中间的 GRAM(Graphics RAM),它就是显存。 GRAM 中每个存储单元都对应着液晶面板的一个像素点。它右侧的各种模块共同作用把 GRAM存储单元的数据转化成液晶面板的控制信号,使像素点呈现特定的颜色,而像素点组合起来则成为一幅完整的图像。 

             框图的左上角为 ILI9341 的主要控制信号线和配置引脚,根据其不同状态设置可以使芯片工作在不同的模式,如每个像素点的位数是 6、 16 还是 18 位;可配置使用 SPI 接口、8080 接口还是 RGB 接口与 MCU 进行通讯。 MCU 通过 SPI、 8080 接口或 RGB 接口与 ILI9341 进行通讯,从而访问它的控制寄存器(CR)、地址计数器(AC)、及 GRAM。在 GRAM 的左侧还有一个 LED 控制器(LED Controller)。 LCD 为非发光性的显示装置,它需要借助背光源才能达到显示功能, LED 控制器就是用来控制液晶屏中的 LED 背光源。 

ILI9341 接口的选择

        STM32 和 ILI9341(液晶控制器)去通信,ILI9341 的通信接口有 SPI/8080,通过 IM[3:0]的引脚高低电平,选择模式,选择 8080 接口,实现 STM32 和 ILI9341 的通信(出厂已经决定了使用8080)

        8080 接口和 SPI 接口的对比:8080 接口速度比较块,SPI 接口相对就比较慢 

        8080:并口协议,传输比较快,但是占空 IO 口太多 

        SPI:串行协议,传输比较慢,占用 IO 口比较少 

        如何确定用的哪个接口: 

液晶屏的信号线及 8080 时序 

        8080 接口一头是 STM32,一头是 ILI9341 

        ILI9341 控制器根据自身的 IM[3:0]信号线电平决定它与 MCU 的通讯方式,它本身支持 SPI 及 8080 通讯方式,液晶屏的 ILI9341 控制器在出厂前就已经按固定配置好(内部已连接硬件电路),它被配置为通过 8080接口通讯,使用 16 根数据线的 RGB565 格式。内部硬件电路连接完,剩下的其它信号线被引出到 FPC 排线,最后该排线由 PCB 底板引出到排针,排针再与实验板上的 STM32 芯片连接。

这些信号线即 8080 通讯接口,带 X 的表示低电平有效, STM32 通过该接口与 ILI9341 芯片进行通讯,实现对液晶屏的控制。通讯的内容主要包括命令和显存数据,显存数据即各个像素点的 RGB565 内容;命令是指对 ILI9341 的控制指令, MCU 可通过 8080 接口发送命令编码控制 ILI9341 的工作方式,例如复位指令、设置光标指令、睡眠模式指令等等,具体的指令在数据手册均有详细说明。

        上面图片数据流向写命令(蓝色)和写数据(黄色) -- STM32-->ILI9341 

        HOST:STM32 LCD: ILI9341 

        由图可知,写命令时序由片选信号 CSX 拉低开始,对数据/命令选择信号线 D/CX 也置低电平表示写入的是命令地址(可理解为命令编码,如软件复位命令: 0x01),以写信号 WRX 为低(方向:HOST→LCD),读信号RDX 为高表示数据传输方向为写入,同时,在数据线 D[17:0](或 D[15:0])输出命令地址,在第二个传输阶段传送的是命令的参数,所以 D/CX 要置高电平,表示写入的是命令数据,命令数据是某些指令带有的参数,如复位指令编码为 0x01,它后面可以带一个参数,该参数表示多少秒后复位(实际的复位命令不含参数,此处只是为了讲解指令编码与参数的区别)。当需要把像素数据写入 GRAM(ILI9341) 时,过程很类似,把片选信号 CSX 拉低后,再把数据/命令选择信号线 D/CX 置为高电平,这时由 D[17:0]传输的数据则会被 ILI9341 保存至它的 GRAM 中。写命令 写数据 读数据

        8080 的写命令和写数据

        8080 的写命令和读数据

        ILI9341 的命令

        用到比较多的命令 

        设置像素点颜色信息 

        读ID 

        扫描方向

如何实现 8080 接口

        通过 GPIO 口模拟出来 8080 时序,过程复杂,通过示波器或者逻辑分析仪查看波形,类似于我们使用的模拟 SPI 和模拟 IIC 和单总线

        FSMC 外拓 SRAM 的功能,可以模拟出来 8080 时序,实现驱动 ILI9341 -- 用这种方案 

                FSMC 是用来外拓存储的,把 ILI9341 这个显存芯片,当做 RAM 来外拓 

                前提条件: 

                        确定单片机是否有 FSMC 这个功能,STM32F103RCT6 没有 FSMC 

                        F4 系列叫做 FMC

FSMC 模拟 8080 时序信号

FSMC 的介绍--灵活的静态存储器控制器

FSMC 的作用—拓展单片机存储空间

        STM32 控制器芯片内部有一定大小的 SRAM 及 FLASH 作为内存和程序存储空间,但当程序较大,内存和程序空间不足时,就需要在 STM32 芯片的外部扩展存储器了。扩展内存时一般使用 SRAM 和 SDRAM 存储器,但 STM32F1 系列的芯片不支持扩展 SDRAM(最新的一些系列芯片支持),它仅支持使用 FSMC 外设扩展 SRAM,我们以 SRAM 为例讲解如何为 STM32 扩展内存。给 STM32 芯片扩展内存与给 PC 扩展内存的原理是一样的,只是 PC 上一般以内存条的形式扩展,内存条实质是由多个内存颗粒(即 SDRAM 芯片)组成的通用标准模块,而 STM32 直接与 SRAM 芯片连接。

 

        STM32F1 系列芯片使用 FSMC 外设来管理扩展的存储器, FSMC 是 Flexible Static Memory Controller 的缩写,译为灵活的静态存储控制器。它可以用于驱动包括 SRAM、NOR FLASH 以及 NAND FLSAH 类型的存储器,不能驱动如 SDRAM 这种动态的存储器。 

在框图的右侧是 FSMC 外设相关的控制引脚,由于控制不同类型存储器的时候会有一些不同的引脚,看起来有非常多, 其中地址线 FSMC_A 和数据线 FSMC_D 是所有控制器都共用的。

        比较特殊的 FSMC_NE 是用于控制 SRAM 芯片的片选控制信号线, STM32 具有 FSMC_NE1/2/3/4号引脚,不同的引脚对应 STM32 内部不同的地址区域。例如,当 STM32 访问 0x68000000-0x6BFFFFFF 地址空间时, FSMC_NE3 引脚会自动设置为低电平,由于它连接到 SRAM 的 CE#引脚,所以 SRAM 的片选被使能, 而访问 0x60000000-0x63FFFFFF 地址时, FSMC_NE1 会输出低电平。当使用不同的 FSMC_NE 引脚连接外部存储器时,STM32 访问 SRAM 的地址不一样,从而达到控制多块 SRAM 芯片的目的。

FSMC 的地址映射

        FSMC 连接好外部的存储器并初始化后,就可以直接通过访问地址来读写数据,而使用 FSMC 外接存储器时,其存储单元是映射到 STM32 的内部寻址空间的;在程序里,定义一个指向这些地址的指针然后就可以通过指针直接修改该存储单元的内容, FSMC 外设会自动完成数据访问过程,读写命令之类的操作不需要程序控制。

所谓的访问指什么?

        读:Bank1 的第 4 块 0x6C000000 -- 0x6FFFFFFF FSMC_NE4 低电平 

                Uint32 date; 

                Date=*(uint32 *)0x6C00 0000; 

                0x6C00 0000 0x6C00 0001 0x6C00 0002 0x6C00 0003 4 个地址中的内容 

 

        写:Bank1 的第 4 块 

                Uint32 date=0x12345678; 

                *(uint32 *)0x6C00 0000=date; 

                0x6C00 0000 0x6C00 0001 0x6C00 0002 0x6C00 0003 4 个地址中的内容更改了 

        FSMC 把整个 External RAM 存储区域分成了 4 个 Bank 区域, 并分配了地址范围及适用的存储器类型,如 NOR 及 SRAM 存储器只能使用 Bank1 的地址。 在每个 Bank 的内部又分成了 4 个小块,每个小块有相应的控制引脚用于连接片选信号,如 FSMC_NE[4:1]信号线可用于选择 BANK1 内部的 4 小块地址区域,当STM32 访问 0x68000000-0x6BFFFFFF 地址空间时, 会访问到 Bank1 的第 3 小块区域,相应的 FSMC_NE3信号线会输出控制信号。

FSMC 如何模拟 8080 时序

        对于 NOR FLASH 控制器,主要是通过 FSMC_BCRx、 FSMC_BTRx 和 FSMC_BWTRx 寄存器设置(其中 x=1~4,对应 4 个区)。 通过这 3 个寄存器, 可以设置 FSMC 访问外部存储器的时序参数,拓宽了可选用的外部存储器的速度范围。 FSMC 的 NOR FLASH 控制器支持同步和异步突发两种访问方式。选用同步突发访问方式时, FSMC 将 HCLK(系统时钟)分频后,发送给外部存储器作为同步时钟信号 FSMC_CLK。此时需要的设置的时间参数有 2 个:

        1,HCLK 与 FSMC_CLK 的分频系数(CLKDIV),可以为 2~16 分频; 

        2,同步突发访问中获得第 1 个数据所需要的等待延迟(DATLAT)。对于异步突发访问方式,FSMC 主要设置 3 个时间参数:地址建立时间(ADDSET)、数据建立时间(DATAST)和地址保持时间(ADDHLD)。 FSMC 综合了 SRAM/ ROM、 PSRAM 和 NOR Flash 产品的信号特点,定义了 4 种不同的异步时序模型。 选用不同的时序模型时,需要设置不同的时序参数,如表所列:

        我们使用异步模式 A(ModeA)方式来控制 TFTLCD(ILI9341),模式 A 支持独立的读写时序控制,这个对我们驱动 TFTLCD 来说非常有用,因为 TFTLCD 在读的时候,一般比较慢,而在写的时候可以比较快,如果读写用一样的时序,那么只能以读的时序为基准,从而导致写的速度变慢,或者在读数据的时候,重新配置FSMC 的延时,在读操作完成的时候,再配置回写的时序,这样虽然也会降低写的速度,但是频繁配置,比较麻烦。而如果有独立的读写时序控制,那么我们只要初始化的时候配置好,之后就不用再配置,既可以满足速度要求,又不需要频繁改配置。

        模式 A 的读操作时序如图 

        模式 A 的写操作时序如图

        D/CX 随便从 A[25:0]地址线中选择一根,硬件已经决定选择的是 A10 

FSMC 的初始化

        初始化 FSMC 主要是初始化三个寄存器 FSMC_BCRx, FSMC_BTRx,FSMC_BWTRx,固件库提供了 3个 FSMC 初始化函数分别为 FSMC_NORSRAMInit();FSMC_NANDInit();FSMC_PCCARDInit();这三个函数分别用来初始化 4 种类型存储器。这里根据名字就很好判断对应关系。 用来初始化 NOR 和 SRAM 使用同一个函数 FSMC_NORSRAMInit()。所以我们之后使用的 FSMC 初始化函数为 FSMC_NORSRAMInit()。

        控制 FSMC 使用 SRAM 存储器时主要是配置时序寄存器以及控制寄存器,利用 ST 标准库的 SRAM 时序结构体以及初始化结构体可以很方便地写入参数

        这个结构体成员定义的都是 SRAM 读写时序中的各项时间参数,这些成员的参数都与 FSMC_BRT 及FSMC_BWTR 寄存器配置对应,各个成员介绍如下: 

        FSMC_AddressSetupTime:本成员设置地址建立时间,即 FSMC 读写时序图 27-9 中的 ADDSET 值, 它可以被设置为 0-0xF 个 HCLK 周期数,按 STM32 标准库的默认配置, HCLK 的时钟频率为 72MHz,即一个HCLK 周期为 1/72 微秒。

        FSMC_AddressHoldTime:本成员设置地址保持时间,它可以被设置为 0-0xF 个 HCLK 周期数。 

        FSMC_DataSetupTime:本成员设置数据建立时间,即 FSMC 读写时序图 27-10 中的 DATAST 值,它可以被设置为 0-0xF 个 HCLK 周期数。

        FSMC_BusTurnAroundDuration:本成员设置总线转换周期,在 NOR FLASH 存储器中,地址线与数据线可以分时复用,总线转换周期就是指总线在这两种状态间切换需要的延时,防止冲突。控制其它存储器时这个参数无效,配置为 0 即可。

        FSMC_CLKDivision:本成员用于设置时钟分频,它以 HCLK 时钟作为输入,经过 FSMC_CLKDivision 分频后输出到 FSMC_CLK 引脚作为通讯使用的同步时钟。 控制其它异步通讯的存储器时这个参数无效,配置为0 即可。

        FSMC_DataLatency:本成员设置数据保持时间,它表示在读取第一个数据之前要等待的周期数,该周期指同步时钟的周期,本参数仅用于同步 NOR FLASH 类型的存储器,控制其它类型的存储器时,本参数无效。

        FSMC_AccessMode:本成员设置存储器访问模式,不同的模式下 FSMC 访问存储器地址时引脚输出的时序不一样,可选 FSMC_AccessMode_A/B/C/D 模式。一般来说控制 SRAM 时使用 A 模式。

        FSMC 的 SRAM 初始化结构体 

        这个结构体,除最后两个成员是上一小节讲解的时序配置外,其它结构体成员的配置都对应到 FSMC_BCR中的寄存器位。各个成员意义介绍如下,括号中的是 STM32 标准库定义的宏:

     FSMC_Bank:本成员用于选择 FSMC 映射的存储区域,它的可选参数以及相应的内核地址映射范围如下: 

   

        FSMC_DataAddressMux : 本 成 员 用 于 设 置 地 址 线 与 数 据 总 线 是 否 复 用(FSMC_DataAddressMux_Enable/Disable),在控制 NOR FLASH 时,可以地址总线与数据总线可以分时复用,以减少使用 STM32 信号线的数量。

        FSMC_MemoryType:本成员用于设置要控制的存储器类型,它支持控制的存储器类型为 SRAM、 PSRAM以及 NOR FLASH(FSMC_MemoryType_SRAM/PSRAM/NOR)。

        FSMC_MemoryDataWidth:本成员用于设置要控制的存储器的数据宽度,可选择设置成 8 或 16 位(FSMC_MemoryDataWidth_8b /16b)。

        FSMC_BurstAccessMode:本成员用于设置是否使用突发访问模式(FSMC_BurstAccessMode_Enable/Disable),突发访问模式是指发送一个地址后连续访问多个数据,非突发模式下每访问一个数据都需要输入一个地址,仅在控制同步类型的存储器时才能使用突发模式。

        FSMC_AsynchronousWait : 本 成 员 用 于 设 置 是 否 使 能 在 同 步 传 输 时 使 用 的 等 待 信 号(FSMC_AsynchronousWait_Enable/Disable) ,在控制同步类型的 NOR 或 PSRAM 时 , 存储 器 可以 使 用FSMC_NWAIT 引脚通知 STM32 需要等待。

        FSMC_WaitSignalPolarity:本成员用于设置等待信号的有效极性,即要求等待时,使用高电平还是低电平(FSMC_WaitSignalPolarity_High/Low)。

        FSMC_WrapMode : 本成员 用 于 设置 是否 支 持把 非 对 齐的 AHB 突 发操 作 分 割成 2 次 线 性操 作(FSMC_WrapMode_Enable/Disable),该配置仅在突发模式下有效。

        FSMC_WaitSignalActive:本成员用于配置在突发传输模式时,决定存储器是在等待状态之前的一个数据周期有效还是在等待状态期间有效(FSMC_WaitSignalActive_BeforeWaitState/DuringWaitState)。

        FSMC_WriteOperation:这个成员用于设置是否写使能(FSMC_WriteOperation_ Enable /Disable),禁止写使能的话 FSMC 只能从存储器中读取数据,不能写入。

        FSMC_WaitSignal:本成员用于设置当存储器处于突发传输模式时,是否允许通过 NWAIT 信号插入等待状态(FSMC_WaitSignal_Enable/Disable)。

        FSMC_ExtendedMode:本成员用于设置是否使用扩展模式(FSMC_ExtendedMode_Enable/Disable),在非扩展模式下,对存储器读写的时序都只使用 FSMC_BCR 寄存器中的配置,即下面的 FSMC_ReadWriteTimingStruct结构体成员;在扩展模式下,对存储器的读写时序可以分开配置,读时序使用 FSMC_BCR 寄存器,写时序使用FSMC_BWTR 寄存器的配置,即下面的 FSMC_WriteTimingStruct 结构体。

        FSMC_ReadWriteTimingStruct : 本 成 员 是 一 个 指 针 , 赋 值 时 使 用 上 面 讲 解 的 时 序 结 构 体FSMC_NORSRAMInitTypeDef 设置,当不使用扩展模式时,读写时序都使用本成员的参数配置。

        FSMC_WriteTimingStruct:同样地,本成员也是一个时序结构体的指针,只有当使用扩展模式时,本配置才有效,它是写操作使用的时序。

        对本结构体赋值完成后,调用 FSMC_NORSRAMInit 库函数即可把配置参数写入到 FSMC_BCR 及FSMC_BTR/BWTR 寄存器中。 

LCD 屏幕代码实现

        1. 初始化 IO 

                FSMC 是片上外设,只要是需要 FSMC 自动调节的全部为 复用

                LCD_BL 背光 配置成通用推挽输出

        2. 配置 FSMC – SRAM 

                FSMC 外拓 SRAM 的时序和 8080 时序类似,所以使用 FSMC 来模拟 8080 时序 

        3. 封装出来发送命令,发送数据,读取数据的函数接口 

                我们操作的是个屏幕,地址没有实际意义 

                但是 FSMC_A10 这个引脚有意义 D/CX(RS) 

                结合硬件原理图查看,屏幕接在 NE4 所控制的区域,0x6C00 0000--0x6FFF FFFF,FSMC_A10 作为数据命令选择线

        只要符合 FSMC_A10 输出 1、或者0,NE4 会自动选中地址

 

        详细解释为啥要 HADDR 和 FSMC_A 要错一位接 

        HADDR :指单片机存储器映射到那个地址 0x6c000000 

        FSMC_A: 指 FSMC 外设的地址线的地址 

        HADDR -- 0x6C00 0000    0110 1100 0000 0000 0000 0000 0000 0000 

        FSMC_A[25:0]                   0110 1100 0000 0000 0000 0000 0000 000 

        传输 16 位

        发送第一次 0x6C00 000 -- 0x6C00 0001 

                HADDR--0110 1100 0000 0000 0000 0000 0000 0000--二进制 

                HADDR--0110 1100 0000 0000 0000 0000 0000 0001--二进制 

        发送第二次 0x6C00 0002-0x6C00 0003 

                HADDR--0110 1100 0000 0000 0000 0000 0000 0010--二进制 

                HADDR--0110 1100 0000 0000 0000 0000 0000 0011--二进制 

        发送第三次 0x6C00 0004-0x6C00 0005 

                HADDR--0110 1100 0000 0000 0000 0000 0000 0100--二进制 

                HADDR--0110 1100 0000 0000 0000 0000 0000 0101--二进制 

        16bit 数据宽度 FSMC_A10 --- HADDR_A11 高电平 -- 发送数据 

        发送数据 D/CX(RS) 高电平 

                0x6Cxx xxxx 随便 HADDR 地址的第 11bit 为 1 的地址都可以,比如发 0x6666 数据

                (*(uint16_t *)0x6C00 0800) = 0x6666; 

                0x6C00 0800=0b(0110 1100 0000 0000 0000 1000 0000 0000) 红色 1 所在的是                 HADDR_A11,FSMC_A10 

        发送命令: D/CX(RS) 低电平

                0x6Cxxx xxxx 随便 HADDR 地址的第 11bit 为 0 的地址都可以,比如说发 0x0001 命令 

                (*(uint16_t *)0x6C00 0000) = 0x0001; 

                0x6C00 0000=0b(0110 1100 0000 0000 0000 0000 0000 0000) 红色 0 所在的是                 HADDR_A11,FSMC_A10

void LCD_SendDATA(uint16_t data)
{(*(uint16_t *)0x6C000800) = data;
}
void LCD_SendCMD(uint16_t cmd)
{(*(uint16_t *)0x6C000000) = cmd;
}

        4. 可以通过读 ID,验证通信是否成功 

        5. 实现屏幕的初始化和开背光 

                屏幕初始化需要调用厂家的代码 

                其中就有设置扫描方向 

        6. 封装出来画点的函数 

                显示原理—设置一个区域然后逐个像素点的发送色彩 

                2A -- 设置开始列 和 结束列 

                2B 设置开始行 结束行 

                2C 写数据指令

                循环发送对应的颜色数据 

        7. 封装显示汉字,显示字符,显示数字,显示图片等函数接口

实现封装颜色字节

红 77 0100 1101

绿 29 0001 1101

蓝 99 0110 0011

RGB565 0100 1000 1110 1100

RGB888 0100 1101 0001 1101 0110 0011 

实现显示

        显示点 

LCD_Init();
/*画点 1 屏幕分辨率 240*320
参数 1 横坐标
参数 2 纵坐标
*/
LCD_DrawPoint(10,10);
/*画点 2 屏幕分辨率 240*320
参数 1 横坐标
参数 2 纵坐标
参数 3 颜色信息
*/
LCD_Fast_DrawPoint(20,20,ZS);

        显示字符 

显示字符 ASCALL:显示字符等符号的时候,需要用单个像素点的描绘,然后按照符号的模型,依次描点,就能显示一个符号借助 字符取模软件 

/*显示字符串 屏幕分辨率 240*320
参数 1 横坐标
参数 2 纵坐标
参数 3 显示区域的宽
参数 4 显示区域的高
参数 5 待显示的字符大小 支持 12 16 24
参数 6 待显示的字符串
*/
LCD_ShowString(0,25,100,16,16,(u8 *)"Hello");

        显示中文

                对于不带字库的显示屏:需要自己取字模

                对于带字库的显示屏:不需要单独取模 

        1. 打开字库取模软件 

        2. 设置取模方式 -- 跟程序保持一致

        3. 设置字体的大小和类型 

        4. 生成要输入字模的内容,将上图选中的内容赋值到 lcd.c 代码中,需要修改两个地方 

        6. 程序中调用显示汉字的函数 

/*显示中文 屏幕分辨率 240*320
参数 1 横坐标
参数 2 纵坐标
参数 3 背景颜色
参数 4 字体颜色
参数 5 待显示的汉字大小 支持 16
参数 6 待显示的中文字符串
*/
LCD_ShowChineseStr(0,45,RED,BLACK,"学习STM32");

        显示图片 

        1. 打开图片取模工具 

        2. 按顺序打开文件并设置 

        3. 保存文件

        4. 生成的文件添加到工程路径并添加到工程中

        5. Main.h 文件声明数组

extern const unsigned char gImage_pic[12482];

        6. Main.c 文件调用图片显示函数  

/*显示图片 屏幕分辨率 240*320
参数 1 横坐标
参数 2 纵坐标
参数 3 图片宽度 和上述图片取模软件截图的第 6 步宽度保持一致
参数 4 图片高度 和上述图片取模软件截图的第 6 步高度保持一致
参数 5 待显示图片的字模首地址
*/
LCD_ShowPhoto(0,65,240,180,(uint8_t *)gImage_pic);

                                                   

相关文章:

  • GitLab-CI简介
  • 深入理解 JavaScript 面向对象编程与 Class
  • git子模块--常见操作
  • c++学习之---stack,queue
  • iOS App启动优化(冷启动、热启动)
  • uni-app学习笔记十二-vue3中创建组件
  • Python实战:轻松连接与高效操作Elasticsearch
  • 【大模型应用开发】Qwen2.5-VL-3B识别视频
  • 解决WPF短暂的白色闪烁(白色闪屏)
  • 免费开源 PDF 阅读器 自带虚拟打印机功能 多格式兼容
  • Acrobat 中 JavaScript 为 PDF 带来的交互
  • Java21 并发处理说明
  • 通过Auto平台与VScode搭建远程开发环境(以Stable Diffusion Web UI为例)
  • 【Python】1. 基础语法(1)
  • 棒球比赛暗号百科·棒球1号位
  • 在Mathematica中,使用鸟枪法求解在无穷远处的边值常微分方程
  • AI助力,制作视频裁剪软件
  • Spring Cloud Sleuth与Zipkin深度整合指南:微服务链路追踪实战
  • 大剧院订座系统源码,大剧院订票,大剧院场馆租赁,大剧院订票系统完整源码
  • Day 31 训练
  • 沂源网站开发/互动营销案例
  • 黑龙江省住房和建设厅网站首页/艾滋病阻断药
  • 网站的在线支付模块怎么做/中国联通和腾讯
  • 网站开发和c语言/上海seo排名
  • 服务器多少钱/优化防疫政策
  • 官方静态网站模板/seo作弊