文章归档友情连接照片地图

STM32F407的FSMC方式操作LCD显示屏

分类:电子设计  作者:rming  时间:2013-02-21

半年的时间了,没怎么更新博客,受到的打击比较多,没有什么敲键盘的心情了,整天沉浸在游戏里,试图解脱,现在游戏打得多了,也没什么意思了,还是回来面对现实吧,仔细想想面前的这点小事也不算什么,不在扯淡,开始正题。

STM32F407的FSMC方式操作LCD显示屏 

之前没用过Cortex-M4的芯片,倒是从M3入门学习的,前一段时间买了一个STM32F407的板子,从网上翻阅了一些资料,因为之前的学习是从寄存器操作学习的,感觉从M3到M4的迁移倒是没什么难度,只不过是翻翻参考手册,看看对应控制寄存器的不同,学习一个MCU大致也就如此。

最基础最实用的GPIO

 IO口在M4里面除去一些普通的功能选项外,就是可以进行功能复用和重新映射,因为板子上的FSMC正是采用了一些IO口的复用功能,这里我们仔细看一下IO口的复用设置。

先来看一下ST对IO控制所创建的结构体,了解一下都是有哪些寄存器和IO有关系:

STM32F4xx.h L650

/**
* @brief General Purpose I/O
*/
typedef struct
{
__IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */
__IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */
__IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */
__IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */
__IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */
__IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */
__IO uint16_t BSRRL; /*!< GPIO port bit set/reset low register, Address offset: 0x18 */
__IO uint16_t BSRRH; /*!< GPIO port bit set/reset high register, Address offset: 0x1A */
__IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */
__IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */
} GPIO_TypeDef;

 刚开始的MODER、OTYPER、OSPEEDR、PUPDR、IDR、ODR、BSSRL、BSSRH、LCR这些寄存器正是设置输出模式、输出类型、输出速度、上拉下拉、输入数据(只读)、输出数据、复位、置位、锁存,我们重点看一下最后的AFR[2],这正是端口复用功能配置寄存器,具体内容我们仔细了解。

20130221012512.jpg

20130221012419.jpg

20130221012556.jpg

这里简单概括讲,就是一个IO口最多可能有16种复用功能,我们给每一个复用功能编号分组,在设置好其他寄存器后,只需要将GPIOx->AFR[y]设置上所需要的功能即可,这里我们使用AF12(FSMC),他的编号是0xC。

如果IO口被用于FSMC,那么首先对IO设置为复用、推挽输出、无上拉无下拉、50Mhz速度,然后对复用功能设置为FSMC功能。

其他的IO口控制寄存器可以查阅参考手册。

20130221124046.jpg

20130221124106.jpg

20130221124134.jpg

20130221124145.jpg

20130221124153.jpg

20130221124202.jpg

20130221124210.jpg

20130221124219.jpg

20130221124245.jpg

具体代码如下:

 RCC->AHB1ENR|=1<AHB1ENR|=1<MODER &= 0x0FC0F0F0; //复用功能
GPIOD->MODER |= 0xA02A0A0A;
GPIOD->OTYPER &= 0x38CC; //推挽输出
GPIOD->OSPEEDR &= 0x0FC0F0F0; // 速度50M
GPIOD->OSPEEDR |= 0xA02A0A0A;
GPIOD->PUPDR &= 0x0FC0F0F0; //无上拉、无下拉
GPIOD->AFR[0] &= 0xFF00FF00;//设置复用功能为FSMC
GPIOD->AFR[0] |= 0x00CC00CC;
GPIOD->AFR[1] &= 0x00FFF000;
GPIOD->AFR[1] |= 0xCC000CCC;
//PORTE7~15 复用FSMC、推挽输出、无上拉无下拉、50Mhz
GPIOE->MODER &= 0x00003FFF; //复用功能
GPIOE->MODER |= 0xAAAA8000;
GPIOE->OTYPER &= 0x007F; //推挽输出
GPIOE->OSPEEDR &= 0x00003FFF; // 速度50M
GPIOE->OSPEEDR |= 0xAAAA8000;
GPIOE->PUPDR &= 0x00003FFF; //无上拉、无下拉
GPIOE->AFR[0] &= 0x0FFFFFFF;//设置复用功能为FSMC
GPIOE->AFR[0] |= 0xC0000000;
GPIOE->AFR[1] &= 0x00000000;
GPIOE->AFR[1] |= 0xCCCCCCCC;
//PORTD11 (RS)
GPIOD->MODER &= 0xFF3FFFFF; //复用功能
GPIOD->MODER |= 0x00800000;
GPIOD->OTYPER &= 0xF7FF; //推挽输出
GPIOD->OSPEEDR &= 0xFF3FFFFF; // 速度50M
GPIOD->OSPEEDR |= 0x00800000;
GPIOD->PUPDR &= 0xFF3FFFFF; //无上拉、无下拉
GPIOD->AFR[1] &= 0xFFFF0FFF;
GPIOD->AFR[1] |= 0x0000C000;
//PORTD7 (CS)
GPIOD->MODER &= 0xFFFF3FFF; //复用功能
GPIOD->MODER |= 0x00008000;
GPIOD->OTYPER &= 0xFF7F; //推挽输出
GPIOD->OSPEEDR &= 0xFFFF3FFF; // 速度50M
GPIOD->OSPEEDR |= 0x00008000;
GPIOD->PUPDR &= 0xFFFF3FFF; //无上拉、无下拉
GPIOD->AFR[0] &= 0x0FFFFFFF;
GPIOD->AFR[0] |= 0xC0000000;

FSMC是个很实用的东西

 首先我们了解下什么事FSMC,FSMC是专门为外扩sram货rom使用的。
FSMC,即灵活的静态存储控制器,能够与同步或异步存储器和16位PC存储器卡接口,STM32的FSMC接口支持包括SRAM、NAND  FLASH、NOR  FLASH和PSRAM等存储器。

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

外部SRAM的控制一般有:地址线(如A0~A18)、数据线(如D0~D15)、写信号(WE)、读信号(OE)、片选信号(CS),如果SRAM支持字节控制,那么还有UB/LB信号。而TFTLCD的信号我们在18.1.1节有介绍,包括:RS、D0~D15、WR、RD、CS、RST和BL等,其中真正在操作LCD的时候需要用到的就只有:RS、D0~D15、WR、RD和CS。其操作时序和SRAM的控制完全类似,唯一不同就是FTLCD有RS信号,但是没有地址信号。 

TFTLCD通过RS信号来决定传送的数据是数据还是命令,本质上可以理解为一个地址信号,比如我们把RS接在A0上面,那么当FSMC控制器写地址0的时候,会使得A0变为0,对TFTLCD来说,就是写命令。而FSMC写地址1的时候,A0将会变为1,对TFTLCD来说,就是写数据了。这样,就把数据和命令区分开了,他们其实就是对应SRAM操作的两个连续地址。

具体的寄存器操作代码如下:

 

	RCC->AHB3ENR|=1; //使能FSMC时钟
//寄存器清零
//bank1有NE1~4,每一个有一个BCR+TCR,所以总共八个寄存器。
//这里我们使用NE1 ,也就对应BTCR[0],[1]。
FSMC_Bank1->BTCR[0]=0X00000000;
FSMC_Bank1->BTCR[1]=0X00000000;
FSMC_Bank1E->BWTR[0]=0X00000000;
//操作BCR寄存器	使用异步模式
FSMC_Bank1->BTCR[0]|=1<<12;	//存储器写使能
FSMC_Bank1->BTCR[0]|=1<<14;	//读写使用不同的时序
FSMC_Bank1->BTCR[0]|=1<<4; //存储器数据宽度为16bit
//操作BTR寄存器
//读时序控制寄存器
FSMC_Bank1->BTCR[1]|=0<<28;	//模式A
FSMC_Bank1->BTCR[1]|=3<<0; //地址建立时间(ADDSET)为2个HCLK 1/36M=27ns
//因为液晶驱动IC的读数据的时候,速度不能太快,尤其对1289这个IC。
FSMC_Bank1->BTCR[1]|=0X1F<<8; //数据保存时间为16个HCLK
//写时序控制寄存器
FSMC_Bank1E->BWTR[0]|=0<<28; //模式A
FSMC_Bank1E->BWTR[0]|=1<<0;	//地址建立时间(ADDSET)为1个HCLK
//4个HCLK(HCLK=72M)因为液晶驱动IC的写信号脉宽,最少也得50ns。72M/4=24M=55ns
FSMC_Bank1E->BWTR[0]|=7<<8; //数据保存时间为4个HCLK
//使能BANK1,区域4
FSMC_Bank1->BTCR[0]|=1<<0;	//使能BANK1,区域4


  1. tjCFeng tjCFeng

    您好,请问STM32F407的中文手册在哪里下载的?谢谢。

    1. @tjCFeng 我没有中文手册,文章里的部分寄存器截图是一位网友的学习笔记

提交评论