在SDRAM里面定义的数组写入数据的时候,
0xD0000000总是与0xD00000008联动
0xD0000002总是与0xD0000000A联动
。。。。。以此类推。
写入0xD0000000的时候,0xD00000008也会同步写入。等写到0xD00000008的时候,0xD0000000也会发生改变。不论定义的数据类型是字、字节或者是双字,非常奇怪!
在调试窗口下,可以看到数据改变:
如果定义的是U16的数组,则数据如下:
0xD0000000 : 04 00
0xD0000002 : 05 00
0xD0000004 : 06 00
0xD0000006 : 07 00
0xD0000008 : 04 00
0xD000000A : 05 00
0xD000000C : 06 00
0xD000000E : 07 00
0xD0000010 : 0C 00
。。。。。
如果定义的是U32的数组,则数据如下:
0xD0000000 : 02 00 00 00
0xD0000004 : 03 00 00 00
0xD0000008 : 02 00 00 00
0xD000000C : 03 00 00 00
0xD0000010 : 06 00 00 00
。。。。。
本人用的SDRAM型号是IS42S16400J,接的bank2。
硬件上是没有问题的,因为用ST官方的库函数版本同样的方式定义数组,读写数组,都OK。
时序配置上也是没有问题的,用单步调试模式,查看过SDRAM所有的寄存器配置,SDCR1/2、SDTR1/2、SDCMR(初始化过程中5次命令都已对比无异常)、SDRTR。这些寄存器都与官方库函数在程序运行时仔细对比过,已改为全部一致!
降低工作频率也于事无补!
另外试过把SDRAM的CKE1/NE1跳线到 CKE0/NE0上,用原子大神的寄存器源程序(稍作时序修改)也是有同样的问题!
实在找不到问题的原因,非常诡异!还求原子大神与路过的大神指点!!
SDRAM.C
[mw_shl_code=applescript,true]#include "sdram.h"
#include "delay.h"
#include "usart.h"
//向SDRAM发送命令
//bankx:0,向BANK5上面的SDRAM发送指令
// 1,向BANK6上面的SDRAM发送指令
//cmd:指令(0,正常模式/1,时钟配置使能/2,预充电所有存储区/3,自动刷新/4,加载模式寄存器/5,自刷新/6,掉电)
//refresh:自刷新次数(cmd=3时有效)
//regval:模式寄存器的定义
//返回值:0,正常;1,失败.
u8 SDRAM_Send_Cmd(u8 bankx,u8 cmd,u8 refresh,u16 regval)
{
u32 retry=0;
u32 tempreg=0;
tempreg|=cmd<<0; //设置指令
tempreg|=1<<(4-bankx); //设置发送指令到bank5还是6
tempreg|=refresh<<5; //设置自刷新次数
tempreg|=regval<<9; //设置模式寄存器的值
FMC_Bank5_6->SDCMR=tempreg; //配置寄存器
while((FMC_Bank5_6->SDSR&(1<<5)))//等待指令发送完成
{
retry++;
if(retry>0X1FFFFF)return 1;
}
return 0;
}
//SDRAM初始化
void SDRAM_Init(void)
{
u32 sdctrlreg=0,sdtimereg=0;
u16 mregval=0;
RCC->AHB3ENR|=1<<0; //使能FMC时钟
RCC->AHB1ENR|=0X3F<<1; //使能PB/PC/PD/PE/PF/PG时钟
GPIO_Set(GPIOB,PIN5|PIN6,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU); //PB5/6
GPIO_Set(GPIOC,PIN0|PIN2|PIN3,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU); //PC0
GPIO_Set(GPIOD,3<<0|7<<8|3<<14,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU); //PD0/1/8/9/10/14/15
GPIO_Set(GPIOE,3<<0|0X1FF<<7,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU); //PE0/1/7~15
GPIO_Set(GPIOF,0X3B<<0|0X1F<<11,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU); //PG0/1/3/4/5/11~15
GPIO_Set(GPIOG,3<<0|3<<4|PIN8|PIN15,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU); //PF0~1/4/5/8/15
GPIO_AF_Set(GPIOB,5,12); //PB5,AF12 SDCKE1
GPIO_AF_Set(GPIOB,6,12); //PB6,AF12 SDNE1/CS#
GPIO_AF_Set(GPIOC,0,12); //PC0,AF12
// GPIO_AF_Set(GPIOC,2,12); //PC0,AF12 SDNE0
// GPIO_AF_Set(GPIOC,3,12); //PC0,AF12 SDCKE0
GPIO_AF_Set(GPIOD,0,12); //PD0,AF12
GPIO_AF_Set(GPIOD,1,12); //PD1,AF12
GPIO_AF_Set(GPIOD,8,12); //PD8,AF12
GPIO_AF_Set(GPIOD,9,12); //PD9,AF12
GPIO_AF_Set(GPIOD,10,12); //PD10,AF12
GPIO_AF_Set(GPIOD,14,12); //PD14,AF12
GPIO_AF_Set(GPIOD,15,12); //PD15,AF12
GPIO_AF_Set(GPIOE,0,12); //PE0,AF12
GPIO_AF_Set(GPIOE,1,12); //PE1,AF12
GPIO_AF_Set(GPIOE,7,12); //PE7,AF12
GPIO_AF_Set(GPIOE,8,12); //PE8,AF12
GPIO_AF_Set(GPIOE,9,12); //PE9,AF12
GPIO_AF_Set(GPIOE,10,12); //PE10,AF12
GPIO_AF_Set(GPIOE,11,12); //PE11,AF12
GPIO_AF_Set(GPIOE,12,12); //PE12,AF12
GPIO_AF_Set(GPIOE,13,12); //PE13,AF12
GPIO_AF_Set(GPIOE,14,12); //PE14,AF12
GPIO_AF_Set(GPIOE,15,12); //PE15,AF12
GPIO_AF_Set(GPIOF,0,12); //PF0,AF12
GPIO_AF_Set(GPIOF,1,12); //PF1,AF12
GPIO_AF_Set(GPIOF,2,12); //PF2,AF12
GPIO_AF_Set(GPIOF,3,12); //PF3,AF12
GPIO_AF_Set(GPIOF,4,12); //PF4,AF12
GPIO_AF_Set(GPIOF,5,12); //PF5,AF12
GPIO_AF_Set(GPIOF,11,12); //PF11,AF12
GPIO_AF_Set(GPIOF,12,12); //PF12,AF12
GPIO_AF_Set(GPIOF,13,12); //PF13,AF12
GPIO_AF_Set(GPIOF,14,12); //PF14,AF12
GPIO_AF_Set(GPIOF,15,12); //PF15,AF12
GPIO_AF_Set(GPIOG,0,12); //PG0,AF12
GPIO_AF_Set(GPIOG,1,12); //PG1,AF12
GPIO_AF_Set(GPIOG,4,12); //PG4,AF12
GPIO_AF_Set(GPIOG,5,12); //PG5,AF12
GPIO_AF_Set(GPIOG,8,12); //PG8,AF12 FMC_SDCLK
GPIO_AF_Set(GPIOG,15,12); //PG15,AF12
sdctrlreg|=0<<0; //8位列地址
sdctrlreg|=1<<2; //12位行地址
sdctrlreg|=1<<4; //16位数据位宽
sdctrlreg|=1<<6; //4个内部存区(4 BANKS)
sdctrlreg|=3<<7; //3个CAS延迟
sdctrlreg|=0<<9; //允许写访问
sdctrlreg|=2<<10; //SDRAM时钟=HCLK/2=192M/2=96M=10.4ns
sdctrlreg|=1<<12; //使能突发访问
sdctrlreg|=1<<13; //读通道延迟0个HCLK
// FMC_Bank5_6->SDCR[0]=sdctrlreg; //设置FMC BANK5 SDRAM控制寄存器(BANK5和6用于管理SDRAM).在FMC_SDCR2中配置是不生效的!必须到FMC_SDCR1中去配置才行!
// FMC_Bank5_6->SDCR[1]=sdctrlreg; //设置FMC BANK5 SDRAM控制寄存器(BANK5和6用于管理SDRAM).
FMC_Bank5_6->SDCR[0]=0x00002800;
FMC_Bank5_6->SDCR[1]=0x000001D4;
sdtimereg|=1<<0; //加载模式寄存器到激活时间的延迟为2个时钟周期 TMRD
sdtimereg|=6<<4; //退出自刷新延迟为7个时钟周期
sdtimereg|=3<<8; //自刷新时间为4个时钟周期
sdtimereg|=6<<12; //行循环延迟为6个时钟周期
sdtimereg|=1<<16; //恢复延迟为2个时钟周期
sdtimereg|=1<<20; //行预充电延迟为2个时钟周期
sdtimereg|=1<<24; //行到列延迟为2个时钟周期
// FMC_Bank5_6->SDTR[0]=sdtimereg; //设置FMC BANK5 SDRAM时序寄存器/ FMC_Bank5_6->SDTR[1]=sdtimereg; //设置FMC BANK5 SDRAM时序寄存器
FMC_Bank5_6->SDTR[0]=0x00106000;
FMC_Bank5_6->SDTR[1]=0x00010361;
SDRAM_Send_Cmd(1,1,0,0); //时钟配置使能
delay_us(200); //至少延迟100us.
SDRAM_Send_Cmd(1,2,0,0); //对所有存储区预充电
SDRAM_Send_Cmd(1,3,3,0); //设置自刷新次数 第一次
SDRAM_Send_Cmd(1,3,3,0); //设置自刷新次数 第二次
mregval|=1<<0; //设置突发长度:2(可以是1/2/4/8)
mregval|=0<<3; //设置突发类型:连续(可以是连续/交错)
mregval|=3<<4; //设置CAS值:3(可以是2/3)
mregval|=0<<7; //设置操作模式:0,标准模式
mregval|=1<<9; //设置突发写模式:1,单点访问
SDRAM_Send_Cmd(1,4,0,mregval); //设置SDRAM的模式寄存器
FMC_Bank5_6->SDRTR=1386<<1; //设置刷新频率计数器
// FMC_Bank5_6->SDRTR=0x00000AD4;
}
[/mw_shl_code]
MAIN.C
[mw_shl_code=applescript,true]u32 testsram[100] __attribute__((at(0XD0000000)));
int main(void)
{
u8 keysta;
u32 ii=0;
u32 ts=0;
u32 i=0;
Stm32_Clock_Init(360,8,2,8); //设置时钟AHB=180M,APB1=45M,APB1_TIM=90M,APB2=90M,APB2_TIM=180M
delay_init(180);
SDRAM_Init();
for(ts=0;ts<100;ts++)
{
testsram[ts]=ts;
}
while(1)
{}
}[/mw_shl_code]
硬件上是没有问题的,因为用ST官方的库函数版本同样的方式定义数组,读写数组,都OK。
大神还有其他方面的建议么?
一周热门 更多>