TA的每日心情![](source/plugin/dsu_paulsign/img/emot/fd.gif) | 奋斗 2013-8-15 09:52 |
---|
签到天数: 1 天 连续签到: 1 天 [LV.1]初来乍到
|
——————什么是FSMC,为什么要用FSMC:
FSMC(Flexible Static Memory Controller,可变静态存储控制器),能够根据不同的外部存储器类型,发出相应的数据/地址/控制信号类型以匹配信号的速度。FSMC的一端通过内部高速总线AHB连接到内核Cortex-M3,另一端则是面向扩展存储器的外部总线。内核对外部存储器的访问信号发送到AHB总线后,经过FSMC转换为符合外部存储器通信规约的信号,送到外部存储器的相应引脚,实现内核与外部存储器之间的数据交互,即通过对FSMC的寄存器配置由硬件自动生成符合外部存储器操作时序的信号。相比直接用IO口模拟操作时序,速度更快。
——————FSMC映射地址空间:见STM32手册。
——————FSMC扩展NOR Flash配置(以驱动TFT为例):
把TFT作为只有2个地址的存储器对待. TFT的控制线有:复位信号RST,片选CS,输出使能RD(读信号),写信号WE以及RS信号。 于STM32连线为: RST->GPIO, CS->FSMC_NEx(N表示低电平有效), RD->FSMC_NOE, FSMC_NEW->WR, RS(Register Select)->A0(或者其他任何一条地址线),关键在于RS信号,在操作时序中RS=0一般是写命令,RS=1写数据,当我们把TFT的RS信号接到FSMC_A(0~25)中的随便一条时就可确定读写数据的地址LCD_DATA_ADDR ,再确定写命令的地址LCD_CMD_ADDR就相当于RS信号线了。如要往TFT写命令只要写入地址LCD_CMD_ADDR,写数据写入地址LCD_DATA_ADDR。
1.确定映射地址空间即LCD_CMD_ADDR:
NOR Flash只能选用BANK1中的4个子BANK ,总地址范围为0X60000000~0X6FFFFFFF由TFT中的CS引脚连到FSMC_NEi(i=1...4)来对应子BANK,由此可以确定寄存器的基地址,如用FSMC_NE1,那么LCD_CMD_ADDR地址就为0X60000000 ,用FSMC_NE3就是0X68000000.这里我们用FSMC_NE1即0X60000000
2.确定 LCD_DATA_ADDR,当我们选择上文所提到的FSMC_A16时,LCD_DATA_ADDR=0X60000000+2^16*2=0X60020000.同理选择FSMC_A0时候就是LCD_DATA_ADDR=0X60000000+2^0*2=0X60000002.
那么写命令就是直接往LCD_CMD_ADDR写
LCD_WRITE_CMD(u16 cmd) //写命令到TFT,16位要写2次
{
*(vu16*)LCD_CMD_ADDR=cmd;
}
写数据就是直接往LCD_DATA_ADDR写
LCD_WRITE_DATA(u16 Data) //写数据到TFT
{
*(vu8*)LCD_DATA_ADDR=Data;
}
至于RD,WE,RS,CS信号都已经是FSMC控制器自动产生的,不用理会
—————— 配置FSMC时序参数 :见STM32数据手册和TFT手册(不是很懂·····)
#define LCD_DATA_ADDR ((u32)0x60020000) //Disp Data ADDR
#define LCD_CMD_ADDR ((u32)0x60000000) //Disp Reg ADDR
#define LCD_WR_CMD(cmd) ((*(__IO u16 *) ( LCD_CMD_ADDR )) = ((u16)cmd))
#define LCD_WR_Data(data) ((*(__IO u16 *) (LCD_DATA_ADDR )) = ((u16)(data)))
void LCD_FSMC_Config(void)
{
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
FSMC_NORSRAMTimingInitTypeDef p;
p.FSMC_AddressSetupTime = 0x02; //地址建立时间
p.FSMC_AddressHoldTime = 0x00; //地址保持时间
p.FSMC_DataSetupTime = 0x05; //数据建立时间
p.FSMC_BusTurnAroundDuration = 0x00;
p.FSMC_CLKDivision = 0x00;
p.FSMC_DataLatency = 0x00;
p.FSMC_AccessMode = FSMC_AccessMode_B; // 一般使用模式B来控制LCD
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1;
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
/* 使能 FSMC Bank1_SRAM Bank */
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);
}
|
|
|