这里写目录标题

  • 一、TFT简介
    • 1.显存
    • 2.指令
      • 3.常用指令
        • 1.读 ID4 指令
        • 2.存储访问控制指令
        • 3.列地址设置指令
        • 4.页地址设置指令
        • 5.写 GRAM 指令
        • 6.读 GRAM 指令
    • 3.一般使用流程
  • 二、FSMC简介
    • 1.SRAM与TFTLCD的关系
      • 注意
    • 2.FSMC的存储控制
    • 3.STM32 的 FSMC 各 Bank 配置寄存器
    • 4.使用异步模式 A(ModeA)方式来控制 TFTLCD
  • 三、寄存器
    • 1.RAM/NOR闪存片选控制寄存器
      • 1.EXTMOD
      • 2.WREN
      • 3.MWID[1:0]
      • 4.MTYP[1:0]
      • 5.MBKEN
    • 2.SRAM/NOR 闪存片选时序寄存器
      • 1.ACCMOD[1:0]
      • 2.DATAST[7:0]
      • 3.ADDSET[3:0]
    • 3.SRAM/NOR 闪写时序寄存器
    • 4.注意
  • 四、函数说明
    • 1.FSMC 初始化函数
      • 1.FSMC_NORSRAMInit
        • 1.FSMC_Bank
        • 2.FSMC_MemoryType
        • 3.FSMC_MemoryDataWidth
        • 4.FSMC_WriteOperation
        • 5.FSMC_ExtendedMode
        • 6.FSMC_DataAddressMux
        • 7.FSMC_NORSRAMTimingInitTypeDef
        • 8.其他参数
    • 2.FSMC 使能函数

一、TFT简介

TFTLCD 彩屏的数据量都比较大,故采用 16 位(DBx)的并方式与外部连接,尤其在显示图片的时候,如果用 8 位数据线,就会比 16 位方式慢一倍以上。

该模块的 80 并口有如下一些信号线:CS:TFTLCD 片选信号。WR:向 TFTLCD 写入数据。RD:从 TFTLCD 读取数据。D[15:0]:16 位双向数据线。RST:硬复位 TFTLCD。RS:命令/数据标志(0,读写命令;1,读写数据)。

1.显存

ILI9341 液晶控制器自带显存,其显存总大小为 172800(24032018/8),即 18 位模式(26万色)下的显存量。
在 16 位模式下,ILI9341 采用 RGB565 格式存储颜色数据,此时 ILI9341的 18 位数据线与 MCU 的 16 位数据线以及 LCD GRAM 的对应关系如下图所示:
最低 5 位代表蓝色,中间 6 位为绿色,最高 5 位为红色。数值越大,表示该颜色越深。

2.指令

特别注意 ILI9341 所有的指令都是 8 位的(高 8 位无效),且参数除了读写 GRAM 的时候是 16 位,其他操作参数,都是 8 位的。

3.常用指令

0XD3,0X36,0X2A,0X2B,0X2C,0X2E。

1.读 ID4 指令

指令:0XD3
读 ID4 指令,用于读取 LCD 控制器的 ID:
0XD3 指令后面跟了 4 个参数,最后 2 个参数,若读出来是 0X93 和 0X41,则是控制器为 ILI9341 的数字部分。

通过该指令,即可判别所用的 LCD 驱动器是什么型号,这样就可以根据控制器的型号去执行对应驱动 IC 的初始化代码,从而兼容不同驱动 IC 的屏,使得一个代码支持多款 LCD。

2.存储访问控制指令

指令:0X36
存储访问控制指令,可以控制 ILI9341 存储器的读写方向,简单的说,就是在连续写 GRAM 的时候,可以控制 GRAM 指针的增长方向,从而控制显示方式。
0X36 指令后面,紧跟一个参数。
通过设置MY、MX、MV这三个位(高三位)的设置,我们可以控制整个 ILI9341 的全部扫描方向。

如要显示 BMP 图片:

BMP 解码数据,就是从图片的左下角开始,慢慢显示到右上角,
如果设置 LCD 扫描方向为从左到右,从下到上,那么我们只需要设置一次坐标,
然后就不停的往 LCD 填充颜色数据即可,这样可以大大提高显示速度。

3.列地址设置指令

指令:0X2A
列地址设置指令,在从左到右,从上到下的扫描方式(默认)下面,该指令用于设置横坐标(x 坐标):

在默认扫描方式时,该指令用于设置 x 坐标,该指令带有 4 个参数,实际上是 2 个坐标值:SC 和 EC,即列地址的起始值和结束值,SC 必须小于等于 EC,且 0≤SC/EC≤239。
一般在设置 x 坐标的时候,我们只需要带 2 个参数即可,也就是设置 SC 即可,因为如果 EC 没有变化,我们只需要设置一次即可(在初始化 ILI9341 的时候设置),从而提高速度。

4.页地址设置指令

指令:0X2B
页地址设置指令,在从左到右,从上到下的扫描方式(默认)下面,该指令用于设置纵坐标(y 坐标):
用于设置 y 坐标,该指令带有 4 个参数,实际上是 2 个坐标值:SP 和 EP,即页地址的起始值和结束值,SP 必须小于等于 EP,且 0≤SP/EP≤319。
一般在设置y 坐标的时候,我们只需要带 2 个参数即可,也就是设置 SP 即可,因为如果 EP 没有变化,我们只需要设置一次即可(在初始化 ILI9341 的时候设置),从而提高速度。

5.写 GRAM 指令

指令:0X2C
写 GRAM 指令,在发送该指令之后,我们便可以往 LCD的 GRAM 里面写入颜色数据了,该指令支持连续写

在收到指令 0X2C 之后,数据有效位宽变为 16 位,我们可以连续写入 LCD GRAM 值,而 GRAM 的地址将根据 MY/MX/MV 设置的扫描方向进行自增。
例如:

假设设置的是从左到右,从上到下的扫描方式,
那么设置好起始坐标(通过 SC,SP 设置)后,每写入一个颜色值,
GRAM 地址将会自动自增 1(SC++),如果碰到 EC,则回到 SC,
同时 SP++,一直到坐标:EC,EP 结束,其间无需再次设置的坐标,
从而大大提高写入速度。

6.读 GRAM 指令

指令:0X2E
读 GRAM 指令,用于读取 ILI9341 的显存(GRAM)。

3.一般使用流程

二、FSMC简介

FSMC,即灵活的静态存储控制器,能够与同步或异步存储器和 16 位 PC 存储器卡连接,STM32 的 FSMC 接口支持包括 SRAM、NAND FLASH、NOR FLASH 和 PSRAM 等存储器。

FSMC框图:

STM32 的 FSMC 将外部设备分为 3 类:NOR/PSRAM 设备、NAND设备、PC 卡设备。
他们共用地址数据总线等信号,他们具有不同的 CS 以区分不同的设备,比如我们用到的 TFTLCD 就是用的 FSMC_NE4 做片选,其实就是将 TFTLCD 当成 SRAM 来控制。

1.SRAM与TFTLCD的关系

外部 SRAM 的控制一般有:

地址线(如 A0~A18)、
数据线(如 D0~D15)、
写信号(WE)、
读信号(OE)、
片选信号(CS)。
如果 SRAM 支持字节控制,那么还有 UB/LB 信号。

TFTLCD的信号包括:

RS:命令/数据标志(0,读写命令;1,读写数据)、
D[15:0]:16 位双向数据线、
WR:向 TFTLCD 写入数据、
RD:从 TFTLCD 读取数据、
CS:TFTLCD 片选信号、
RST:硬复位 TFTLCD、
BL:背光 等。

其中真正在操作 LCD 的时候需要用到的就只有:RS、D0~D15、WR、RD 和 CS。

其操作时序和 SRAM的控制完全类似,唯一不同就是 TFTLCD 有 RS 信号,但是没有地址信号。
TFTLCD 通过 RS 信号来决定传送的数据是数据还是命令,本质上可以理解为一个地址信号
把 RS 接在 A0 上面,那么当 FSMC 控制器写地址 0 的时候,会使得 A0 变为 0,对 TFTLCD 来说,就是写命令。而 FSMC 写地址 1 的时候,A0 将会变为 1,对 TFTLCD 来说,就是写数据了。这样,就把数据和命令区分开了,他们其实就是对应 SRAM 操作的两个连续地址。当然 RS 也可以接在其他地址线上,精英 STM32 开发板是把 RS 连接在 A10 上面的。

注意


LCD_BASE,必须根据我们外部电路的连接来确定,我们使用 Bank1.sector4 就是从地址 0X6C000000 开始,而 0X000007FE,则是 A10(2^10) 的偏移量(STM32内部地址右移一位后A10的当前地址就是0x800)。将这个地址强制转换为LCD_TypeDef 结构体地址
那么可以得到 LCD->LCD_REG 的地址就是 0X6C00,07FE,对应A10 的状态为 0(即 RS=0):

而 LCD-> LCD_RAM 的地址就是 0X6C00,0800(结构体地址自增),对应 A10 的状态为 1(即 RS=1):

所以,有了这个定义,当我们要往 LCD 写命令/数据的时候,可以这样写:

而读的时候反过来操作就可以了,如下所示:

这其中,CS、WR、RD 和 IO 口方向都是由 FSMC 控制,不需要我们手动设置了。

2.FSMC的存储控制

STM32 的 FSMC 支持 8/16/32 位数据宽度。
FSMC 的外部设备地址映像,STM32 的 FSMC将外部存储器划分为固定大小为 256M 字节的四个存储块:

FSMC 总共管理 1GB 空间(1024=4*256MB),拥有 4 个存储块(Bank)。

STM32 的 FSMC 存储块 1(Bank1)被分为 4 个区,每个区管理 64M 字节空间,每个区都有独立的寄存器对所连接的存储器进行配置。

Bank1 的 256M 字节空间由 28 根地址线(HADDR[27:0])寻址。
HADDR 是内部 AHB 地址总线,其中HADDR[25:0]来自外部存储器地址FSMC_A[25:0],而 HADDR[26:27]对 4 个区进行寻址。



注意HADDR[25:0]的对应关系:

当 Bank1 接的是 16 位宽度存储器的时候:HADDR[25:1]→ FSMC_A[24:0]。
当 Bank1 接的是 8 位宽度存储器的时候:HADDR[25:0]→ FSMC_A[25:0]。

FSMC_A[0]永远接在外部设备地址 A[0]。
TFTLCD使用的是 16 位数据宽度,所以 HADDR[0]并没有用到,只有 HADDR[25:1]是有效的,对应关系变为:HADDR[25:1]→ FSMC_A[24:0],相当于右移了一位

3.STM32 的 FSMC 各 Bank 配置寄存器


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

1,HCLK 与 FSMC_CLK 的分频系数(CLKDIV),可以为 2~16 分频;
2,同步突发访问中获得第 1 个数据所需要的等待延迟(DATLAT)。

异步突发访问方式,FSMC 主要设置 3 个时间参数:

地址建立时间(ADDSET)、
数据建立时间(DATAST)、
地址保持时间(ADDHLD)。


在实际扩展时,根据选用存储器的特征确定时序模型,从而确定各时间参数与存储器 读/写 周期参数指标之间的计算关系;利用该计算关系和存储芯片数据手册中给定的参数指标,可计算出 FSMC 所需要的各时间参数,从而对时间参数寄存器进行合理的配置。

4.使用异步模式 A(ModeA)方式来控制 TFTLCD

模式A读操作时序图:

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

模式A写操作时序图:

从模式 A 的读写时序图,可以看出,读操作还存在额外的 2 个 HCLK 周期,用于数据存储,所以同样的配置读操作一般比写操作会慢一点。

三、寄存器

1.RAM/NOR闪存片选控制寄存器

FSMC_BCRx(x=1~4):

1.EXTMOD

扩展模式使能位,也就是 是否允许读写不同的时序。
若需要读写不同的时序,则该位需要设置为 1。

2.WREN

写使能位。
若需要向 TFTLCD 写数据,则该位必须设置为 1。

3.MWID[1:0]

存储器数据总线宽度。00,表示 8 位数据模式;01 表示 16 位数据模式;10和 11 保留。
若使用的是 16 位数据线,则应该设置 WMID[1:0]=01。

4.MTYP[1:0]

存储器类型。00 表示 SRAM、ROM;01 表示 PSRAM;10 表示 NOR FLASH;11保留。
前面提到,我们把 TFTLCD 当成 SRAM 用,所以需要设置 MTYP[1:0]=00。

5.MBKEN

存储块使能位。
需要用该存储块控制 TFTLCD,就要使能这个存储块。

2.SRAM/NOR 闪存片选时序寄存器

FSMC_BTRx(x=1~4):

这个寄存器包含了每个存储器块的控制信息,可以用于 SRAM、ROM 和 NOR 闪存存储器。
如果 FSMC_BCRx 寄存器中设置了 EXTMOD 位,则有两个时序寄存器分别对应读(本寄存器)写操作(FSMC_BWTRx 寄存器)。因为我们要求读写分开时序控制,所以 EXTMOD 是使能了的,也就是本寄存器是读操作时序寄存器,控制读操作的相关时序。

1.ACCMOD[1:0]

访问模式。00 表示访问模式 A;01 表示访问模式 B;10 表示访问模式 C;11 表示访问模式 D,我们用到模式 A,故设置为 00。

2.DATAST[7:0]

数据保持时间。0 为保留设置,其他设置则代表保持时间为: DATAST 个HCLK 时钟周期,最大为 255 个 HCLK 周期。对 ILI9341 来说,其实就是 RD 低电平持续时间,一般为 355ns。而一个 HCLK 时钟周期为 13.8ns 左右(1/72Mhz),为了兼容其他屏,我们这里设置 DATAST 为 15,也就是 16 个 HCLK 周期,时间大约是 234ns(未计算数据存储的 2 个 HCLK时间,对 9341 来说超频了,但是实际上是可以正常使用的)。

3.ADDSET[3:0]

地址建立时间。其建立时间为:ADDSET 个 HCLK 周期,最大为 15 个 HCLK周期。对 ILI9341 来说,这里相当于 RD 高电平持续时间,为 90ns,本来这里我们应该设置和DATAST 一样,但是由于 STM32F103 FSMC 的性能问题,就算设置 ADDSET 为 0,RD 的高电平持续时间也达到了 190ns 以上,所以,我们这里可以设置 ADDSET 为较小的值,我们设置 ADDSET 为 1,即 2 个 HCLK 周期,实际 RD 高电平大于 200ns。

3.SRAM/NOR 闪写时序寄存器

FSMC_BWTRx(x=1~4):

该寄存器用作写操作时序控制寄存器。
需要用到的设置同样是:ACCMOD、DATAST和 ADDSET 这三个设置。这三个设置的方法同 FSMC_BTRx 一模一样。
ACCMOD 设置同 FSMC_BTRx 一模一样,同样是选择模式 A,另外 DATAST 和ADDSET 则对应低电平和高电平持续时间,对 ILI9341 来说,这两个时间只需要 15ns 就够了,比读操作快得多。所以我们这里设置 DATAST 为 3,即 4 个 HCLK 周期,时间约为 55ns(因为9320 等控制器,这个时间要求比较长,要 50ns)。然后 ADDSET(也存在性能问题)设置为 0, 即 1 个 HCLK 周期,实际 WR 高电平时间大于 100ns。

4.注意

在 MDK 的寄存器定义里面,并没有定义 FSMC_BCRx、FSMC_BTRx、FSMC_BWTRx 等这个单独的寄存器,而是将他们进行了一些组合。FSMC_BCRx 和 FSMC_BTRx,组合成 BTCR[8]寄存器组。

四、函数说明

1.FSMC 初始化函数

FSMC 对不同的存储器类型同样提供了不同的初始化函数:

这三个函数分别用来初始化 4 种类型存储器。

1.FSMC_NORSRAMInit

void FSMC_NORSRAMInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct);

前面有 13 个基本类型(unit32_t)的成员变量,这 13 个参数是用来配置片选控制寄存器 FSMC_BCRx。
SMC_NORSRAMTimingInitTypeDef 指针类型的成员变量,用来设置读时序和写时序的参数(用来配置寄存器 FSMC_BTRx 和 FSMC_BWTRx)。

模式 A下的相关配置参数:

1.FSMC_Bank

设置使用到的存储块标号和区号,我们是使用的存储块 1 区 号 4,所以选择值为 FSMC_Bank1_NORSRAM4。

2.FSMC_MemoryType

设置存储器类型,我们这里是 SRAM,所以选择值为FSMC_MemoryType_SRAM。

3.FSMC_MemoryDataWidth

设置数据宽度,可选 8 位还是 16 位,这里我们是 16 位数据宽度,所以选择值为 FSMC_MemoryDataWidth_16b。

4.FSMC_WriteOperation

设置写使能.
我们要向 TFT 写数据,所以要写使能,选择 FSMC_WriteOperation_Enable。

5.FSMC_ExtendedMode

设置扩展模式使能位,也就是是否允许读写不同的时序,这里我们采取的读写不同时序,所以设置值为 FSMC_ExtendedMode_Enable。

6.FSMC_DataAddressMux

设置地址/数据复用使能,若设置为使能,那么地址的低 16位和数据将共用数据总线,仅对 NOR 和 PSRAM 有效,所以我们设置为默认值不复用,值FSMC_DataAddressMux_Disable。

7.FSMC_NORSRAMTimingInitTypeDef

FSMC_ReadWriteTimingStruct 和FSMC_WriteTimingStruct分别用来初始化片选控制寄存器 FSMC_BTRx 和写操作时序控制寄存器 FSMC_BWTRx。

有7 个参数用来设置 FSMC 读写时序。
主要是设计地址建立保持时间,数据建立时间等等配置,在TFT_LCD的配置中,读写时序不一样,读写速度要求不一样,所以对于参数 FSMC_DataSetupTime 设置了不同的值。

8.其他参数

FSMC_BurstAccessMode , FSMC_AsynchronousWait , FSMC_WaitSignalPolarity ,FSMC_WaitSignalActive , FSMC_WrapMode , FSMC_WaitSignal FSMC_WriteBurst 和FSMC_WaitSignal 这些参数在成组模式同步模式才需要设置。

2.FSMC 使能函数

FSMC 对不同的存储器类型同样提供了不同的使能函数:

如我们使用的:

FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE);  // 使能BANK1

基于stm32f1(正点原子)的tft_lcd(ILI9341)学习相关推荐

  1. 正点原子 linux 开发板学习 uboot 篇 一

    源码选择 出厂可以直接使用 原子出厂源码, 出厂源码会随时修复bug或者添加新的驱动以兼容正点原子的其他模块 学习的时候 U-Boot 烧写与启动 uboot 启动位置根据拨码开关 烧写 通过.imx ...

  2. 正点原子imx6ullUBOOT顶层Makefile学习笔记

    跟据正点原子的linux开发板手册与视频学习了uboot的顶层makefile工作流程. 一.准备阶段 $(MAKE) -C subdir:调用subdir目录下的makefile文件,make支持递 ...

  3. 正点原子 Linux驱动开发学习笔记-06 chrdevbase虚拟设备驱动的完善

    要求:应用程序可以对驱动进行读写操作. 读:从驱动读一个字符串 写:应用程序向驱动写一个字符串 驱动的缓冲,与应用程序的读写buffer都是100. 1. read驱动函数编写,需要用到copy_to ...

  4. 正点原子STM32F103精英版学习笔记(二)

    #使用ST-LINK下载调试程序 **应用场景:**如果工程的代码比较大,难免存在bug,就需要硬件调试解决 ST-LINK 和STM32F103都支持JTAG 和SWD,用JTAG调试时占用的IO线 ...

  5. 正点原子minifly学习

    对正点原子的开发板学习已经好几个月了,暂且了解了一点freertos和stm32的一些知识.本着从项目入手的原则,从今天开始,对正点原子小四轴无人机minifly进行学习. ** 目录** minif ...

  6. 基于正点原子STM32F1精英版秒表(库函数版)

    基于正点原子STM32F1精英版秒表(库函数版) 一.前期准备 二.代码实现: 1.独立按键与触摸按键 2.TFTLCD 3.定时器 4.蜂鸣器与LED灯 5.主函数设计 三. 结束语: 一.前期准备 ...

  7. STM32学习笔记——基于正点原子例程编码器模式小结

    STM32学习笔记--基于正点原子例程编码器模式小结 最近一段时间学习了,STM32f4的编码器功能,经过自己探索和他人的热心帮助,对于编码器模式有了一定了解.STM32f4单片机提供编码器模式,以便 ...

  8. stm32f407 6路串口dma如何配置_stm32cubeMX学习十、扫码模块程序开发(基于正点原子STM32F407开发板)...

    本程序编写基于正点原子STM32F407开发板. 本文使用的扫码模块是下面这个品牌. 扫码模块的应用场景非常广泛,我们可以上百度搜索一下: 等等. 今天就来说说如何在开发板上实现控制它吧,打开数据手册 ...

  9. 正点原子STM32(基于HAL库)5

    目录 SRAM 实验 存储器简介 SRAM 方案简介 硬件设计 程序设计 程序流程图 程序解析 下载验证 内存管理实验 内存管理简介 硬件设计 程序设计 程序流程图 程序解析 下载验证 SD 卡实验 ...

  10. 正点原子STM32(基于HAL库)3

    目录 高级定时器实验 高级定时器简介 高级定时器输出指定个数PWM 实验 高级定时器输出指定个数PWM原理 TIM1/TIM8 寄存器 硬件设计 课堂源码(输出指定个数PWM灯就闪几次) 程序设计 下 ...

最新文章

  1. RxPermissions的简单应用
  2. 指针,引用之间的关系
  3. 怎么测并发 PHP,PHP接口并发测试的方法(推荐)
  4. Nhibernate和 Entity Framework 4优缺点
  5. SQLServer数据库文件相关知识笔记
  6. [剑指offer][JAVA]面试题第[32-2]题[从上到下打印二叉树][BFS]
  7. flinksql写入hudi 踩坑实录
  8. 【AD】如何删除AD20右下角Title
  9. 编写python代码估算sin(x)的值
  10. 0505.Net基础班第二十天(基础加强总复习)
  11. php 读取js文件,JS中如何读取文件
  12. 车机没有carlife可以自己下载吗_安卓车机CarPlay模块初体验
  13. 软件开发人员的简历项目经验怎么写
  14. 微信公众号文章排版php,微信内容排版工具总结
  15. java拯救公主_Java实现 计蒜客 拯救行动
  16. android fresco 流程,Android Fresco 笔记
  17. 如何用计算机巧记英语词汇,小学英语单词巧记法
  18. 第6章 详细设计(软件工程导论 第6版)
  19. SQL查询cross join 的用法(笛卡尔积)
  20. 2D游戏知识点二、Unity 2D游戏主角基本功能和动画

热门文章

  1. AVX指令集函数列表中文翻译
  2. 网络变压器 原理、功能、解决辐射发射问题的应用
  3. FP6195耐压60V电流降压3.3V5V模块供电方案
  4. word/wps分页
  5. webOffice 常用的一些API以及其他操作
  6. 使用BigInteger.setBit与BigInteger.testBit来实现权限控制
  7. java 下载速度_java下载速度慢啊!!
  8. HIVE——常用sql命令总结
  9. win10 汇编工具 em8086安装
  10. Hololens 开发笔记(10)——World Anchor