STM32f746gdiscovery 开发板使用的是16MB的SDRAM,由于少了一根地址线,只有8MB可用。
- /*************************************************************************************************************
- * 文件名 : stm32f7_sdram.c
- * 功能 : STM32F7 外部SDRAM驱动
- * 作者 : <a href="mailto:cp1300@139.com">cp1300@139.com</a>
- * 创建时间 : 2019-09-08
- * 最后修改时间 : 2019-09-08
- * 详细 : 2019-10-31 设置突发长度:4(可以是1/2/4/8)-测试过1/2/4发现都正常,唯独8的时候,屏幕会出现随机噪点
- *************************************************************************************************************/
- #include "stm32f7_sdram.h"
- #include "SYSTEM.H"
- //BANK选择
- typedef enum
- {
- SDRAM_CMD_BANK1 = 2, //命令模板存储区域1
- SDRAM_CMD_BANK2 = 1, //命令模板存储区域2
- SDRAM_CMD_BANK1_2 = 3, //命令模板存储区域1与2
- }SDRAM_CMD_BANK_SELECT;
- //命令
- typedef enum
- {
- SDRAM_CMD_NORMAL = 0, //正常模式
- SDRAM_CMD_CLOCK_CONFIG = 1, //时钟配置使能
- SDRAM_CMD_PALL = 2, //预充电所有存储区域
- SDRAM_CMD_AR = 3, //自刷新命令
- SDRAM_CMD_LOAD_MODE = 4, //加载模式寄存器
- //SDRAM_CMD_AR = 5, //自刷新命令
- SDRAM_CMD_POWER_DOWN = 6, //掉电命令
- }SDRAM_CMD_TYPE;
- bool SDRAM_SendCmd(SDRAM_CMD_BANK_SELECT BankSelect, u16 mode, u8 AutoRefresh, SDRAM_CMD_TYPE cmd);//SDRAM 命令模式设置
- /*************************************************************************************************************************
- * 函数 : void SDRAM_Init(void)
- * 功能 : SDRAM 接口初始化
- * 参数 : 无
- * 返回 : 无
- * 依赖 : 底层宏定义
- * 作者 : <a href="mailto:cp1300@139.com">cp1300@139.com</a>
- * 时间 : 2019-09-08
- * 最后修改时间 : 2019-09-08
- * 说明 : 用于初始化STM32F7 SDRAM 接口
- *************************************************************************************************************************/
- void SDRAM_Init(void)
- {
- u32 temp;
-
- SYS_DeviceClockEnable(DEV_FSMC, TRUE); //FSMC时钟使能
- SYS_DeviceClockEnable(DEV_GPIOC, TRUE); //使能GPIOC时钟
- SYS_DeviceClockEnable(DEV_GPIOD, TRUE); //使能GPIOD时钟
- SYS_DeviceClockEnable(DEV_GPIOE, TRUE); //使能GPIOE时钟
- SYS_DeviceClockEnable(DEV_GPIOF, TRUE); //使能GPIOF时钟
- SYS_DeviceClockEnable(DEV_GPIOG, TRUE); //使能GPIOG时钟
- SYS_DeviceClockEnable(DEV_GPIOH, TRUE); //使能GPIOH时钟
-
- //初始化IO
- SYS_GPIOx_Init(GPIOC, BIT3, AF_PP_OPU, SPEED_100M); //PC3
- SYS_GPIOx_Init(GPIOD, BIT0|BIT1|BIT8|BIT9|BIT10|BIT14|BIT15, AF_PP_OPU, SPEED_100M); //PD0/1/8/9/10/14/15
- SYS_GPIOx_Init(GPIOE, BIT0|BIT1|(0X1FF<<7), AF_PP_OPU, SPEED_100M); //PE0/1/7~15
- SYS_GPIOx_Init(GPIOF, BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT11|BIT12|BIT13|BIT14|BIT15, AF_PP_OPU, SPEED_100M); //PF0~5/11~15
- SYS_GPIOx_Init(GPIOG, BIT0|BIT1|BIT4|BIT5|BIT8|BIT15, AF_PP_OPU, SPEED_100M); //PG0/1/4/5/8/15
- SYS_GPIOx_Init(GPIOH, BIT3|BIT5, AF_PP_OPU, SPEED_100M);
-
- SYS_GPIOx_SetAF(GPIOC, 3, AF12_FSMC); //PC3,AF12
-
- SYS_GPIOx_SetAF(GPIOD, 0, AF12_FSMC); //PD0,AF12
- SYS_GPIOx_SetAF(GPIOD, 1, AF12_FSMC); //PD1,AF12
- SYS_GPIOx_SetAF(GPIOD, 8, AF12_FSMC); //PD8,AF12
- SYS_GPIOx_SetAF(GPIOD, 9, AF12_FSMC); //PD9,AF12
- SYS_GPIOx_SetAF(GPIOD, 10, AF12_FSMC); //PD10,AF12
- SYS_GPIOx_SetAF(GPIOD, 14, AF12_FSMC); //PD14,AF12
- SYS_GPIOx_SetAF(GPIOD, 15, AF12_FSMC); //PD15,AF12
-
- SYS_GPIOx_SetAF(GPIOE, 0, AF12_FSMC); //PE0,AF12
- SYS_GPIOx_SetAF(GPIOE, 1, AF12_FSMC); //PE1,AF12
- SYS_GPIOx_SetAF(GPIOE, 7, AF12_FSMC); //PE7,AF12
- SYS_GPIOx_SetAF(GPIOE, 8, AF12_FSMC); //PE8,AF12
- SYS_GPIOx_SetAF(GPIOE, 9, AF12_FSMC); //PE9,AF12
- SYS_GPIOx_SetAF(GPIOE, 10, AF12_FSMC); //PE10,AF12
- SYS_GPIOx_SetAF(GPIOE, 11, AF12_FSMC); //PE11,AF12
- SYS_GPIOx_SetAF(GPIOE, 12, AF12_FSMC); //PE12,AF12
- SYS_GPIOx_SetAF(GPIOE, 13, AF12_FSMC); //PE13,AF12
- SYS_GPIOx_SetAF(GPIOE, 14, AF12_FSMC); //PE14,AF12
- SYS_GPIOx_SetAF(GPIOE, 15, AF12_FSMC); //PE15,AF12
- SYS_GPIOx_SetAF(GPIOF, 0, AF12_FSMC); //PF0,AF12
- SYS_GPIOx_SetAF(GPIOF, 1, AF12_FSMC); //PF1,AF12
- SYS_GPIOx_SetAF(GPIOF, 2, AF12_FSMC); //PF2,AF12
- SYS_GPIOx_SetAF(GPIOF, 3, AF12_FSMC); //PF3,AF12
- SYS_GPIOx_SetAF(GPIOF, 4, AF12_FSMC); //PF4,AF12
- SYS_GPIOx_SetAF(GPIOF, 5, AF12_FSMC); //PF5,AF12
- SYS_GPIOx_SetAF(GPIOF, 11, AF12_FSMC); //PF11,AF12
- SYS_GPIOx_SetAF(GPIOF, 12, AF12_FSMC); //PF12,AF12
- SYS_GPIOx_SetAF(GPIOF, 13, AF12_FSMC); //PF13,AF12
- SYS_GPIOx_SetAF(GPIOF, 14, AF12_FSMC); //PF14,AF12
- SYS_GPIOx_SetAF(GPIOF, 15, AF12_FSMC); //PF15,AF12
-
- SYS_GPIOx_SetAF(GPIOG, 0, AF12_FSMC); //PG0,AF12
- SYS_GPIOx_SetAF(GPIOG, 1, AF12_FSMC); //PG1,AF12
- SYS_GPIOx_SetAF(GPIOG, 4, AF12_FSMC); //PG4,AF12
- SYS_GPIOx_SetAF(GPIOG, 5, AF12_FSMC); //PG5,AF12
- SYS_GPIOx_SetAF(GPIOG, 8, AF12_FSMC); //PG8,AF12
- SYS_GPIOx_SetAF(GPIOG, 15, AF12_FSMC); //PG15,AF12
-
- SYS_GPIOx_SetAF(GPIOH, 3, AF12_FSMC); //PH3,AF12
- SYS_GPIOx_SetAF(GPIOH, 5, AF12_FSMC); //PH5,AF12
-
- temp = 0;
- temp |= 0<<0; //8位列地址
- temp |= 1<<2; //12位行地址
- temp |= 1<<4; //16位数据位宽
- temp |= 1<<6; //4个内部存区(4 BANKS)
- temp |= 2<<7; //2个CAS延迟
- temp |= 0<<9; //允许写访问
- temp |= 2<<10; //SDRAM时钟=HCLK/2
- temp |= 1<<12; //使能突发访问
- temp |= 0<<13; //读通道延迟0个HCLK
- FMC_Bank5_6->SDCR[0] = temp; //设置FMC BANK5 SDRAM控制寄存器(BANK5和6用于管理SDRAM).
- temp = 0;
- temp|=1<<0; //加载模式寄存器到激活时间的延迟为2个时钟周期
- temp|=5<<4; //退出自刷新延迟为6个时钟周期
- temp|=3<<8; //自刷新时间为4个时钟周期
- temp|=5<<12; //行循环延迟为6个时钟周期
- temp|=1<<16; //恢复延迟为2个时钟周期
- temp|=1<<20; //行预充电延迟为2个时钟周期
- temp|=1<<24; //行到列延迟为2个时钟周期
- FMC_Bank5_6->SDTR[0] = temp; //设置FMC BANK5 SDRAM时序寄存器
- SDRAM_SendCmd(SDRAM_CMD_BANK1, 0, 1, SDRAM_CMD_CLOCK_CONFIG); //时钟配置使能
- Delay_US(300); //至少延迟200us.
- SDRAM_SendCmd(SDRAM_CMD_BANK1,0, 1, SDRAM_CMD_PALL); //对所有存储区预充电
- SDRAM_SendCmd(SDRAM_CMD_BANK1,0, 8, SDRAM_CMD_AR); //设置自刷新次数
-
- temp = 0;
- temp |= 2<<0; //设置突发长度:4(可以是1/2/4/8) -测试过1/2/4发现都正常,唯独8的时候,屏幕会出现随机噪点
- temp |= 0<<3; //设置突发类型:连续(可以是连续/交错)
- temp |= 2<<4; //设置CAS值:2
- temp |= 0<<7; //设置操作模式:0,标准模式
- temp |= 1<<9; //设置突发写模式:1,单点访问
- SDRAM_SendCmd(SDRAM_CMD_BANK1,temp, 1, SDRAM_CMD_LOAD_MODE); //设置SDRAM模式
-
- //COUNT=SDRAM刷新周期/行数-20
- //SDRAM刷新周期为64ms,SDCLK=AHB/2=100Mhz,行数为4096.
- //计算方法为64*1000*AHB/2/4096-20
- temp = 64*1000*(SYS_GetAHBClockSpeed()/1000000/2)/4096-20;
- FMC_Bank5_6->SDRTR = temp<<1; //设置刷新频率计数器
- }
- /*************************************************************************************************************************
- * 函数 : bool SDRAM_SendCmd(SDRAM_CMD_BANK_SELECT BankSelect, u16 mdr, u8 AutoRefresh, SDRAM_CMD_TYPE mode)
- * 功能 : SDRAM 命令模式设置
- * 参数 : BankSelect:bank选择;mdr:模式;AutoRefresh:自刷新设置;mode:模式命令
- * 返回 : TRUE:成功;FALSE:失败
- * 依赖 : 底层宏定义
- * 作者 : <a href="mailto:cp1300@139.com">cp1300@139.com</a>
- * 时间 : 2019-09-08
- * 最后修改时间 : 2019-09-08
- * 说明 :
- *************************************************************************************************************************/
- bool SDRAM_SendCmd(SDRAM_CMD_BANK_SELECT BankSelect, u16 mdr, u8 AutoRefresh, SDRAM_CMD_TYPE mode)
- {
- u32 retry=0;
- u32 temp = 0;
-
- temp |= mode<<0; //设置指令
- temp |= BankSelect<<3; //设置发送指令到bank5还是6
- temp |= (AutoRefresh&0xf)<<5; //设置自刷新次数
- temp |= mdr<<9; //设置模式寄存器的值
- FMC_Bank5_6->SDCMR = temp; //配置寄存器
-
- //temp = FMC_Bank5_6->SDCMR;
- //uart_printf("FMC_Bank5_6->SDCMR=%X\r\n", temp);
- while((FMC_Bank5_6->SDSR&(1<<5))) //等待指令发送完成
- {
- retry++;
- Delay_US(1);
- if(retry > 50000)return FALSE;
- }
-
-
- return TRUE;
- }
复制代码
- /*************************************************************************************************************
- * 文件名 : stm32f7_sdram.h
- * 功能 : STM32F7 外部SDRAM驱动
- * 作者 : <a href="mailto:cp1300@139.com">cp1300@139.com</a>
- * 创建时间 : 2019-09-08
- * 最后修改时间 : 2019-09-08
- * 详细:
- *************************************************************************************************************/
- #ifndef __STM32F7_SDRAM_H_
- #define __STM32F7_SDRAM_H_
- #include "system.h"
- //========================================================================
- // SRAM硬件相关配置
- //------------------------------------------------------------------------
- #define Bank5_SDRAM_ADDR ((u32)0XC0000000)
-
- void SDRAM_Init(void); //SDRAM初始化
- #endif //__STM32F7_SDRAM_H_
复制代码
|