历史上的今天
返回首页

历史上的今天

今天是:2024年10月16日(星期三)

正在发生

2018年10月16日 | 58.外部SRAM实验

2018-10-16 来源:eefocus

一。IS62WV51216 简介

1.     IS62WV51216 是 ISSI(Integrated  Silicon  Solution,  Inc)公司生产的一颗 16 位宽 512K

(512*16,即 1M 字节)容量的 CMOS 静态内存芯片。

58.外部SRAM实验

58.外部SRAM实验
实验选用的芯片没有CS2引脚。

2. IS62WV51216读时序

58.外部SRAM实验

58.外部SRAM实验
58.外部SRAM实验

3. IS62WV51216写时序

58.外部SRAM实验

58.外部SRAM实验
58.外部SRAM实验

二。FSMC简介

1. STM32中FSMC框图

58.外部SRAM实验

为什么VBT6不能用FSMC功能驱动SRAM?

STM32与SRAM连接必须要连接19根地址线,FSMC_A0对应的引脚为PF0,而在100脚的STM32芯片上只有A,B,C,D,E引脚,没有F引脚,所以在100脚以下的STM32芯片无法驱动SRAM。只有144个引脚的STM32芯片才可以驱动SRAM。

为什么在100个引脚的VET6的芯片上可以利用FSMC功能控制液晶屏?

    因为FSMC有的地址线是在PE引脚上,而控制液晶屏只需要一根地址线,用来控制发指令还是发数据,所以在100脚的VET6上可以用FSMC功能控制液晶屏,如果要控制SRAM则地址线需要从FSMC_A0到FSMC_A18,很多都是在PF引脚上。,所以VET6不能用FSMC功能控制SRAM。

二。FSMC驱动SRAM的原理

58.外部SRAM实验

三。NOR PSRAM外设接口

58.外部SRAM实验
驱动SRAM使用存储块1,由4*64MB四个区组成

三。存储块1操作简介

58.外部SRAM实验

Bank1接的是16位宽度存储器的时候,内部地址右移一位跟FSMC的地址对齐,除以2对齐

因为在STM32内部每个地址对应一个字节的数据,如果外部设备是16位宽度,那么外部设备的一个地址就代表了FSMC的2个字节。

比如 内部地址 6000 0000(0) 对应FSMC的A0=0 (A0=0的时候对应2个字节)

                       6000 0010(2) 对应FSMC的A0=1 (A0=1的时候对应2个字节)

                       6000 0100(4) 对应FSMC的A1=1,A0=0 (对应2个字节)

58.外部SRAM实验

四。FSMC寄存器介绍

58.外部SRAM实验
FSMC_BWTRx只有在读写时序不一致的时候才设置。

本实验中EXTMOD位设置为0,不允许读写不同的时序,因此FSMC_BWTRx寄存器不需要设置。

片选时序寄存器(FSMC_BTRx)是很重要的一个寄存器,控制访问的时序。

58.外部SRAM实验

访问模式为模式A,因此ACCMOD设置为00. 控制FSMC只能选用模式A。

58.外部SRAM实验

五。硬件连接

58.外部SRAM实验
    为了布线方便,IS62WV51216的地址线A0-A18并没有与FSMC的地址线A0-A18相对应,但这样不会影响使用,因为地址具有唯一性,比如写的地址是xx,读的时候地址也是xx,所以不存在任何问题,地址线可以随意乱接的。

  但是数据线必须一一对应。

  实验中CS接的是FSMC_NE3。

六。驱动代码讲解

58.外部SRAM实验

//使用NOR/SRAM的 Bank1.sector3,地址位HADDR[27,26]=10 

//对IS61LV25616/IS62WV25616,地址线范围为A0~A17 

//对IS61LV51216/IS62WV51216,地址线范围为A0~A18

#define Bank1_SRAM3_ADDR    ((u32)(0x68000000))  //NE3所在区的首地址

1. FSMC初始化函数

    

//初始化外部SRAM

void FSMC_SRAM_Init(void)

{

  FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;

  FSMC_NORSRAMTimingInitTypeDef  readWriteTiming;

  GPIO_InitTypeDef  GPIO_InitStructure;

 

  // 所使用的GPIO的初始化     

 //在使用FSMC功能中所有引脚都要设置成复用推挽输出功能    

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOF|   RCC_APB2Periph_GPIOG,ENABLE);  //使能相应的GPIO时钟

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC,ENABLE);  //使能FSMC时钟

  

  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);

 

   //读写时序的设置

  //控制FSMC只用到AddressSetupTime和DataSetupTime

   readWriteTiming.FSMC_AddressSetupTime = 0x00; //地址建立时间(ADDSET)为1个HCLK 

                                                                                           1/72M=14ns

    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; //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  

}

2. 连续写函数

//在指定地址开始,连续写入n个字节.

//pBuffer:字节指针

//WriteAddr:要写入的地址

//n:要写入的字节数

void FSMC_SRAM_WriteBuffer(u8* pBuffer,u32 WriteAddr,u32 n)

{

for( ; n!=0; n--)  

{    

*(vu8*)(Bank1_SRAM3_ADDR+WriteAddr)=*pBuffer;   //把地址强制转换为u8类型

WriteAddr++; 

pBuffer++;

}   

}     

假设WriteAddr=0,(注意:写入的地址是偶数)那么A0肯定是0

此时LB=0有效,写入的数据是D0-D7有效 ,D8-D15无效,UB=1

继续写地址1的时候,写入的地址就变成6800 0001,此时自动设置LB=1,无效,UB=0,有效,这时候高八位有效,因此数据就写入高8位地址。

UB,LB与要写入的地址的最低位有关联。

如果要写入的数据是16位,那么UB和LB都等于0.而且地址是偶数。

如果地址是奇数,要写一个16位的数据就需要分两次写入,一次写一个8位。因此如果地址是个奇数,写入一个16位的数据,速度就要减半。     

3. 连续读函数

//在指定地址开始,连续读出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++; 

}  

4. 测试函数

u32 testsram[250000] __attribute__((at(0X68000000)));//测试用数组,定义数组的初始绝对地址在6800 0000

//外部内存测试(最大支持1M字节内存测试)    

void fsmc_sram_test(u16 x,u16 y)

{  

u32 i=0;    

u8 temp=0;   

u8 sval=0; //在地址0读到的数据     

  LCD_ShowString(x,y,239,y+16,16,"Ex Memory Test:   0KB"); 

//每隔4K字节,写入一个数据,总共写入256个数据,刚好是1M字节

for(i=0;i<1024*1024;i+=4096)

{

FSMC_SRAM_WriteBuffer(&temp,i,1);

temp++;

}

//依次读出之前写入的数据,进行校验  

  for(i=0;i<1024*1024;i+=4096) 

{

  FSMC_SRAM_ReadBuffer(&temp,i,1);

if(i==0)sval=temp;

  else if(temp<=sval)break;//后面读出的数据一定要比第一次读到的数据大.     

LCD_ShowxNum(x+15*8,y,(u16)(temp-sval+1)*4,4,16,0);//显示内存容量  

  }  

}  

c语言小贴士:

__attribute__,这个是 用来指定变量或结构位域的特殊属性,该关键字后的双括弧中的内容是属性说明。 
然后是at关键字,该关键字可以用来设置变量的绝对地址,也就是你可以通过这个关键字,指定某个变量处于内存里面的某个给定的地址. 

综合起来,就是设置变量处于0X68000000这个地址.

在使用FSMC功能中所有引脚都要设置成复用推挽输出功能    

58.外部SRAM实验

读写时序分析

58.外部SRAM实验
经验值 DATAST = 2才能正常工作

58.外部SRAM实验

单位是HCLK个时钟周期

1个HCLK时钟周期为1/72M=13.8ns

DATAST位的值不能为0.(0为保留)


5. 如何对SRAM进行读写

使用指针的方法进行读写

不需要写读写函数,可以直接使用指针的方式对STM32的内存地址进行访问。

(1)首先要定义SRAM的基地址:

#defeine SRAM_BASE_ADDR       (0x68000000)  //基地址从0x68000000开始

#define SRAM_SIZE                      (1*1024*1024) //一共有1M字节

#define SRAM_END_ADDR          (SRAM_BASE_ADDR + SRAM_SIZE)   //SRAM结束的地址

//用#define定义宏的时候用括号是个习惯,防止以后如果有运算的时候会影响宏的运算法则。

 (2)定义指针,操作单字节数据

u8 *p;

p = (u8 *)SRAM_BASE_ADDR; //把数据SRAM_BASE_ADDR强制转换成指针

*p = 0xAB;    //向0x68000000地址写入0xAB


如何操作双字节数据

先定义一个16位的指针

u16 *p16;

p = (u16 *)SRAM_BASE_ADDR; //把数据SRAM_BASE_ADDR强制转换成16位指针

*p16 = 0xCDEF;   //一次可以操作2个字节


如何操作浮点数

定义一个指向浮点数的指针

float *pf;

p = (float *)SRAM_BASE_ADDR; //把数据SRAM_BASE_ADDR强制转换成指向浮点数的指针

*pf = 56.35;

使用绝对地址的方式访问SRAM

u8 testValue __attribute__ ( (at (SRAM_BASE_ADDR ) ) );

把变量testValue的地址定义到0x68000000

testValue = 50;

注意:使用 __attribute__定义变量时必须定义为全局变量

否则如果使用局部变量,变量还是会被定义在内部RAM中。


推荐阅读

史海拾趣

COTO TECHNOLOGY公司的发展小趣事

进入上世纪六十年代,COTO TECHNOLOGY迎来了一个重大的转折点。公司开始探索线圈绕组以外的领域,通过引入簧片继电器,成功扩展了产品线。这一创新举措不仅丰富了公司的产品种类,更重要的是,它为公司打开了新的市场领域。到了七十年代,COTO更是凭借开发出的首款获得专利的低热电动势簧片继电器,一跃成为业界领先的干簧继电器制造商。

长园维安(CYGWAYON)公司的发展小趣事

面对电子行业快速发展的挑战,长园维安积极应对,进行转型升级。公司加大研发投入,开发更加智能化、集成化的产品,满足市场需求。同时,长园维安还注重人才培养和引进,建立了一支高素质的技术和管理团队。这些努力使长园维安在激烈的市场竞争中保持领先地位。

亿晶源(ekinglux)公司的发展小趣事

面对不断变化的市场环境和客户需求,亿晶源始终保持敏锐的市场洞察力和创新精神。公司将继续加大研发投入,推出更多具有竞争力的新产品;同时,加强与国际知名企业的合作与交流,提升公司的国际竞争力。展望未来,亿晶源将致力于成为全球领先的LED半导体制造商之一。

请注意,以上故事框架仅为示例,具体细节和事实可能需要根据实际情况进行调整和补充。

Delta Electronics Manufacturing Corp公司的发展小趣事

Delta Electronics Manufacturing Corp公司始建于上世纪七十年代,起初以生产电源产品为主。在初创阶段,公司凭借对技术的深度钻研和对市场的敏锐洞察,成功研发出一系列高效、稳定的电源产品。这些产品迅速在市场上获得认可,为Delta在电源领域奠定了坚实的基础。

GeneSiC Semiconductor公司的发展小趣事

技术创新一直是Delta的核心竞争力。多年来,公司不断投入研发资源,推动技术创新和产品升级。Delta的工程师团队致力于电源技术的研发,成功推出了一系列具有领先技术水平的电源产品,如高效能转换器、智能电源管理系统等。这些产品不仅满足了市场的多样化需求,也推动了电源行业的技术进步。

世纪金光(CENGOL)公司的发展小趣事

自成立以来,世纪金光始终注重科研实力的积累。公司积极承担国家科研任务,已转接和直接承担国家科研任务80多项。在这些科研项目中,世纪金光取得了丰硕的成果,其中12项成果处于国内同类技术领先水平,5项成果达到国际先进水平。这些成果的取得不仅提升了公司的技术水平,也为公司在半导体领域的竞争提供了有力支撑。

问答坊 | AI 解惑

LPC2000应用笔记

免费资料,内容很齐全哦 [ 本帖最后由 jxb01033016 于 2009-9-17 11:36 编辑 ]…

查看全部问答>

我可以解决芯片的焊接问题

我可以焊接芯片CP2102,我觉得是件很容易的事,如果谁需要焊接,我很乐意帮忙。我的QQ;724791682       724791682@qq.com…

查看全部问答>

有关jlink

想玩一玩S3C2440, 请问: 1. 一定需要jlink或ulink吗? 2.看网上卖jlink从100元至1200元不等,真正功能上有区别么? 谢了 …

查看全部问答>

RAW格式转换为NTFS

请教: 如何将RAW格式转换为NTFS格式的? …

查看全部问答>

DMA传输数据的问题

DMA传输数据64K时,目的空间每包前一部分(4K左右)是后一包的数据,后一部分是前一包的数据(60K), 比如我第i包全是2,第i+1全是3,我看到的第i+1数据如下(很有规律): 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 ...…

查看全部问答>

变频器的正常使用及故障维修

一、正确使用变频器应注意事项 1、环境温度对变频器的使用寿命有很大的影响。环境温度每升10℃,则变频器寿命减半,所以周围环境温度及变频器散热的问题一定要解决好。 2、正确的接线及参数设置。在安装变频器之前一定要熟读其手册,掌握其用法、 ...…

查看全部问答>

大家来谈谈喜欢玩单片机还是ARM!~

我相信大家都是应该先玩完单片机以后开始玩ARM的吧!~我也是这样的,但是为什么突然觉得还是单片机好玩一些,我想了一下,是因为单片机简单?不是,是因为它价格低?我不做产品,所以无所谓呀,但是就是感觉自己还是喜欢玩单片机一些,坛友们你们也 ...…

查看全部问答>

STM8L做FFT可行不?

                                 请问香水板主,有没有人用STM8L做256点,16位整形的 FFT计算,大概要多长时间?…

查看全部问答>

选型前咨询:STM8敢上吗?

现在又回到8位机做一个低成本的东东,STM8敢选吗? 有使用经历的朋友诚恳介绍下吧! 谢谢了!…

查看全部问答>

pi闭环控制技术

pi闭环控制技术是什么技术呀?它的原理是什么呀?我在网上收索了pi,但相关资源太少了。我还是不懂。所以就到了论坛里问问。…

查看全部问答>