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

2019-10-15 21:00发布

外部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 != ''; i++) { USART_SendData(USARTx,sendstr); while(USART_GetFlagStatus(USARTx,USART_FLAG_TC) == RESET); } } [/mw_shl_code] 但是在使用Jlink和串口测试的时候发现:当仅写入一个地址数据的时候,偶数地址写不进,奇数地址可以写进,但是都可以读;如果连续写入n个地址数据,前面地址的数据都会被最后一个数据覆盖掉!而且FSMC上只挂了这个SRAM!网上查了很多资料也没找到,求高手们解答一下啊!(不会是硬件走线有问题吧?)
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
12条回答
正点原子
1楼-- · 2019-10-16 00:50
检查硬件焊接吧。
ck0908125
2楼-- · 2019-10-16 06:39
补充一句,错误的原因是因为元件焊反了!IS62WV51216芯片表面有两个圆点,一定要注意哪个才是第一引脚!
styleno1
3楼-- · 2019-10-16 07:45
 精彩回答 2  元偷偷看……
ck0908125
4楼-- · 2019-10-16 11:47
回复【2楼】styleno1:
---------------------------------
是的啊,硬件软件都一样,所以才会很纠结!
正点原子
5楼-- · 2019-10-16 17:41
可能A0有问题。
ck0908125
6楼-- · 2019-10-16 18:34
回复【5楼】正点原子:
---------------------------------
IS62的第六引脚片选端我并没有加10K上拉电阻,这应该不会造成问题吧?

一周热门 更多>