-第 2 页-
0、 友情提示
《零死角玩转 STM32》系列教程由初级篇、中级篇、高级篇、系统篇、
四个部分组成,根据野火 STM32 开发板旧版教程升级而来,且经过重新深入编
写,重新排版,更适合初学者,步步为营,从入门到精通,从裸奔到系统,让
您零死角玩转 STM32。M3 的世界,与野火同行,乐意惬无边。
另外,野火团队历时一年精心打造的《STM32 库开发实战指南》将于今
年 10 月份由机械工业出版社出版,该书的排版更适于纸质书本阅读以及更有利
于查阅资料。内容上会给你带来更多的惊喜。是一本学习 STM32 必备的工具
书。敬请期待!
-第 3 页-
4、液晶触摸画板
4.1 实验简介
本实验向大家介绍如何使用 STM32 的 FSMC 接口驱动 LCD 屏,及使用触
摸屏控制器检测触点坐标。
4.2 LCD 控制器简介
LCD,即液晶显示器,因为其功耗低、体积小,承载的信息量大,因而被
广泛用于信息输出、与用户进行交互,目前仍是各种电子显示设备的主流。
因为 STM32 内部没有集成专用的液晶屏和触摸屏的控制接口,所以在显示
面板中应自带含有这些驱动芯片的驱动电路(液晶屏和触摸屏的驱动电路是独立
的),STM32 芯片通过驱动芯片来控制液晶屏和触摸屏。以野火 3.2 寸液晶屏
(240*320)为例,它使用 ILI9341 芯片控制液晶屏,通过 TSC2046 芯片控制触
摸屏。
4.2.1 ILI9341 控制器结构
液晶屏的控制芯片内部结构非常复杂,见错误!未找到引用源。。最主要
的是位于中间 GRAM(Graphics RAM),可以理解为显存。GRAM 中每个存储单
元都对应着液晶面板的一个像素点。它右侧的各种模块共同作用把 GRAM 存储
单元的数据转化成液晶面板的控制信号,使像素点呈现特定的颜色,而像素点
组合起来则成为一幅完整的图像。
框图的左上角为 ILI9341 的主要控制信号线和配置引脚,根据其不同状态
设置可以使芯片工作在不同的模式,如每个像素点的位数是 6、16 还是 18
位;使用 SPI 接口还是 8080 接口与 MCU 进行通讯;使用 8080 接口的哪种模
式。MUC 通过 SPI 或 8080 接口与 ILI9341 进行通讯,从而访问它的控制寄存
器(CR)、地址计数器(AC)、及 GRAM。
-第 4 页-
在 GRAM 的左侧还有一个 LED 控制器(LED Controller)。LCD 为非发光性的
显示装置,它需要借助背光源才能达到显示功能,LED 控制器就是用来控制液
晶屏中的 LED 背光源。
图 0-1 ILI9341 控制器内部框图
4.2.2 像素点的数据格式
图像数据的像素点由红(R)、绿(G)、蓝(B)三原色组成,三原色根据其深浅
程度被分为 0~255 个级别,它们按不同比例的混合可以得出各种色彩。如 R:
255,G255,B255 混合后为白色。根据描述像素点数据的长度,主要分为 8、
16、24 及 32 位。如以 8 位来描述的像素点可表示 28=256 色,16 位描述的为
-第 5 页-
216=65536 色,称为真彩色,也称为 64K 色。实际上受人眼对颜色的识别能力
的限制, 16 位色与 12 位色已经难以分辨了。
ILI9341 最高能够控制 18 位的 LCD,但为了数据传输简便,我们采用它的
16 位控制模式,以 16 位描述的像素点。按照标准格式,16 位的像素点的三原
色描述的位数为 R:G:B =5:6:5,描述绿色的位数较多是因为人眼对绿色
更为敏感。16 位的像素点格式见图 0-2。
图 0-2 16 位像素点格式
图中的是默认 18 条数据线时,像素点三原色的分配状况,D1~D5 为蓝色,
D6~D11 为绿色,D13~D17 为红色。这样分配有 D0 和 D12 位是无效的。若使
用 16 根数据线传送像素点的数据,则 D0~D4 为蓝色,D5~D10 为绿色,
D11~D15 为红色,使得刚好使用完整的 16 位。
RGB 比例为 5:6:5 是一个十分通用的颜色标准,在 GRAM 相应的地址中填
入该颜色的编码,即可控制 LCD 输出该颜色的像素点。如黑色的编码为
0x0000,白色的编码为 0xffff,红色为 0xf800。
4.2.3 ILI9341 的通讯时序
目前,大多数的液晶控制器都使用 8080 或 6800 接口与 MCU 进行通讯,
它们的时序十分相似,野火以 ILI9341 使用的 8080 通讯时序进行分析,实际上
ILI9341 也可以使用 SPI 接口来控制。
ILI9341 的 8080 接口有 5 条基本的控制信号线:
1. 用于片选的 CSX 信号线;
2. 用于写使能的 WRX 信号线;
3. 用于读使能的 RDX 信号线;
4. 用于区分数据和命令的 D/CX 信号线;
5. 用于复位的 RESX 信号线。
-第 6 页-
其中带 X 的表示低电平有效。除了控制信号,还有数据信号线,它的数目
不定,可根据 ILI9341 框图中的 IM[3:0]来设定,这部分一般由制作液晶屏的厂
家完成。为便于传输像素点数据,野火使用的液晶屏设定为 16 条数据线
D[15:0]。使用 8080 接口的写命令时序图见错误!未找到引用源。。
图 0-3 使用 18 条数据线的 8080 接口写命令时序
由图可知,写命令时序由 CSX 信号线拉低开始,D/CX 信号线也置低电平
表示写入的是命令地址(可理解为命令编码,如软件复位命令:0x01),以 WRX
信号线为低,RDX 信号为高表示数据传输方向为写入,同时,在数据线[17:0]
输出命令地址,在第地二个传输阶段传送的为命令的参数,所以 D/CX 要置高
电平,表示写入的是命令数据。
当我们需要向 GRAM 写入数据的时候,把 CSX 信号线拉低后,把 D/CX 信
号线置为高电平,这时由 D[17:0]传输的数据则会被 ILI9341 保存至它的 GRAM
中。
4.3 用 STM32 驱动 LCD
ILI9341 的 8080 通讯接口时序可以由 STM32 使用普通 I/O 接口进行模
拟,但这样效率较低,它提供了一种特别的控制方法——使用 FSMC 接口。
-第 7 页-
FSMC 简介
FSMC(flexible static memory controller),译为静态存储控制器。可用于
STM32 芯片控制 NOR FLASH、PSRAM、和 NAND FLASH 存储芯片。其结构见
图 0-4。
图 0-4 FSMC 结构图
我们是使用 FSMC 的 NOR\PSRAM 模式控制 LCD,所以我们重点分析框图
中 NOR FLASH 控制信号线部分。控制 NOR FLASH 主要使用到如下信号线:
-第 8 页-
图 0-5 FSMC 控制 NOR FLASH 的信号线
根据 STM32 对寻址空间的地址映射,见前面的错误!未找到引用源。,地
址 0x6000 0000 ~0x9FFF FFFF 是映射到外部存储器的,而其中的 0x6000
0000 ~0x6FFF FFFF 则是分配给 NOR FLASH、PSRAM 这类可直接寻址的器
件。当 FSMC 外设被配置为正常工作,并且外部接了 NOR FLASH,这时若向
0x60000000 地址写入数据 0xffff,FSMC 会自动在各信号线上产生相应的电平
信号,写入数据。该过程的时序图见图 0-6。
图 0-6 FSMC 写 NOR 时序图
它会控制片选信号 NE[X]选择相应的某块 NOR 芯片,然后使用地址线
A[25:0]输出 0x60000000,在 NEW 写使能信号线上发出写使能信号,而要写
与 8080 类
似的信号线
D/CX
CSX
RDX
WRX
D[15:0]
-第 9 页-
入的数据信号 0xffff 则从数据线 D[15:0]输出,然后数据就被保存到 NOR
FLASH 中了。
用 FSMC 模拟 8080 时序
在图 0-6 的时序图中 NADV 信号是在地址、信号线复用时作为锁存信号
的,在此,我们略它。然后读者会发现,这个 FSMC 写 NOR 时序是跟 8080 接
口的时序(见图 0-3)是十分相似的,对它们的信号线对比如下:
8080 信号线 功能 FSMC-NOR 信
号线
功能
CSX 片选信号 NEx 片选
WRX 写使能 NWR 写使能
RDX 读使能 NOE 读使能
D[15:0] 数据信号 D[15:0] 数据信号
D\CX 数据/命令选
择
A[25:0] 地址信号
前四种信号线都是完全一样的,仅在 8080 的数据\命令选择线与 FSMC 的
地址信号线有区别。为了模拟出 8080 时序,我们把 FSMC 的 A0 地址线(也可以
使用其它地址线)连接 8080 的 D\CX,即 A0 为高电平时,数据线 D[15:0]的信
号会被理解 ILI9341 为数值,若 A0 为低电平时,传输的信号则会被理解为命
令。
也就是说,当向地址为 0x6xxx xxx1、0x6xxx xxx3、0x6xxx xxx5„这些奇
数地址写入数据时,地址线 A0(D/CX)会为高电平,这个数据被理解为数值;若
向 0x6xxx xxx0 、0x6xxx xxx2、0x6xxx xxx4„这些偶数地址写入数据时,地
址线 A0(D/CX)会为低电平,这个数据会被理解为命令。
有了这个基础,只要我们在代码中利用指针变量,向不同的地址单元写入
数据,就能够由 FSMC 模拟出的 8080 接口向 ILI9341 写入控制命令或 GRAM 的
数据了。
-第 10 页-
4.3.1 触摸屏感应原理
触摸屏常与液晶屏配套使用,组合成为一个可交互的输入输出系统。除了
熟悉的电阻、电容屏外,触摸屏的种类还有超声波屏、红外屏。由于电阻屏的
控制系统简单、成本低,且能适应各种上恶劣环境,被广泛采用。
电阻触摸屏的基本原理为分压,它由一层或两层阻性材料组成,在检测坐
标时,在阻性材料的一端接参考电压 Vref,另一端接地,形成一个沿坐标方向
的均匀电场。当触摸屏受到挤压时,阻性材料与下层电极接触,阻性材料被分
为两部分,因而在触摸点的电压,反映了触摸点与阻性材料的 Vref 端的距离,
而且为线性关系,而该触点的电压可由 ADC 测得。更改电场方向,以同样的方
法,可测得另一方向的坐标。
4.3.2 TSC2046 触摸屏控制器
TSC2046 是专用在四线电阻屏的触摸屏控制器,MCU 可通过 SPI 接口向它写
入控制字,由它测得 X、Y 方向的触点电压返回给 MCU。见图 0-7。
图 0-7 TSC2046 与电阻屏的连接图
图中,电阻屏两层阻性材料的两端分别接入到 TSC2046 的 X+、X-和
Y+、Y-。当要测量 X 坐标时,MCU 通过 SPI 接口写命令到 TSC2046,使它通
过内部的模拟开关使 X+、X-接通电源,于是在电阻屏的 X 方向上产生一个匀强
电场;把 Y+、Y-连接到 TSC2046 的 ADC。当电阻屏被触摸时,上、下两层的
-第 11 页-
阻性材料接触,在 PENIRQ 引脚产生一个中断信号,通知 MCU。该触点的电压
由 Y+或 Y-(此时的 Y+Y-电阻很小,可忽略)引入到 ADC 进行测量,MCU 读取该
电压,进行软件转换,就可以测得触点 X 方向的坐标。同理可以测得 Y 方向的
坐标。
4.4 实验讲解
4.4.1 实验描述及工程文件清单
实验描述 野火 STM32 开发板驱动配套的 3.2 寸液晶、触摸屏,使用
FSMC 接口控制该屏幕自带的液晶控制器 ILI9341,使用 SPI
接口与触摸屏控制器 TSC2046 通讯。驱动成功后可在屏幕上
使用基本的触摸绘图功能。
硬件连接 TFT 数据线
PD14-FSMC-D0 ----LCD-DB0
PD15-FSMC-D1 ----LCD-DB1
PD0-FSMC-D2 ----LCD-DB2
PD1-FSMC-D3 ----LCD-DB3
PE7-FSMC-D4 ----LCD-DB4
PE8-FSMC-D5 ----LCD-DB5
PE9-FSMC-D6 ----LCD-DB6
PE10-FSMC-D7 ----LCD-DB7
PE11-FSMC-D8 ----LCD-DB8
PE12-FSMC-D9 ----LCD-DB9
PE13-FSMC-D10 ----LCD-DB10
PE14-FSMC-D11 ----LCD-DB11
PE15-FSMC-D12 ----LCD-DB12
PD8-FSMC-D13 ----LCD-DB13
PD9-FSMC-D14 ----LCD-DB14
PD10-FSMC-D15 ----LCD-DB15
-第 12 页-
TFT 控制信号线
PD4-FSMC-NOE ----LCD-RD
PD5-FSMC-NEW ----LCD-WR
PD7-FSMC-NE1 ----LCD-CS
PD11-FSMC-A16 ----LCD-DC
PE1-FSMC-NBL1 ----LCD-RESET
PD13-FSMC-A18 ----LCD-BLACK-LIGHT
触摸屏 TSC2046 控制线
PA5-SPI1-SCK ----TSC2046-SPI -SCK
PA7-SPI1-MOSI ----TSC2046-SPI - MOSI
PA6-SPI1-MISO ----TSC2046-SPI – MISO
PB7-I2C1-SDA ----TSC2046-SPI-CS
PB6-I2C1-SCL ----TSC2046- INT_IRQ
用到的库文件 startup/start_stm32f10x_hd.c
CMSIS/core_cm3.c
CMSIS/system_stm32f10x.c
FWlib/misc.c
FWlib/stm32f10x_spi.c
FWlib/stm32f10x_rcc.c
FWlib/stm32f10x_exti.c
FWlib/stm32f10x_gpio.c
FWlib/stm32f10x_fsmc.c
用户编写的文件 USER/main.c
USER/stm32f10x_it.c
USER/lcd.c
USER/SysTick.c
USER/lcd_botton.c
USER/Touch.c
-第 13 页-
野火 STM32 开发板 3.2 寸 LCD 硬件连接图(兼容 V1 版本的 2.4 寸屏)
4.4.2 配置工程环境
本 LCD 触摸屏画板实验中我们用到了 GPIO、RCC、SPI、EXTI、FSMC 外
设,所以我们先要把以下库文件添加到工程:stm32f10x_gpio.c 、
stm32f10x_rcc.c、stm32f10x_spi.c、stm32f10x_exti.c、stm32f10x_fsmc.c。
由于在 TSC2046 的触摸检测中使用了中断,所以还要把 misc.c 文件添加进工
程。
本工程使用了旧的用户文件 SysTick.c,用作定时,把它添加到新工程之
中,并新建 lcd_botton.c、lcd.c、Touch.c 及相应的头文件。其中 lcd_botton.c
文件定义了最底层的 LCD 控制函数,LCD 上层的函数如画点、显示字符等位于
lcd.c 文件中。
最后在 stm32f10x_conf.h 中把使用到的 ST 库的头文件注释去掉。
1. /**
2. **********************************************************
3. * @file Project/STM32F10x_StdPeriph_Template/stm32f10x_conf.h
4. * @author MCD Application Team
5. * @version V3.5.0
6. * @date 08-April-2011
7. * @brief Library configuration file.
8. ******************************************************/
9.
10. #include "stm32f10x_exti.h"
11. #include "stm32f10x_fsmc.h"
12. #include "stm32f10x_gpio.h"
13. #include "stm32f10x_rcc.h"
14. #include "stm32f10x_spi.h"
-第 14 页-
15. #include "misc.h"
4.4.3 main 文件
从本工程的 main 文件分析代码的执行流程:
1. /*
2. * 函数名:main
3. * 描述 :主函数
4. * 输入 :无
5. * 输出 :无
6. */
7. int main(void)
8. {
9. SysTick_Init(); /*systick 初始化*/
10. LCD_Init(); /*LCD 初始化*/
11. Touch_init(); /*触摸初始化*/
12.
13. while(Touchl_Calibrate() !=0); /*等待触摸屏校准完毕*/
14. Init_Palette(); /*画板初始化*/
15.
16. while (1)
17. {
18. if(touch_flag == 1) /*如果触笔按下了*/
19. {
20. /*获取点的坐标*/
21. if(Get_touch_point(&display, Read_2046_2(), &touch_para )
!=DISABLE)
22. {
23. /*画点*/
24. Palette_draw_point(display.x,display.y);
/*画点*/
25. }
26. }
27. }
28. }
其执行流程如下:
1. 调用 SysTick_Init()、LCD_Init()、Touch_init()初始化了 STM32 的
Systick、FSMC、SPI 外设,并用 FSMC 和 SPI 接口初始化了 ILI9341 和
TSC2046 控制器。
2. 调用 Touch1_Calibrate()函数进行触摸屏校准,使得触摸屏与液晶屏的
坐标匹配。
3. 调用 Init_Palette()函数初始化触摸画板的应用程序,使得在 LCD 上显示
画板界面,并能够正常响应触摸屏的信号。
4. 第 16~27 行的 while 循环,通过不断检测触笔按下标志 touch_flag,判
断触摸屏是否被触笔按下。触摸屏控制器 TSC2046 检测到触笔信号
-第 15 页-
时,由它的 PENIRQ 引脚触发 STM32 的中断,在中断服务函数中对
touch_flag 标志置 1。
5. 第 21 行,若检测到触笔按下,调用 Get_touch_point()函数读取
TSC2046 的寄存器,获得与触点的 X、Y 坐标相关的电压信号,转化成
LCD 的 X、Y 坐标。
6. 获取了触点坐标后,使 LCD 液晶屏在该坐标点显示为对应的颜色。
7. 循环触点捕捉、画点过程,就实现了触摸画板的功能。
4.4.5 初始化 FSMC 模式
4.4.5.1 初始化液晶屏流程
在 main 函数中调用的 LCD_Init()函数,它对液晶控制器 ILI9341 用到的
GPIO、FSMC 接口进行了初始化,并且向该控制器写入了命令参数,配置好了
LCD 液晶屏的基本功能。其函数定义位于 lcd_botton.c 文件,如下:
1. /*****************************************
2. * 函数名:LCD_Init
3. * 描述 :LCD 控制 I/O 初始化
4. * LCD FSMC 初始化
5. * LCD 控制器 HX8347 初始化
6. * 输入 : 无
7. * 输出 :无
8. * 举例 :无
9. * 注意 :无
10. ******************************************/
11. void LCD_Init(void)
12. {
13. unsigned long i;
14.
15. LCD_GPIO_Config(); //初始化使用到的 GPIO
16. LCD_FSMC_Config(); //初始化 FSMC 模式
17. LCD_Rst(); //复位 LCD 液晶屏
18. Lcd_init_conf(); //写入命令参数,对液晶屏进行基本的初始化配置
19. Lcd_data_start(); //发送写 GRAM 命令
20. for(i=0; i<(320*240); i++)
21. {
22. LCD_WR_Data(GBLUE); //发送颜色数据,初始化屏幕为 GBLUE 颜色
23.
24. }
25. }
LCD_Init()函数执行后,最直观的结果是使 LCD 整个屏幕显示编码为
0X07FF 的 GBLUE 颜色。
-第 16 页-
函数中调用的 LCD_GPIO_Config()主要工作是把液晶屏(不包括触摸屏)中
使用到的 GPIO 引脚和使能外设时钟,除了背光、复位用的 PD13 和 PD1 设置
为通用推挽输出外,其它的与 FSMC 接口相关的地址信号、数据信号、控制信
号的端口均设置为复用推挽输出。
4.4.5.2 初始化 FSMC 模式
接下来 LCD_Init()函数调用 LCD_FSMC_Config()设置 FSMC 的模式,我们
的目的是使用它的 NOR FLASH 模式模拟出 8080 接口,在 LCD 接口中我们使用
的是 FSMC 地址线 A16 作为 8080 的 D/CX 命令选择信号的。
LCD_FSMC_Config()具体代码如下:
1. /*******************************************
2. * 函数名:LCD_FSMC_Config
3. * 描述 :LCD FSMC 模式配置
4. * 输入 : 无
5. * 输出 :无
6. * 举例 :无
7. * 注意 :无
8. *********************************************/
9. void LCD_FSMC_Config(void)
10. {
11. FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
12. FSMC_NORSRAMTimingInitTypeDef p;
13.
14.
15. p.FSMC_AddressSetupTime = 0x02; //地址建立时间
16. p.FSMC_AddressHoldTime = 0x00; //地址保持时间
17. p.FSMC_DataSetupTime = 0x05; //数据建立时间
18. p.FSMC_BusTurnAroundDuration = 0x00; //总线恢复时间
19. p.FSMC_CLKDivision = 0x00; //时钟分频
20. p.FSMC_DataLatency = 0x00; //数据保持时间
21. p.FSMC_AccessMode = FSMC_AccessMode_B; //在地址数\据线不复用的情况
下,ABCD 模式的区别不大
22. //本成员配置只有使用扩展模式
才有效
23.
24.
25. FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1;
//NOR FLASH 的 BANK1
26. FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMu
x_Disable; //数据线与地址线不复用
27. FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;
//存储器类型 NOR FLASH
28. FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWi
dth_16b; //数据宽度为 16 位
29. FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessM
ode_Disable; //使用异步写模式,禁止突发模式
30. FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSigna
lPolarity_Low; //本成员的配置只在突发模式下有效,等待信号极性为低
-第 17 页-
31. FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
//禁止非对齐突发模式
32. FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalA
ctive_BeforeWaitState; //本成员配置仅在突发模式下有效。NWAIT 信号在什么时期
产生
33. FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disabl
e; //本成员的配置只在突发模式下有效,禁用 NWAIT 信号
34. FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disabl
e; //禁止突发写操作
35. FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperatio
n_Enable; //写使能
36. FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Di
sable; //禁止扩展模式,扩展模式可以使用独立的读、写模式
37. FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
//配置读写时序
38. FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
//配置写时序
39.
40.
41. FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
42.
43. /* 使能 FSMC Bank1_SRAM Bank */
44. FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);
45. }
本函数主要使用了两种类型的结构体对 FSMC 进行配置,第一种
为 FSMC_NORSRAMInitTypeDef 类型的结构体主要用于 NOR FLASH 的模式配
置,包括存储器类型、数据宽度等。另一种的类型为
FSMC_NORSRAMTimingInitTypeDef,这是用于配置 FSMC 的 NOR FLASH 模式
下读写时序中的地址建立时间、地址保持时间等,代码中用它定义了结构体
p,这个第二种类型的结构体在前一种结构体中被指针调用。
下面先来分析 FSMC_NORSRAMInitTypeDef 的结构体成员:
1. FSMC_Bank
用于选择外接存储器的区域(或地址),见图 0-8 FSMC 存储块,
STM32 的存储器映射中,把 0x6000 0000~0x9fff ffff 的地址都映射到
被 FSMC 控制的外存储器中,其中属于 NOR FLASH 的为 0x6000
0000~0x6fff ffff。而属于 NOR FLASH 的这部分地址空间又被分为 4
份,每份大小为 64MB,编号为 BANK1 ~BANK4。分 BANK 是由 FSMC
寻址范围决定的,该接口的地址线最多为 26 条,即最大寻址空间为
226 =64MB。为了扩展寻址空间,可把地址与数据线与多片 NOR
FLASH 并联,由不同的片选信号 NE[3:0]区分不同的 BANK。
-第 18 页-
在本实验中,我们使用的是 FSMC 的信号线 NE1 作为控制 8080
的 CSX 片选信号,所以我们把本成配置为 FSMC_Bank1_NORSRAM1
(NE1 片选 BANK1)。
图 0-8 FSMC 存储块
2. FSMC_DataAddressMux
本成员用于配置 FSMC 的数据线与地址线是否复用。FSMC 支持数
据与地址线复用或非复用两种模式。在非复用模式下 16 位数据线及 26
位地址线分开始用;复用模式则低 16 位数据/地址线复用。在复用模式
下,推荐使用地址锁存器以区分数据与地址。当 NADV 信号线为低时,
复用信号线 ADx(x=0…15)上出现地址信号 Ax,当 NADV 变高时,ADx
上出现数据信号 Dx。
本实验中用 FSMC 模拟 8080 接口,地址线 A16 提供 8080 的
D/CX 信号,实际上就只使用了这一条地址线,I\O 资源并不紧张,所
以把本成员配置为 FSMC_DataAddressMux_Disable (非复用模式)。
3. FSMC_MemoryType
-第 19 页-
本成员用于配置 FSMC 外接的存储器的类型,可被配置为 NOR FLASH 模
式、PSARM 模式及 SRAM 模式。
在本实验的应用中,由于 NOR FLASH 模式的时序与 8080 更接近,所以本
结构体被配置为 FSMC_MemoryType_NOR(NOR FLASH 模式)。
4. FSMC_MemoryDataWidth
本成员用于设置 FSMC 接口的数据宽度,可被设置为 8Bit 或 16bit。对于
16 位宽度的外部存储器。在 STM32 地址映射到 FSMC 接口的结构中,HADDR
信号线是需要转换到外部存储器的内部 AHB 地址线,是字节地址。
若存储器的数据线宽为 8Bit,FSMC 的 26 条地址信号线 FSMC_A[25:0]直
接可以引入到与 AHB 相连的 HADDR[25:0],26 条字节地址信号线最大寻址空
间为 64MB。见图 0-9。
图 0-9 外部存储器地址
若存储器的数据线宽 16Bit,则存储器的地址信号线是半字地址(16Bit) 。
为了使 HADDR 的字节地址信号线与存储器匹配,FSMC 的 25 条地址信号线
FSMC_A[24:0]与 HADDR[25:1]相连,由于变成了半字地址(16Bit),仅需要 25
条半字字地址信号线就达到最大寻址空间 64MB。正因地址线的不对称相连,
16bit 数据线宽下,实际的访问地址为右移一位之后的地址。
本实验中 8080 接口采用 16bit 模式,所以我们把本成员配置为
FSMC_MemoryDataWidth_16b,由于地址线不对称相连,这会影响到我们用地
址信号线 A16 控制的 8080 接口的 D/CX 信号。
5. FSMC_BurstAccessMode
本成员用于配置访问模式。FSMC 对存储器的访问分为异步模式和突发
模式(同步模式)。在异步模式下,每次传送数据都需要产生一个确定的地
址,而突发模式可以在开始始提供一个地址之后,把数据成组地连续写
入。
-第 20 页-
本实验中使用 FSMC 模拟 8080 端口,更适合使用异步模式,因而向本成
员赋值为 FSMC_WriteBurst_Disable。
6. 突发模式参数配置
代码中的 30~34 行,都是关于使用突发模式时的一些参数配置,这些成
员为: FSMC_WaitSignalPolarity(配置等待信号极性)、
FSMC_WrapMode(配置是否使用非对齐方式)、FSMC_WaitSignalActive(配
置等待信号什么时期产生)、FSMC_WaitSignal(配置是否使用等待信
号)、FSMC_WriteBurst(配置是否允许突发写操作),这些成员均需要在突
发模式开启后配置才有效。
这些成员在开启突发模式时才有效,本实验使用的是异步模式,所以这
些成员的参数没有意义。
7. FSMC_WriteOperation
本成员用于配置写操作使能,如果禁止了写操作,FSMC 不会产生写时
序,但仍可从存储器中读出数据。
本实验需要写时序,所以向本成员赋值为
FSMC_WriteOperation_Enable(写使能)
8. FSMC_ExtendedMode
本成员用于配置是否使用扩展模式,在扩展模式下,读时序和写时序可以
使用独立时序模式。如读时序使用模式 A,写时序使用模式 B,这些 A、B、
C、D 模式实际上差别不大,主要是在使用数据/地址线复用的情况下,NADV
信号产生的时序不一样,具体的时序图可查阅《STM32 参考
手册
华为质量管理手册 下载焊接手册下载团建手册下载团建手册下载ld手册下载
》。
本实验中数据/地址线不复用,所以读写时序中不同的 NADV 信号并没影
响,禁止使用扩展模式 SMC_ExtendedMode_Disable。
9. FSMC_ReadWriteTimingStruct 及 FSMC_WriteTimingStruct
这两