OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4353|回复: 9

F429 FMC SDRAM 数据写入惊现诡异现象 , 困扰多日,求原子大神及路过大神援助!

[复制链接]

3

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
64
金钱
64
注册时间
2017-2-16
在线时间
16 小时
发表于 2017-3-2 09:43:58 | 显示全部楼层 |阅读模式
5金钱


在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]





正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

88

主题

7377

帖子

5

精华

资深版主

Rank: 8Rank: 8

积分
14980
金钱
14980
注册时间
2013-11-13
在线时间
1823 小时
发表于 2017-3-2 09:58:44 | 显示全部楼层
硬件焊接什么的都检查一遍。
回复

使用道具 举报

88

主题

7377

帖子

5

精华

资深版主

Rank: 8Rank: 8

积分
14980
金钱
14980
注册时间
2013-11-13
在线时间
1823 小时
发表于 2017-3-2 09:58:44 | 显示全部楼层
硬件焊接什么的都检查一遍。
回复

使用道具 举报

3

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
64
金钱
64
注册时间
2017-2-16
在线时间
16 小时
 楼主| 发表于 2017-3-2 10:13:49 | 显示全部楼层
zuozhongkai 发表于 2017-3-2 09:58
硬件焊接什么的都检查一遍。

硬件上是没有问题的,因为用ST官方的库函数版本同样的方式定义数组,读写数组,都OK。
回复

使用道具 举报

3

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
64
金钱
64
注册时间
2017-2-16
在线时间
16 小时
 楼主| 发表于 2017-3-2 10:21:20 | 显示全部楼层
zuozhongkai 发表于 2017-3-2 09:58
硬件焊接什么的都检查一遍。

大神还有其他方面的建议么?
回复

使用道具 举报

3

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
64
金钱
64
注册时间
2017-2-16
在线时间
16 小时
 楼主| 发表于 2017-3-2 16:30:35 | 显示全部楼层
路过的大神请看一眼~
回复

使用道具 举报

3

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
64
金钱
64
注册时间
2017-2-16
在线时间
16 小时
 楼主| 发表于 2017-3-3 17:42:41 | 显示全部楼层
有人么?
回复

使用道具 举报

16

主题

216

帖子

1

精华

高级会员

Rank: 4

积分
970
金钱
970
注册时间
2016-11-24
在线时间
156 小时
发表于 2017-3-4 09:55:32 | 显示全部楼层
建议你检查一下这个SDRAM的引脚布线是否和其他芯片的有冲突,比如弄成了上下层交叉造成干扰什么的,我之前用外部SRAM芯片时,也遇到了很诡异的问题,数据读写等各方面正常,但是一旦整体用起来就死。后来检查结果是声卡的I2S_MCLK和SRAM芯片的数据走线产生了干扰导致,遇到这种问题时完全是懵的,希望对你有帮助吧
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2017-3-4 12:08:49 | 显示全部楼层
你用ST库函数没问题,那你对比下和官方库代码的差异,就知道问题点了。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

3

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
64
金钱
64
注册时间
2017-2-16
在线时间
16 小时
 楼主| 发表于 2017-3-6 08:38:32 | 显示全部楼层
lzq12 发表于 2017-3-4 09:55
建议你检查一下这个SDRAM的引脚布线是否和其他芯片的有冲突,比如弄成了上下层交叉造成干扰什么的,我之前 ...

感谢回复!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-19 08:02

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表