基于STM32F429的SDRAM使用
使用ST的HAL庫進(jìn)行開發(fā),SDRAM使用的是W9825G6KH-6。
W9825G6KH-6共有4個(gè)Bank,13位行地址,9位列地址,位寬是16位,
所以芯片的容量是:4x8192x512x16=256Mbits=32MBytes。
W9825G6KH-6的原理圖如下:
FMC_D0~15:16位數(shù)據(jù)線;
FMC_A0~12:13位地址線,行地址與列地址是公用的,作為行地址時(shí)使用了0~12位,作為列地址時(shí)使用了0~8位;
FMC_SDNWE:低電平時(shí)寫,高電平時(shí)讀;
FMC_SDNCAS:列地址選通信號(hào),低電平有效;
FMC_SDNRAS:行地址選通信號(hào),低電平有效;
FMC_SDNE0:片選信號(hào),低電平有效;
FMC_BA0~1:Bank選擇信號(hào);
FMC_SDCKE0:時(shí)鐘使能信號(hào);
FMC_SDCLK:時(shí)鐘信號(hào);
FMC_NBL0~1:寫訪問的輸出字節(jié)屏蔽。
STM32F429自帶FMC外設(shè),可以對(duì)多種外部存儲(chǔ)器進(jìn)行控制,存儲(chǔ)區(qū)域?qū)?yīng)如下:
我們使用的是Bank5,也就是SDRAM Bank1。
我們要做的就是對(duì)SDRAM進(jìn)行初始化配置,初始化成功后即可對(duì)指定的內(nèi)存進(jìn)行訪問,單片機(jī)和外部SDRAM之間的讀寫時(shí)序
是由外設(shè)自動(dòng)產(chǎn)生的,不需要程序進(jìn)行控制,非常方便。
STM32F4xx參考手冊(cè)中對(duì)SDRAM的初始化過程如下:
使用STM32CubeMx生成FMC的初始化代碼,如下:
void MX_FMC_Init(void) {FMC_SDRAM_TimingTypeDef SdramTiming;/** Perform the SDRAM1 memory initialization sequence*/hsdram1.Instance = FMC_SDRAM_DEVICE;/* hsdram1.Init */hsdram1.Init.SDBank = FMC_SDRAM_BANK1; //使用SDRAM Bank1hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9; //列寬度9位hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_13; //行寬度13位hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16; //數(shù)據(jù)總線為16位hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4; //SDRAM內(nèi)部Bank數(shù)為4個(gè)hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_3; //CAS為3,表示發(fā)送完讀時(shí)序后延遲3個(gè)時(shí)鐘周期返回?cái)?shù)據(jù)hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE; //忽略寫保護(hù)hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2; //SDRAM時(shí)鐘SDCLK = HCLK/2 = 180MHz / 2 = 90MHzhsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE; //失能突然讀模式hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_1; //讀通道延時(shí)1個(gè)時(shí)鐘周期,在CAS延時(shí)后延時(shí)讀取數(shù)據(jù)的時(shí)鐘個(gè)數(shù)/* SdramTiming */SdramTiming.LoadToActiveDelay = 2; //TMRD/TRSC,2個(gè)時(shí)鐘周期SdramTiming.ExitSelfRefreshDelay = 8; //TXSR,8個(gè)時(shí)鐘周期SdramTiming.SelfRefreshTime = 6; //TRAS,6個(gè)時(shí)鐘周期SdramTiming.RowCycleDelay = 6; //TRC,6個(gè)時(shí)鐘周期SdramTiming.WriteRecoveryTime = 4; //TWR,4個(gè)時(shí)鐘周期SdramTiming.RPDelay = 2; //TRP,2個(gè)時(shí)鐘周期SdramTiming.RCDDelay = 2; //TRCD,2個(gè)時(shí)鐘周期if (HAL_SDRAM_Init(&hsdram1, &SdramTiming) != HAL_OK){_Error_Handler(__FILE__, __LINE__);} }
上述FMC的初始化代碼完成了SDRAM初始化中的1、2兩個(gè)步驟;
接下來添加SDRAM初始化中的步驟3~8:
uint8_t SDRAM_SendCommand(uint32_t CommandMode, uint32_t Bank, uint32_t RefreshNum, uint32_t RegVal) {uint32_t CommandTarget;FMC_SDRAM_CommandTypeDef Command;if(Bank == 1)CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;else if(Bank == 2)CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;Command.CommandMode = CommandMode;Command.CommandTarget = CommandTarget;Command.AutoRefreshNumber = RefreshNum;Command.ModeRegisterDefinition = RegVal;if(HAL_SDRAM_SendCommand(&hsdram1, &Command, 0x1000) == HAL_OK)return 1;elsereturn 0; } void SDRAM_Init(void) {uint32_t temp;SDRAM_SendCommand(FMC_SDRAM_CMD_CLK_ENABLE, 1, 1, 0); //步驟3:使能時(shí)鐘信號(hào),SDCKE0 = 1Delay_us(500); //步驟4:至少延時(shí)200usSDRAM_SendCommand(FMC_SDRAM_CMD_PALL, 1, 1, 0); //步驟5:發(fā)送全部預(yù)充電命令SDRAM_SendCommand(FMC_SDRAM_CMD_AUTOREFRESH_MODE, 1, 8, 0); //步驟6:設(shè)置自動(dòng)刷新次數(shù)temp = SDRAM_MODEREG_BURST_LENGTH_1 | //設(shè)置突發(fā)長度:1SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL | //設(shè)置突發(fā)類型:連續(xù)SDRAM_MODEREG_CAS_LATENCY_3 | //設(shè)置CAS值:3SDRAM_MODEREG_OPERATING_MODE_STANDARD | //設(shè)置操作模式:標(biāo)準(zhǔn)SDRAM_MODEREG_WRITEBURST_MODE_SINGLE; //設(shè)置突發(fā)寫模式:單點(diǎn)訪問SDRAM_SendCommand(FMC_SDRAM_CMD_LOAD_MODE, 1, 1, temp); //步驟7:裝載模式寄存器的值//SDRAM刷新周期是64ms,行數(shù)是8192行,時(shí)鐘頻率是180MHz/2=90MHz//所有COUNT = (64ms/8192)/(1/90us)-20 = 64000*90/8192-20 = 683HAL_SDRAM_ProgramRefreshRate(&hsdram1, 683); //步驟8:設(shè)置刷新速率 }
函數(shù)SDRAM_SendCommand()用來發(fā)送命令,內(nèi)部調(diào)用了HAL的庫函數(shù)HAL_SDRAM_SendCommand()發(fā)送配置命令;
函數(shù)SDRAM_Init()完成了SDRAM初始化中的步驟3~8。
至此,我們就完成了對(duì)SDRAM的初始化操作,此時(shí)外部SDRAM已經(jīng)被映射到了相應(yīng)的內(nèi)存地址;需要注意的是,
SDRAM Bank1的地址是從0xC0000000~0xCFFFFFFF,SDRAM Bank2的地址是從0xD0000000~0xDFFFFFFF,
我們使用的是SDRAM Bank1,并且外部SDRAM的大小是32M字節(jié),所以對(duì)應(yīng)的內(nèi)存地址范圍是0xC0000000~0xC1FFFFFF。
接下來就測(cè)試一下SDRAM的讀寫:
。
。
SDRAM測(cè)試結(jié)束。
總結(jié)
以上是生活随笔為你收集整理的基于STM32F429的SDRAM使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一个SRM系统应该包含哪些模块?
- 下一篇: mklink 创建链接(当文件已存在时,