外部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!网上查了很多资料也没找到,求高手们解答一下啊!(不会是硬件走线有问题吧?)
---------------------------------
不会。
---------------------------------
我的问题找到了,供买到F103ZET6最小系统板的朋友们参考:
资料包里面有个“简单SRAM测试”的代码,在不插LCD的时候测试没有问题;
插上LCD测试不过的原因是,这个代码没有考虑插入LCD的情况,所以要把LCD的初始化加入进来,也就是说是LCD没有正确的复位和初始化造成没有收起“对总线的干扰”造成的。
但是当你试图整合LCD测试包和SRAM测试包的时候,就会发现,这些包的调用库文件不是来自于同一个“体系”的,好一番周折啊,把它们都统一了。测试也OK了。
需要说明的是,这个板不是原子兄的。所以大家买东西要尽可能选择一脉相承的东西,少很多麻烦。当然那个板硬体上是没有问题的。
能不能把你的初始化程序分享一下,我是挂一块SRAM,一块FPGA,FPGA监测的时序总是不对
一周热门 更多>