当前位置:   article > 正文

STM32-基本知识梳理9-FSMC控制外部SRAM_stm32 驱动spi sram

stm32 驱动spi sram

一、SRAM基础知识介绍

1,外部SRAM,STM32芯片扩展内存与给PC扩展内存的原理是一样的,只是PC上一般以内存条的形式扩展;

2,外部SRAM,断电之后,存储器信息会丢失;

 3,外部SRAM的内部框图解析

1-实际存储器模块;

2-IO接口,包括地址线、数据线

3-控制模块,

包括 CS片选引脚、OE读使能、WE写使能、UB高位字节允许访问、LB低位字节允许访问

(补充,具体操作不需要担心,只要后面配置好FSMC模块和时间参数,这些都会交给FSMC模块自动处理)

4,地址和内存位置的关系

内存可以理解为在excel中的一个个小表格,我们可以通过行地址和列地址具体的找到一个地址位置;

本例中,使用的是IS62WV51216型号的SRAM,SRAM比较小,没有列地址线,它的数据宽度为16位,即一个行地址对应2字节空间,框图中左侧的A0-A18是行址信号,18根地址线一共可以表示218=28x1024=512K行存储单元,所以它一共能访问512Kx16bits大小的空间。访问时,使用UB#或LB#线控制数据宽度,

 5,控制的SRAM的关键参数

1-地址建立时间;

2-数据建立时间;

具体在后面的fmsc模块初始化中介绍


至此,SRAM简要介绍到此结束,下面介绍FSMC模块

二、FSMC基础知识介绍

1,用FSMC外设来管理扩展的存储器,FSMC是Flexible Static Memory Controller的缩写,译为灵活的静态存储控制器。

2,可以用于驱动包括SRAM、NOR FLASH以及NAND FLSAH类型的存储器;不同的存储器类型,由于读取操作方式的不同,在FSMC模块中有不同的接口进行配置

3,FSMC框图介绍

①外部接线引脚,根据不同的存储器类型,由对应的控制引脚,但是地址线和数据线是共用的;

②控制模块

③FMSC模块是直接挂载在AHB总线上的,时钟是72mhz

 4,使用FMSC模块中访问外部SRAM空间

通过FSMC模块控制的存储器模块,和SPI控制的flash模块、I2C控制的EEROM,甚至串口控制的最大区别在于:FSMC控制的存储器模块,数据地址是存放在STM32的地址区间内的,也就是连接的SRAM模块,相当于STM32的内存,我们可以通过指针访问的方式直接对SRAM进行操作;

而其他一般是输入指令,输入内存模块自身的地址空间,执行对应操作

5,对应地址空间在STM32中的内存地址分区

在bank1-NORSRAM3模块区域,首地址为0x68000000

 

6,FSMC控制SRAM的时序

①FSMC外设支持输出多种不同的时序以便于控制不同的存储器,它具有ABCD四种模式,控制SRAM使用模式A,控制外部液晶屏选用模式B

②地址建立周期的关键参数

地址建立周期ADDSET配置为0x00(即1个地址建立周期,单位HCLK);HCLK的数值是由AHB时钟决定,STM32F103 为1/72M;

数据建立周期为0x02,即3个HCLK

ps:这是读写周期相同的情况,理论上要具体计算,我这边直接借用了野火的经验值。

至此FSMC模块介绍完毕,下面进入代码模块


三、代码模块解析

1,FSMC结构体初始化

1- FSMC结构初始化主要分为两个模块,时序初始化、整体FSMC初始化

 配置好时序结构体后,再在整体初始化结构体中,进行地址传递,一起进行初始化

2,整体代码逻辑分析

1 - GPIO模块初始化,按照ST推荐方式初始化,全部复用推挽输出;

2 - 初始化FSMC

3-mian函数中配置使用

1 - GPIO模块初始化

  1. void fsmc_gpio_config(void)
  2. {
  3. //打开时钟
  4. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF|RCC_APB2Periph_GPIOD|
  5. RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOG,ENABLE);
  6. //开始配置GPIO
  7. //地址A0-A18
  8. GPIO_InitTypeDef GPIO_InitStruct;
  9. GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
  10. GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
  11. GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//PF0
  12. GPIO_Init( GPIOF, & GPIO_InitStruct);
  13. GPIO_InitStruct.GPIO_Pin=GPIO_Pin_1 |GPIO_Pin_2 | GPIO_Pin_3| GPIO_Pin_4
  14. |GPIO_Pin_5|GPIO_Pin_12 |GPIO_Pin_13 |GPIO_Pin_14 |GPIO_Pin_15;// PF
  15. GPIO_Init( GPIOF, & GPIO_InitStruct);
  16. GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0 |GPIO_Pin_1 | GPIO_Pin_7| GPIO_Pin_8
  17. |GPIO_Pin_9|GPIO_Pin_10 |GPIO_Pin_11 |GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14
  18. |GPIO_Pin_15;
  19. GPIO_Init( GPIOE, & GPIO_InitStruct);
  20. GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0 |GPIO_Pin_1|GPIO_Pin_4 |GPIO_Pin_5
  21. |GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13
  22. |GPIO_Pin_14|GPIO_Pin_15;
  23. GPIO_Init( GPIOD, & GPIO_InitStruct);
  24. GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0 |GPIO_Pin_1|GPIO_Pin_2 |GPIO_Pin_3
  25. |GPIO_Pin_4|GPIO_Pin_5 |GPIO_Pin_10;
  26. GPIO_Init( GPIOG, & GPIO_InitStruct);
  27. }

2 - 初始化FSMC,并在调用GPIO,并且cmd启动

  1. void fsmc_config(void)
  2. {
  3. fsmc_gpio_config();
  4. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC,ENABLE);//开启fsmc时钟
  5. //先配置读写时序结构体
  6. FSMC_NORSRAMTimingInitTypeDef readWriteTiming;
  7. readWriteTiming.FSMC_AccessMode=FSMC_AccessMode_A;//控制sram选择模式A
  8. readWriteTiming.FSMC_AddressHoldTime=0x00;//地址保持时间0
  9. //地址建立时间(ADDSET)为1个HCLK 1/72M=14ns,addset+1
  10. readWriteTiming.FSMC_AddressSetupTime=0x00;
  11. readWriteTiming.FSMC_BusTurnAroundDuration=0;
  12. readWriteTiming.FSMC_CLKDivision=0;
  13. readWriteTiming.FSMC_DataLatency=0x00; //这三个,模式A未用到
  14. //数据保持时间(DATAST)+ 1个HCLK = 3/72M=42ns(对EM的SRAM芯片)
  15. readWriteTiming.FSMC_DataSetupTime=0x02;
  16. //下面进行FSMC-SRAM初始化
  17. FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStruct;
  18. //SRAM的地址区域在bank1-SRAM3
  19. FSMC_NORSRAMInitStruct.FSMC_Bank=FSMC_Bank1_NORSRAM3 ;
  20. //异步,不适用突发模式
  21. FSMC_NORSRAMInitStruct.FSMC_BurstAccessMode=FSMC_BurstAccessMode_Disable ;
  22. //等待时间
  23. FSMC_NORSRAMInitStruct.FSMC_AsynchronousWait=FSMC_AsynchronousWait_Disable ;
  24. //数据总线和地址总线不复用
  25. FSMC_NORSRAMInitStruct.FSMC_DataAddressMux=FSMC_DataAddressMux_Disable ;
  26. //扩展模式不开启,读写时序保持一种
  27. FSMC_NORSRAMInitStruct.FSMC_ExtendedMode=FSMC_ExtendedMode_Disable ;
  28. //数据宽度16
  29. FSMC_NORSRAMInitStruct.FSMC_MemoryDataWidth=FSMC_MemoryDataWidth_16b ;
  30. //存储器类型 SRAM
  31. FSMC_NORSRAMInitStruct.FSMC_MemoryType=FSMC_MemoryType_SRAM ;
  32. FSMC_NORSRAMInitStruct.FSMC_WaitSignal=FSMC_WaitSignal_Disable ;
  33. FSMC_NORSRAMInitStruct.FSMC_WaitSignalActive=FSMC_WaitSignalActive_BeforeWaitState ;
  34. FSMC_NORSRAMInitStruct.FSMC_WaitSignalPolarity=FSMC_WaitSignalPolarity_Low ;
  35. FSMC_NORSRAMInitStruct.FSMC_WrapMode=FSMC_WrapMode_Disable;
  36. FSMC_NORSRAMInitStruct.FSMC_WriteBurst=FSMC_WriteBurst_Disable ;
  37. //写使能
  38. FSMC_NORSRAMInitStruct.FSMC_WriteOperation=FSMC_WriteOperation_Enable ;
  39. FSMC_NORSRAMInitStruct.FSMC_ReadWriteTimingStruct=&readWriteTiming;
  40. //扩展模式有效
  41. FSMC_NORSRAMInitStruct.FSMC_WriteTimingStruct=&readWriteTiming;
  42. FSMC_NORSRAMInit(&FSMC_NORSRAMInitStruct);
  43. //启动
  44. FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3,ENABLE);
  45. }

3-main函数中配置使用

  1. #include "stm32f10x.h" // Device header
  2. #include "LED.H"
  3. #include "BSP_USART.H"
  4. #include "BSP_FSMC.H"
  5. //uint8_t testvalue __attribute__((at(SRAM_BASE_ADD+0x40)));
  6. uint8_t testValue __attribute__((section(".ARM.__at_(0x68000000+0x40)")));
  7. int main(void)
  8. {
  9. bsp_usart_config();
  10. fsmc_config();
  11. printf ( "\r\n野火外部 SRAM 测试1\r\n" );
  12. uint16_t *p16;
  13. p16=(uint16_t *)(0x68000000);
  14. *p16=0x1234;
  15. printf("%x %p\n",*p16,p16);
  16. float*pf=(float *)(0x68000000+0x20);
  17. *pf=56.789;
  18. printf("%.4f %p\n",*pf,pf);
  19. uint32_t *p32;
  20. p32=(uint32_t *)(0x68000000+0x40);
  21. *p32=0x12345678;
  22. printf("%x %p\n",*p32,p32);
  23. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/901889
推荐阅读
相关标签
  

闽ICP备14008679号