控制FSMC使用SRAM存储器时主要是配置时序寄存器以及控制寄存
器,利用ST标准库的SRAM时序结构体以及初始化结构体可以很方便地写入参
数。
时序结构体: FSMC_ NORSRAMTimingInitTypeDef
初始化结构体: FSMC NORSRAMInitTypeDef
与其他的初始化相似,是由对应的XXX_Init()函数就可以初始化了。
这个FSMC_NORSRAMTimingInitTypeDef 时序结构体配置的延时参数,将作为下一节的FSMC SRAM初始化结构体的一个成员。
typedef struct
{
uint32_t FSMC_AddressSetupTimz; /*地址建立时间,0-0xF 个HCLK周期*/
uint32_t FSMC_AddressHoldTime; /*地址保持时间,0-0xF 个HCLK周期*/
uint32_t FSMC_DataSetupTime ; /*地址建立时间,0-0xF 个HCLK周期*/
uint32_t FSMC_BusTurnAroundDuration; /* 总线转换周期,0-0xF个HCLK周期,在NOR FLASH */
uint32_t FSMC_CLKDivision; /*时钟分频因子, 1-0xE,若控制异步存储器,本参数无效*/
uint32_t FSMC_DataLatency; /*数据延迟时间,若控制异步存储器,本参数无效*/
uint32_t FSMC_AccessMode; /*设置访问模式 */
} FSMC_NORSRAMTimingInitTypeDef;
FSMC初始化结构体,除最后两个成员是上一小节讲解的时序配置外,其它结构体成员的配置都对应到FSMCBCR中的寄存器位。
typedef struct
{
uint32_t FSMC_Bank; /*设置要控制的Bank区域*/
uint32_t FSMC_DataAddressMux; /*设置地址总线与数据总线是否复用*/
uint32_t FSMC_MemoryType; /*设置存储器的类型*/
uint32_t FSMC_MemoryDatawidth; /*设置存储器的数据宽度*/
uint32_t FSMC_BurstAccessMode; /*设置是否支持突发访问模式, 只支持同步类型的存储器*/
uint32_t FSMC_AsynchronousWait; /* 设置是否使能在同步传输时的等待信号,*/
uint32_t FSMC_WaitSignalPolarity; /* 设置等待信号的极性*/
uint32_t FSMC_WrapMode; /*设置是否支持对 齐的突发模式*/
uint32_t FSMC_WaitsignalActive; /*配置等待信 号在等待前有效还是等待期间有效*/
uint32_t FSMC_WriteOperation; /* 设置是否写使能*/
uint32_t FSMC_WaitSignal; /*设置是否使能等待状态插入*/
uint32_t FSMC_ExtendedMode ; /*设置是否使能扩展模式*/
uint32_t FSMC_WriteBurst; /* 设置是否使能写突发操作*/
/*当不使用扩展模式时,本参数用于配置读写时序,否则用于配置读时序*/
FSMC_NORSRAMTimingInitTypeDef* FSMC_ReadWriteTimingStruct;
/*当使用扩展模式时,本参数用于配置写时序*/
FSMC_NORSRAMTimingInitTypeDef* FSMC_WriteTimingStruct;
} FSMC_NORSRAMInitTypeDef; .
代码如下:
//一个 HCLK时钟周期 为 1/72us = 0.0138us = 13.8ns。
//按照如下配置(ADDSET+1) + (DATAST+1) = 13.8 +41.4 = 55.2ns >55ns
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;//初始化结构体
FSMC_NORSRAMTimingInitTypeDef writeTiming;//读时序结构体
writeTiming.FSMC_AddressSetupTime = 0x00; //地址建立时间为0+1个HCLK :1*13.8ns = 13.8ns
writeTiming.FSMC_DataSetupTime = 0x03; //数据保存时间为2+1个HCLK:3*13.8ns = 41.4ns
writeTiming.FSMC_AddressHoldTime = 0x00; //地址保持时间(ADDHLD)模式A未用到
writeTiming.FSMC_BusTurnAroundDuration = 0x00;
writeTiming.FSMC_CLKDivision = 0x00;
writeTiming.FSMC_DataLatency = 0x00;
writeTiming.FSMC_AccessMode = FSMC_AccessMode_A; //模式A
//一个 HCLK时钟周期 为 1/72us = 0.0138us = 13.8ns。
//按照如下配置(ADDSET+1) + (DATAST+1) + 2HCLK = 13.8 + 27.6 + 27.6 = 69ns >55ns
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;//初始化结构体
FSMC_NORSRAMTimingInitTypeDef readWriteTiming; //写时序结构体
readWriteTiming.FSMC_AddressSetupTime = 0x00; //地址建立时间为0+1个HCLK :1*13.8ns = 13.8ns
readWriteTiming.FSMC_DataSetupTime = 0x01; //数据保存时间为1+1个HCLK:2*13.8ns = 27.6ns
readWriteTiming.FSMC_AddressHoldTime = 0x00; //地址保持时间(ADDHLD)模式A未用到
readWriteTiming.FSMC_BusTurnAroundDuration = 0x00;
readWriteTiming.FSMC_CLKDivision = 0x00;
readWriteTiming.FSMC_DataLatency = 0x00;
readWriteTiming.FSMC_AccessMode = FSMC_AccessMode_A; //模式A
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM4;// 这里我们使用NE4 ,也就对应BTCR[6],[7]。
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; // 不复用数据地址
FSMC_NORSRAMInitStructure.FSMC_MemoryType =FSMC_MemoryType_SRAM;//SRAM
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;//存储器数据宽度为16bit
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode =FSMC_BurstAccessMode_Disable;//不使用突发访问模式
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;//设置等待信号的有效极性
FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait=FSMC_AsynchronousWait_Disable; //是否使能等待信号
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_Enable; // 读写使用不同的时序
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; //不开启突发写操作
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &readWriteTiming; //读写时序
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &writeTiming; //写时序
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); //初始化FSMC配置
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE); // 使能BANK1
注意:
在((ADDSET+1) + (DATAST+1))HCLK中,((ADDSET+1) + (DATAST))HCLK这段时间是保持写使能信号NWE低电平的时间,剩下的1HCLK是NWE保持高电平的默认时间
在数据建立周期FSMC才会操作数据总线传输数据
twrl:
写控制低电平信号最小时间为15ns,故可以设置FSMC模式B的地址建立周期(ADDSET+1)要15ns, 用来保证写控制低电平信号有效。
(ADDSET+1)HCLK > 15ns, (1+1) * 13.8 > 15 ,所以ADDSET可以设置为1保证写低电平有效
tdst、tdht:
tdst:数据设置时间最小是10ns,在这个周期内WRX线处于低电平。
tdht:数据保持时间,与 twrh写控制高电平的最小时间相同,是10ns,在这个周期内WRX线处于高电平。
观察时序图,我们设置 tdst数据设置时间 为1HCLK(13.8>10)就能满足数据设置最小时间的要求,我们不需要考虑tdht数据保持时间(看上面模式B时序图,NWE变成高电平后,会持续1HCLK=13.8ns,默认满足tdht了)
故我们只需考虑数据建立周期 DATAST 要大于10ns就行.
(DATAST )HCLK > 10ns,13.8>10 ,故DATAST 至少设置为1
twc
写时序周期,最小66ns,所以FSMC的一个写入操作周期((ADDSET+1) + (DATAST+1))HCLK要大于66ns.
((ADDSET+1) + (DATAST+1))HCLK > 66ns ,((1+1)+(2+1))·13.8 = 5·13.8 = 69ns>66ns
故ADDSET可以设置为1,DATAST可以设置为2
代码如下:
//一个 HCLK时钟周期 为 1/72us = 0.0138us = 13.8ns。
//按照如下配置(ADDSET+1) + (DATAST+1) = 13.8 +41.4 = 55.2ns >55ns
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;//初始化结构体
FSMC_NORSRAMTimingInitTypeDef writeTiming;//读时序结构体
writeTiming.FSMC_AddressSetupTime = 0x01; //地址建立时间为1+1个HCLK :2*13.8ns = 27.6ns
writeTiming.FSMC_DataSetupTime = 0x02; //数据设置时间为2个HCLK:2*13.8ns = 27.6ns,数据保存时间为1个HCLK = 13.8ns
writeTiming.FSMC_AddressHoldTime = 0x00; //地址保持时间(ADDHLD)模式B未用到
writeTiming.FSMC_BusTurnAroundDuration = 0x00;
writeTiming.FSMC_CLKDivision = 0x00;
writeTiming.FSMC_DataLatency = 0x00;
writeTiming.FSMC_AccessMode = FSMC_AccessMode_B; //模式B
注意:RDX(ID)ID指LCD的ID号, RDX(FM)FM指帧缓存,即:GRAM
//一个 HCLK时钟周期 为 1/72us = 0.0138us = 13.8ns。
//按照如下配置(ADDSET+1) + (DATAST+1) + 2HCLK = 13.8 + 27.6 + 27.6 = 69ns >55ns
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;//初始化结构体
FSMC_NORSRAMTimingInitTypeDef readWriteTiming; //写时序结构体
readWriteTiming.FSMC_AddressSetupTime = 0x00; //第一段低电平时间为0+1个HCLK :1*13.8ns = 13.8ns
readWriteTiming.FSMC_DataSetupTime = 0x0f; //第二段低电平时间为15+1个HCLK:16*13.8ns = 220.8ns
readWriteTiming.FSMC_AddressHoldTime = 0x00; //地址保持时间(ADDHLD)模式A未用到
readWriteTiming.FSMC_BusTurnAroundDuration = 0x00;
readWriteTiming.FSMC_CLKDivision = 0x00;
readWriteTiming.FSMC_DataLatency = 0x00;
readWriteTiming.FSMC_AccessMode = FSMC_AccessMode_B; //模式A
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM4;// 这里我们使用NE4 ,也就对应BTCR[6],[7]。
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; // 不复用数据地址
FSMC_NORSRAMInitStructure.FSMC_MemoryType =FSMC_MemoryType_NOR;//NOR
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;//存储器数据宽度为16bit
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode =FSMC_BurstAccessMode_Disable;//不使用突发访问模式
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;//设置等待信号的有效极性
FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait=FSMC_AsynchronousWait_Disable; //是否使能等待信号
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_Enable; // 读写使用不同的时序
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; //不开启突发写操作
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &readWriteTiming; //读写时序
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &writeTiming; //写时序
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); //初始化FSMC配置
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE); // 使能BANK1
总结
想要编写时序相关的内容时,时序图一定要看懂。所以要懂得如何取看时序图。