OpenEdv-开源电子网

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

STM32F103ZET6的外部SRAM写入一直不对,数据覆盖且偶数地址写不进

[复制链接]

1

主题

10

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2014-1-5
在线时间
2 小时
发表于 2015-4-28 09:50:11 | 显示全部楼层 |阅读模式
5金钱
外部RAM的扩展参考战舰版的硬件电路:


驱动程序代码也是参考战舰版的:
sram.c文件内容:
[mw_shl_code=c,true]#include "sram.h" //使用NOR/SRAM的 Bank1.sector3,地址位HADDR[27,26]=10 //对IS61LV25616/IS62WV25616,地址线范围为A0~A17 //对IS61LV51216/IS62WV51216,地址线范围为A0~A18 #define Bank1_SRAM3_ADDR ((u32)(0x68000000)) //初始化外部SRAM void FSMC_SRAM_Init(void) { FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure; FSMC_NORSRAMTimingInitTypeDef readWriteTiming; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOF|RCC_APB2Periph_GPIOG,ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC,ENABLE); GPIO_InitStructure.GPIO_Pin = 0xFF33; //PORTD复用推挽输出 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOD, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = 0xFF83; //PORTE复用推挽输出 GPIO_Init(GPIOE, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = 0xF03F; //PORTD复用推挽输出 GPIO_Init(GPIOF, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = 0x043F; //PORTD复用推挽输出 GPIO_Init(GPIOG, &GPIO_InitStructure); readWriteTiming.FSMC_AddressSetupTime = 0x00; //地址建立时间(ADDSET)为1个HCLK 1/36M=27ns readWriteTiming.FSMC_AddressHoldTime = 0x00; //地址保持时间(ADDHLD)模式A未用到 readWriteTiming.FSMC_DataSetupTime = 0x03; //数据保持时间(DATAST)为3个HCLK 4/72M=55ns(对EM的SRAM芯片) readWriteTiming.FSMC_BusTurnAroundDuration = 0x00; readWriteTiming.FSMC_CLKDivision = 0x00; readWriteTiming.FSMC_DataLatency = 0x00; readWriteTiming.FSMC_AccessMode = FSMC_AccessMode_A; //模式A FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3;// 这里我们使用NE3 ,也就对应BTCR[4],[5]。 FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; FSMC_NORSRAMInitStructure.FSMC_MemoryType =FSMC_MemoryType_SRAM;// FSMC_MemoryType_SRAM; //SRAM FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;//存储器数据宽度为16bit FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode =FSMC_BurstAccessMode_Disable;// 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; FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; //存储器写使能 FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; // 读写使用相同的时序 FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &readWriteTiming; FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &readWriteTiming; //读写同样时序 FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); //初始化FSMC配置 FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE); // 使能BANK3 } //在指定地址开始,连续写入n个字节. //pBuffer:字节指针 //WriteAddr:要写入的地址 //n:要写入的字节数 void FSMC_SRAM_WriteBuffer(u8* pBuffer,u32 WriteAddr,u32 n) { for(;n!=0;n--) { *(vu8*)(Bank1_SRAM3_ADDR+WriteAddr)=*pBuffer; WriteAddr ++; pBuffer++; } } //在指定地址开始,连续读出n个字节. //pBuffer:字节指针 //ReadAddr:要读出的起始地址 //n:要写入的字节数 void FSMC_SRAM_ReadBuffer(u8* pBuffer,u32 ReadAddr,u32 n) { for(;n!=0;n--) { *pBuffer++=*(vu8*)(Bank1_SRAM3_ADDR+ReadAddr); ReadAddr++;// } } //////////////////////////////////////////////////////////////////////////////////////// //测试函数 //在指定地址写入1个字节 //addr:地址 //data:要写入的数据 void fsmc_sram_test_write(u8 data,u32 addr) { FSMC_SRAM_WriteBuffer(&data,addr,1);//写入1个字节 } //读取1个字节 //addr:要读取的地址 //返回值:读取到的数据 u8 fsmc_sram_test_read(u32 addr) { u8 data; FSMC_SRAM_ReadBuffer(&data,addr,1); return data; } [/mw_shl_code]
主函数文件main.c程序:
[mw_shl_code=c,true]#include <stdio.h> #include "stm32f10x.h" #include "delay.h" #include "sram.h" #include "sbitdef.h" void System_ClockInit(void); void GPIO_Configurature(void); void USART_Configuration(void); void USART_SendString(USART_TypeDef* USARTx,const u8 *sendstr); int main(void) { u8 temp_write[40] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; System_ClockInit(); GPIO_Configurature(); USART_Configuration(); FSMC_SRAM_Init(); //初始化外部SRAM while(1) { FSMC_SRAM_WriteBuffer(temp_write,0,20); } } //主要完成时钟配置工作 void System_ClockInit(void) { RCC_DeInit(); RCC_HSEConfig(RCC_HSE_ON); //外部高速晶振启动 while(RCC_WaitForHSEStartUp() == ERROR);//等待HSE起振 FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);//使能FLASH预取指缓存 FLASH_SetLatency(FLASH_Latency_2);//设置FLASH存储器延时时钟周期数 RCC_HCLKConfig(RCC_SYSCLK_Div1);//设置AHB时钟为系统时钟 RCC_PCLK1Config(RCC_HCLK_Div2);//APB1的速度最高36M RCC_PCLK2Config(RCC_HCLK_Div1);//APB2的速度可达72M RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9); //锁相环设置,输入时钟源为外部晶振,倍频系数为9 RCC_PLLCmd(ENABLE); //使能锁相环,此处很重要,要先进行锁相环配置工作,再使能锁相环! while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //选择PLL作为系统时钟 } //配置PA9和PA10用于串口 void GPIO_Configurature(void) { GPIO_InitTypeDef GPIO_InitStructure;//定义一个初始化GPIO口的结构体 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOD,ENABLE);//使能GPIOA口的时钟 GPIO_StructInit(&GPIO_InitStructure);//将GPIO_InitStructure初始化为默认值 //初始化PD6口用于LED显示 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出模式 GPIO_Init(GPIOD,&GPIO_InitStructure); GPIO_SetBits(GPIOD,GPIO_Pin_6); //初始化PA9用于发送数据TXD GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出 GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA10用于接收数据RXD GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入 GPIO_Init(GPIOA,&GPIO_InitStructure); } void USART_Configuration(void) { USART_InitTypeDef USART_InitStructure; //定义初始化串口结构体 //初始化USART,9600,8数据位,1停止位,无校验 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1的时钟 USART_StructInit(&USART_InitStructure); USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_Mode = USART_Mode_Tx;//使能发送 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_Init(USART1,&USART_InitStructure); USART_Cmd(USART1,ENABLE);//使能USART1 USART_ClearFlag(USART1,USART_FLAG_TC); } //发送一个字符串 void USART_SendString(USART_TypeDef* USARTx,const u8 *sendstr) { u16 i; for( i = 0; sendstr != '\0'; i++) { USART_SendData(USARTx,sendstr); while(USART_GetFlagStatus(USARTx,USART_FLAG_TC) == RESET); } } [/mw_shl_code]
但是在使用Jlink和串口测试的时候发现:当仅写入一个地址数据的时候,偶数地址写不进,奇数地址可以写进,但是都可以读;如果连续写入n个地址数据,前面地址的数据都会被最后一个数据覆盖掉!而且FSMC上只挂了这个SRAM!网上查了很多资料也没找到,求高手们解答一下啊!(不会是硬件走线有问题吧?)

最佳答案

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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-4-28 09:50:12 | 显示全部楼层
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

1

主题

10

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2014-1-5
在线时间
2 小时
 楼主| 发表于 2015-4-28 09:50:12 | 显示全部楼层
补充一句,错误的原因是因为元件焊反了!IS62WV51216芯片表面有两个圆点,一定要注意哪个才是第一引脚!
回复

使用道具 举报

28

主题

1489

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1656
金钱
1656
注册时间
2013-7-24
在线时间
1 小时
发表于 2015-4-28 10:53:30 | 显示全部楼层
型号是原理图那个吗?
于20150522停用该账号:http://www.microstar.club
回复

使用道具 举报

1

主题

10

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2014-1-5
在线时间
2 小时
 楼主| 发表于 2015-4-28 11:39:23 | 显示全部楼层
回复【2楼】styleno1:
---------------------------------
是的啊,硬件软件都一样,所以才会很纠结!
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-4-28 22:54:43 | 显示全部楼层
可能A0有问题。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

1

主题

10

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2014-1-5
在线时间
2 小时
 楼主| 发表于 2015-4-30 20:18:16 | 显示全部楼层
回复【5楼】正点原子:
---------------------------------
IS62的第六引脚片选端我并没有加10K上拉电阻,这应该不会造成问题吧?
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-4-30 22:42:22 | 显示全部楼层
回复【6楼】ck0908125:
---------------------------------
不会。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

1

主题

10

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2014-1-5
在线时间
2 小时
 楼主| 发表于 2015-5-3 23:18:09 | 显示全部楼层
我又重新焊了块板子,读写没有问题,都很正常,还真有可能是上块板子焊接的问题,多谢原子哥啊!
回复

使用道具 举报

0

主题

5

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2015-12-8
在线时间
0 小时
发表于 2015-12-8 16:15:32 | 显示全部楼层
我的是F103ZET6最小系统板,外扩了IS62WV51216,和LCD共用数据口,片选不同,SRAM是NE3,LCD是NE4,我的问题是只要插LCD,SRAM读写测试就不能通过,拔下LCD就好,原子兄能否指点一下,多谢了。
回复

使用道具 举报

0

主题

5

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2015-12-8
在线时间
0 小时
发表于 2015-12-8 20:12:18 | 显示全部楼层
回复【10楼】dalaozhangge:
---------------------------------
我的问题找到了,供买到F103ZET6最小系统板的朋友们参考:
资料包里面有个“简单SRAM测试”的代码,在不插LCD的时候测试没有问题;
插上LCD测试不过的原因是,这个代码没有考虑插入LCD的情况,所以要把LCD的初始化加入进来,也就是说是LCD没有正确的复位和初始化造成没有收起“对总线的干扰”造成的。
但是当你试图整合LCD测试包和SRAM测试包的时候,就会发现,这些包的调用库文件不是来自于同一个“体系”的,好一番周折啊,把它们都统一了。测试也OK了。
需要说明的是,这个板不是原子兄的。所以大家买东西要尽可能选择一脉相承的东西,少很多麻烦。当然那个板硬体上是没有问题的。
回复

使用道具 举报

4

主题

8

帖子

0

精华

初级会员

Rank: 2

积分
165
金钱
165
注册时间
2016-5-26
在线时间
53 小时
发表于 2016-8-30 14:45:53 | 显示全部楼层
dalaozhangge 发表于 2015-12-8 20:12
回复【10楼】dalaozhangge:
---------------------------------
我的问题找到了,供买到F103ZET6最小系统板 ...

能不能把你的初始化程序分享一下,我是挂一块SRAM,一块FPGA,FPGA监测的时序总是不对
回复

使用道具 举报

7

主题

63

帖子

0

精华

高级会员

Rank: 4

积分
530
金钱
530
注册时间
2013-12-26
在线时间
124 小时
发表于 2016-12-30 14:58:00 | 显示全部楼层
MARK,一下。。。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-24 09:02

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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