STM32之FSMC-SRAM例程
SRAM使用的是55ns的IS62WV51216,需要先分析IS62WV51216對讀寫的時序要求。
讀時序
?分析時序圖,可以提取如下信息(不分析高低字節位和使能位,因為FSMC訪問模式是一直保持的):整個讀周期大于55ns、地址建立時間55ns且讀使能25ns才能確保輸出數據
?
寫時序
分析時序圖,可以提取如下信息(不分析高低字節位和使能位,因為FSMC訪問模式是一直保持的):整個寫周期大于55ns、寫使能時間大于45ns(tHZWE+tSD)才能保證數據寫入
?
FSMC時序配置
根據手冊模式1和模式A一般用于SRAM操作。注意:根據手冊,模式1具有相同的讀寫時序,而模式A則是獨立的讀寫時序。
下面分別結合兩種模式進行時序分析:
模式1
根據提取出來的要求:整個讀周期大于55ns、地址建立時間55ns且讀使能25ns才能確保輸出數據、整個寫周期大于55ns、寫使能時間大于45ns(tHZWE+tSD)才能保證數據寫入。
得出:
tHCLK * ((ADDSET + 1) + (DATAST + 1) + 2) >= 55ns
tHCLK * ((ADDSET + 1) + (DATAST + 1) ) >= 55ns(不應包括2周期存儲時間)
tHCLK * ((ADDSET + 1) + (DATAST + 1) ) >= 25ns(不應包括2周期存儲時間)
tHCLK * ((ADDSET + 1) + (DATAST + 1) ) >= 55ns
tHCLK * DATAST >= 45ns
STM32F103的HCLK配置為72MHz,則tHCLK=13.8ns。因此,DATAST >= 4且ADDSET >= 0。
?
模式A
根據提取出來的要求:整個讀周期大于55ns、地址建立時間55ns且讀使能25ns才能確保輸出數據
得出:
tHCLK * ((ADDSET + 1) + (DATAST + 1) + 2) >= 55ns
tHCLK * ((ADDSET + 1) + (DATAST + 1) ) >= 55ns(不應包括2周期存儲時間)
tHCLK * (DATAST + 1) >= 25ns(不應包括2周期存儲時間)
STM32F103的HCLK配置為72MHz,則tHCLK=13.8ns。因此,DATAST = 1且ADDSET >=?1,DATAST >=?2且ADDSET >=?0。
?
根據提取出來的要求:整個寫周期大于55ns、寫使能時間大于45ns(tHZWE+tSD)才能保證數據寫入
tHCLK * ((ADDSET + 1) + (DATAST + 1) ) >= 55ns
tHCLK * DATAST >= 45ns
STM32F103的HCLK配置為72MHz,則tHCLK=13.8ns。因此,DATAST >= 4且ADDSET >= 0。
?
源碼例程
以模式A為例
#include "stm32f10x.h"/* RCC時鐘配置 */ void RCC_config() { ErrorStatus HSEStartUpStatus;/* RCC寄存器設置為默認配置 */RCC_DeInit();/* 打開外部高速時鐘 */RCC_HSEConfig(RCC_HSE_ON);/* 等待外部高速時鐘穩定 */HSEStartUpStatus = RCC_WaitForHSEStartUp();if(HSEStartUpStatus == SUCCESS) { /* 設置HCLK = SYSCLK */RCC_HCLKConfig(RCC_SYSCLK_Div1);/* 設置PCLK2 = HCLK */RCC_PCLK2Config(RCC_HCLK_Div1);/* 設置PCLK1 = HCLK / 2 */RCC_PCLK1Config(RCC_HCLK_Div2);/* 設置FLASH代碼延時 */FLASH_SetLatency(FLASH_Latency_2);/* 使能預取址緩存 */FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);/* 設置PLL時鐘源為HSE倍頻9 72MHz */RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);/* 使能PLL */RCC_PLLCmd(ENABLE);/* 等待PLL穩定 */while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);/* 設置PLL為系統時鐘源 */RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);/* 等待系統時鐘源切換到PLL */while(RCC_GetSYSCLKSource() != 0x08);} }/* GPIO配置 */ void GPIO_config(void) {GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_8| GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOD, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;GPIO_Init(GPIOE, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;GPIO_Init(GPIOF, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_10;GPIO_Init(GPIOG, &GPIO_InitStructure); }/* FSMC配置 */ void FSMC_SRAM_Init(void) {FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;FSMC_NORSRAMTimingInitTypeDef readTiming;FSMC_NORSRAMTimingInitTypeDef WriteTiming;RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3; //BankFSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; //數據和地址線是否復用FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM; //存儲器類型FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; //存儲器數據寬度 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; //WAIT信號有效時機(突發模式下)FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; //是否允許寫操作FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; //是否使用WAIT信號(突發模式下)FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Enable; //是否使用讀寫不同時序FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; //是否允許突發寫操作readTiming.FSMC_AddressSetupTime = 0x00; //地址建立時間readTiming.FSMC_AddressHoldTime = 0x00; //地址保持時間readTiming.FSMC_DataSetupTime = 0x02; //數據保持時間readTiming.FSMC_BusTurnAroundDuration = 0x00;readTiming.FSMC_CLKDivision = 0x00;readTiming.FSMC_DataLatency = 0x00;readTiming.FSMC_AccessMode = FSMC_AccessMode_A; //模式AWriteTiming.FSMC_AddressSetupTime = 0x00; //地址建立時間WriteTiming.FSMC_AddressHoldTime = 0x00; //地址保持時間WriteTiming.FSMC_DataSetupTime = 0x04; //數據保持時間WriteTiming.FSMC_BusTurnAroundDuration = 0x00;WriteTiming.FSMC_CLKDivision = 0x00;WriteTiming.FSMC_DataLatency = 0x00;WriteTiming.FSMC_AccessMode = FSMC_AccessMode_A; //模式A FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &readTiming;FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &WriteTiming;FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE); }uint8_t testsram[1000000] __attribute__((at(0x68000000))); uint8_t test;int main(void) { uint8_t count = 0;/* 時鐘配置 */RCC_config();/* GPIO配置 */GPIO_config();/* FSMC配置 */FSMC_SRAM_Init();for(uint32_t ts = 0; ts < 1000000; ts++)testsram[ts] = count++;for(uint32_t ts = 0; ts < 1000000; ts++)test = testsram[ts];while(1){} }?
總結
以上是生活随笔為你收集整理的STM32之FSMC-SRAM例程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 双极结型三极管及放大电路基础
- 下一篇: 从0到1:Python爬虫知识点梳理