用户工具

站点工具


icore3l_18

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

后一修订版
前一修订版
icore3l_18 [2020/11/11 10:32]
zgf 创建
icore3l_18 [2020/11/11 11:18] (当前版本)
zgf
行 7: 行 7:
  
 ===== STM32CubeMX教程十八——SDRAM实验 ===== ===== STM32CubeMX教程十八——SDRAM实验 =====
-在主界面选择File-->​New Project或者直接点击ACCEE TO MCU SELECTOR ​+1.在主界面选择File-->​New Project或者直接点击ACCEE TO MCU SELECTOR ​ 
 +{{ :​icore3l:​icore3l_cube_18_1.png?​direct |}} 
 +2.出现芯片型号选择,搜索自己芯片的型号,双击型号,或者点击Start Project进入配置在搜索栏的下面,提供的各种查找方式,可以选择芯片内核,型号等等,可以帮助你查找芯片。本实验选取的芯片型号为:STM32F429IGHx。 
 +{{ :​icore3l:​icore3l_cube_18_2.png?​direct |}} 
 +3.配置RCC,使用外部时钟源 
 +{{ :​icore3l:​icore3l_cube_18_3.png?​direct |}} 
 +4.Debug选择Serial Wire时基源选择SysTick 
 +{{ :​icore3l:​icore3l_cube_18_4.png?​direct |}} 
 +{{ :​icore3l:​icore3l_cube_18_5.png?​direct |}} 
 +5.将LEDG,​LEDR,​LEDB对应的PI3,​PI4,​PH14设置为GPIO_Output 
 +{{ :​icore3l:​icore3l_cube_18_6.png?​direct |}} 
 +6.引脚模式配置 
 +{{ :​icore3l:​icore3l_cube_18_7.png?​direct |}} 
 +7.配置FMC 
 +{{ :​icore3l:​icore3l_cube_18_8.png?​direct |}} 
 +8.时钟源设置,选择外部高速时钟源,配置为最大主频 
 +{{ :​icore3l:​icore3l_cube_18_9.png?​direct |}} 
 +9.工程文件的设置,​ 这里就是工程的各种配置 我们只用到有限几个,其他的默认即可IDE我们使用的是 MDK V5.27 
 +{{ :​icore3l:​icore3l_cube_18_10.png?​direct |}} 
 +10.点击Code Generator,进行进一步配置 
 +{{ :​icore3l:​icore3l_cube_18_11.png?​direct |}} 
 +*  **Copy all used libraries into the project folder** 
 +  *将HAL库的所有.C和.H都复制到所建工程中 
 +     ​*优点:这样如果后续需要新增其他外设又可能不再用STM32CubeMX的时候便会很方便 
 +     ​*缺点:体积大,编译时间很长 
 +*  **Copy only the necessary library files** 
 +  *只复制所需要的.C和.H(推荐) 
 +     ​*优点:体积相对小,编译时间短,并且工程可复制拷贝 
 +     ​*缺点:新增外设时需要重新用STM32CubeMX导入 
 +*  **Add necessary library files as reference in the toolchain project configuration file** 
 +  *不复制文件,直接从软件包存放位置导入.C和.H 
 +     ​*优点:体积小,比较节约硬盘空间 
 +     ​*缺点:复制到其他电脑上或者软件包位置改变,就需要修改相对应的路径自行选择方式即可 
 +11.然后点击GENERATE CODE创建工程 
 +{{ :​icore3l:​icore3l_cube_18_12.png?​direct |}} 
 +创建成功,打开工程。 
 +\\ 
 +\\ 
 +\\ 
 +\\ 
 +===== 实验十八:SDRAM实验——读写测试SDRAM ===== 
 +==== 一、实验目的与意义 ==== 
 +  - 了解STM32 SDRAM结构 
 +  - 了解STM32 SDRAM特征 
 +  - 掌握SDRAM的使用方法 
 +  - 掌握STM32 HAL库中SDRAM属性的配置方法 
 +  - 掌握KEILMDK 集成开发环境使用方法 
 +==== 二、实验设备及平台 ==== 
 +  - iCore3L 双核心板 
 +  - JLINK(或相同功能)仿真器 
 +  - Micro USB线缆 
 +  - Keil MDK 开发平台 
 +  - STM32CubeMX开发平台 
 +  - 装有WIN XP(及更高版本)系统的计算机 
 +==== 三、实验原理 ==== 
 +=== 1.SDRAM简介 === 
 +  * 同步动态随机存取内存(synchronous dynamic random-access memory,简称SDRAM)是有一个同步接口的动态随机存取内存(DRAM)。通常DRAM是有一个异步接口的,这样它可以随时响应控制输入的变化。而SDRAM有一个同步接口,在响应控制输入前会等待一个时钟信号,这样就能和计算机的系统总线同步。时钟被用来驱动一个有限状态机,对进入的指令进行管线(Pipeline)操作。这使得SDRAM与没有同步接口的异DRAM(asynchronous DRAM)相比,可以有一个更复杂的操作模式。管线意味着芯片可以在处理完之前的指令前,接受一个新的指令。在一个写入的管线中,写入命令在另一个指令执行完之后可以立刻执行,而不需要等待数据写入存储队列的时间。在一个读取的流水线中,需要的数据在读取指令发出之后固定数量的时钟频率后到达,而这个等待的过程可以发出其它附加指令。 
 +  * SDRAM是多Bank结构,例如在一个具有两个Bank的SDRAM的模组中,其中一个Bank在进行预充电期间,另一个Bank却马上可以被读取,这样当进行一次读取后,又马上去读取已经预充电Bank的数据时,就无需等待而是可以直接读取了,这也就大大提高了存储器的访问速度。为了实现这个功能,SDRAM需要增加对多个Bank的管理,实现控制其中的Bank进行预充电。在一个具有2个以上Bank的SDRAM中,一般会多一根叫做BAn的引脚,用来实现在多个Bank之间的选择。 
 +SDRAM具有多种工作模式,内部操作是一个复杂的状态机。SDRAM器件的引脚分为以下几类: 
 +  - 控制信号:包括片选、时钟、时钟使能、行列地址选择、读写有效及数据有效。 
 +  - 地址信号:时分复用引脚,根据行列地址选择引脚,控制输入的地址为行地址或列地址。 
 +  - 数据信号:双向引脚,受数据有效控制。 
 +SDRAM的所有操作都同步于时钟。根据时钟上升沿控制管脚和地址输入的状态,可以产生多种输入命令:​ 
 +  * 模式寄存器设置命令 
 +  * 激活命令 
 +  * 预充命令 
 +  * 读命令 
 +  * 写命令 
 +  * 带预充的读命令 
 +  * 带预充的写命令 
 +  * 自动刷新命令 
 +  * 自我刷新命令 
 +  * 突发停命令 
 +  * 空操作命令 
 +  * 根据输入命令,SDRAM状态在内部状态间转移。内部状态包括模式寄存器设置状态、激活状态、预充状态、写状态、读状态、预充读状态、预充写状态、自动刷新状态及自我刷新状态。 
 +  * SDRAM支持的操作命令有初始化配置、预充电、行激活、读操作、写操作、自动刷新、自刷新等。所有的操作命令通过控制线CS#​、RAS#​、CAS#​、WE#​和地址线、体选地址BA输入。 
 +=== 2.FMC简介 === 
 +  * STM32F429IGHx使用FMC外设来管理扩展的存储器,FMC是Flexible Memory Controller的缩写,译为可变存储控制器。它可以用于驱动包括SRAM、SDRAM、PSRAM、NOR FLASH以及NAND FLSAH类型的存储器。 
 +  * FMC有6个存储区域,每个区域支持256MB的寻址空间。 
 +    * (1)数字列表项目存储区域 1 可连接多达 4 个 NOR Flash 或 PSRAM 设备。此存储区域被划分为如下 4 个NOR/​PSRAM 子区域,带 4 个专用片选信号: 
 +      * 存储区域 1 NOR/PSRAM 1 
 +      * 存储区域 1 NOR/PSRAM 2 
 +      * 存储区域 1 NOR/PSRAM 3 
 +      * 存储区域 1 NOR/PSRAM 4 
 +    * (2)存储区域2用于SDRAM器件,具体是SDRAM存储区域1还是SDRAM存储区域2取决于BMAP位配置。 
 +    * (3)存储区域3用于连接NAND Flash器件。此空间的MPU存储器特性必须通过软件重新配置到器件中。 
 +    * (4)存储区域5和6用于连接SDRAM器件(每个存储区域1个器件)。 
 +  * 对于每个存储区域,所要使用的存储器类型可由用户应用程序通过配置寄存器配置。 
 +  * 本实验使用FMC控制SDRAM。启动时,必须通过用户应用程序对用于连接 FMC SDRAM 控制器与外部 SDRAM 设备的SDRAM I/O 引脚进行配置。应用程序未使用的 SDRAM 控制器 I/O 引脚可用于其它用途。 
 +FMC的存储区域如图所示: 
 +{{ :​icore3l:​icore3l_arm_hal_18_1.png?​direct |}} 
 +FMC框图如下: 
 +{{ :​icore3l:​icore3l_arm_hal_18_2.png?​direct |}} 
 +=== 3.SDRAM的地址映射 === 
 +两个可用的SDRAM存储区域如图: 
 +{{ :​icore3l:​icore3l_arm_hal_18_3.png?​direct |}} 
 +=== 4.SDRAM控制寄存器 === 
 +  * 控制SDRAM的有FMC_SDCR1/​FMC_SDCR2控制寄存器、FMC_SDTR1/​FMC_SDTR2 时序寄存器、FMC_SDCMR 命令模式寄存器以及 FMC_SDRTR刷新定时器寄存器。其中控制寄存器及时序寄存器各有2个,分别对应于SDRAM存储区域1和存储区域2的配置。 
 +  * FMC_SDCR控制寄存器可配置SDCLK的同步时钟频率、突发读使能、写保护、CAS延迟、行列地址位数以及数据总线宽度等。 
 +  * FMC_SDTR时序寄存器用于配置SDRAM访问时的各种时间延迟,如TRP行预充电延迟、TMRD加载模式寄存器激活延迟等。 
 +  * FMC_SDCMR命令模式寄存器用于存储要发送到SDRAM模式寄存器的配置,以及要向SDRAM芯片发送的命令。 
 +  * FMC_SDRTR 刷新定时器寄存器用于配置 SDRAM 的自动刷新周期。 
 +=== 5.原理图 === 
 +{{ :​icore3l:​icore3l_arm_hal_18_4.png?​direct |}} 
 +==== 四、实验程序 ==== 
 +1.主函数 
 +<code c> 
 +int main(void) 
 +
 +int i,j; 
 +  HAL_Init();​ 
 +  SystemClock_Config();​ 
 +  MX_GPIO_Init();​ 
 +  MX_FMC_Init();​ 
 +  BSP_SDRAM_Init();​ 
 +  for(j = 0; j < 64;​j++) ​ //​向SDRAM中写入0~65536并读取校验 
 +  { 
 +     for(i = 0;i < 65536;​i++) 
 +     { 
 + write_sdram((65536 * j + i),i); 
 +     } 
 +  } 
 +  for(j = 0; j < 64; j++) 
 +  { 
 +     for(i = 0;i < 65536;​i++) 
 +     { 
 + if(i != read_sdram((65536 * j + i))) //​读取SDRAM中的值,测试是否成功写入  
 +         {  
 +             ​while(1) ​      //​测试失败,红色LED闪烁 
 +      { 
 +   LED_RED_ON;​ 
 +   HAL_Delay(500);​ 
 +   LED_RED_OFF;​ 
 +   HAL_Delay(500);​ 
 +      } 
 +
 +     } 
 +  }  
 +  HAL_Delay(1000);​ 
 +  LED_RED_ON; ​       //​测试成功,红色LED常亮 
 +  while (1) 
 +  { 
 +  } 
 +}  
 +</​code>​ 
 +2.SDRAM初始化函数 
 +<code c> 
 +uint8_t BSP_SDRAM_Init(void) 
 +
 +  static uint8_t sdramstatus = SDRAM_ERROR;​ 
 +  /​*SDRAM设备配置*/​ 
 +  SdramHandle.Instance = FMC_SDRAM_DEVICE;​ 
 +  /* FMC SDRAM Bank配置 */ 
 +  /* SD时钟频率为90 Mhz的定时配置(180Mhz / 2) */ 
 +  /* TMRD:2个时钟周期 */ 
 +  Timing.LoadToActiveDelay ​   = 2; 
 +  /* TXSR:最小值= 70ns(7x11.11ns) */ 
 +  Timing.ExitSelfRefreshDelay = 7; 
 +  /* TRAS:最小值= 42ns(4x11.11ns)最大值= 120k(ns) */ 
 +  Timing.SelfRefreshTime ​     = 4; 
 +  /* TRC:最小值= 70(7x11.11ns) */ 
 +  Timing.RowCycleDelay ​       = 7; 
 +  /* TWR:最小值 = 1 + 7ns(1 + 1x11.11ns) */ 
 +  Timing.WriteRecoveryTime ​   = 2; 
 +  /* TRP:  20ns => 2x11.11ns*/​ 
 +  Timing.RPDelay ​             = 2; 
 +  /* TRCD: 20ns => 2x11.11ns */ 
 +  Timing.RCDDelay ​            = 2; 
 +  /* FMC SDRAM控制配置 */ 
 +  SdramHandle.Init.SDBank ​            = FMC_SDRAM_BANK1;​ 
 +  /* 列寻址: [7:0] */ 
 +  SdramHandle.Init.ColumnBitsNumber ​  = FMC_SDRAM_COLUMN_BITS_NUM_8;​ 
 +  /* 行寻址: [11:0] */ 
 +  SdramHandle.Init.RowBitsNumber ​     = FMC_SDRAM_ROW_BITS_NUM_12;​ 
 +  /​*SDRAM的数据宽度 */ 
 +  SdramHandle.Init.MemoryDataWidth ​   = SDRAM_MEMORY_WIDTH;​ 
 +  /​*SDRAM内部的Bank数目 */ 
 +  SdramHandle.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;​ 
 +  /​*CASLatency的时钟个数*/​ 
 +  SdramHandle.Init.CASLatency ​        = SDRAM_CAS_LATENCY;​ 
 +  /​*是否使能写保护模式 */ 
 +  SdramHandle.Init.WriteProtection ​   = FMC_SDRAM_WRITE_PROTECTION_DISABLE;​ 
 +  /​*配置同步时钟SDCLK的参数*/​ 
 +  SdramHandle.Init.SDClockPeriod ​     = SDCLOCK_PERIOD;​ 
 +  /​*是否使能突发读模式*/​ 
 +  SdramHandle.Init.ReadBurst ​         = SDRAM_READBURST;​ 
 +  /​*在CAS个延迟后再等待多少个HCLK时钟才读取数据 */ 
 +  SdramHandle.Init.ReadPipeDelay ​     = FMC_SDRAM_RPIPE_DELAY_1;​ 
 +  /​*SDRAM控制器初始化*/​ 
 +  BSP_SDRAM_MspInit(&​SdramHandle,​ (void *)NULL); 
 +  if(HAL_SDRAM_Init(&​SdramHandle,​ &​Timing) != HAL_OK) 
 +  { 
 +    sdramstatus = SDRAM_ERROR;​ 
 +  } 
 +  else 
 +  { 
 +    sdramstatus = SDRAM_OK; 
 +  } 
 +  /​*SDRAM初始化顺序*/​ 
 +  BSP_SDRAM_Initialization_sequence(REFRESH_COUNT);​ 
 +  return sdramstatus;​ 
 +
 +</​code>​ 
 +3.SDRAM读写函数 
 +<code c> 
 +#​define ​ write_sdram(offset,​data) *(volatile unsigned short int *)(SDRAM_DEVICE_ADDR + (offset << 1)) = data 
 +#​define ​ read_sdram(offset) *(volatile unsigned short int *)(SDRAM_DEVICE_ADDR + (offset << 1)) 
 +</​code>​ 
 +4.FMC初始化函数 
 +<code c> 
 +void MX_FMC_Init(void)   
 +{  //​本实验中我们只用到了FMC的引脚,时序配置使用官方提供的SDRAM驱动 
 +  FMC_SDRAM_TimingTypeDef SdramTiming = {0};​   
 +  /​* 执行SDRAM1存储器初始化序列 */​   
 +  hsdram1.Instance = FMC_SDRAM_DEVICE;​   
 +  /​* hsdram1初始化 */​   
 +  hsdram1.Init.SDBank = FMC_SDRAM_BANK1;​   
 +  hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;​   
 +  hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_13;​   
 +  hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16;​   
 +  hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;​   
 +  hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_1;​   
 +  hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;​   
 +  hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_DISABLE;​   
 +  hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_DISABLE;​   
 +  hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;​   
 +  /​* Sdram时序 */​   
 +  SdramTiming.LoadToActiveDelay = 16;​   
 +  SdramTiming.ExitSelfRefreshDelay = 16;​   
 +  SdramTiming.SelfRefreshTime = 16;​   
 +  SdramTiming.RowCycleDelay = 16;​    
 +  SdramTiming.WriteRecoveryTime = 16;​   
 +  SdramTiming.RPDelay = 16;​   
 +  SdramTiming.RCDDelay = 16;​   
 +  if (HAL_SDRAM_Init(&​hsdram1,​ &​SdramTiming) != HAL_OK)   
 +  {   
 +    Error_Handler( );​   
 +  }   
 +}   
 +</​code>​ 
 +==== 五、实验步骤 ==== 
 +  - 把仿真器与iCore3L的SWD调试口相连(直接相连或者通过转接器相连); 
 +  - 把iCore3L通过Micro USB线与计算机相连,为iCore3L供电; 
 +  - 打开Keil MDK 开发环境,并打开本实验工程; 
 +  - 烧写程序到iCore3L上; 
 +  - 也可以进入Debug 模式,单步运行或设置断点验证程序逻辑。 
 +==== 六、实验现象 ==== 
 +SDRAM读写测试成功,红色LED灯常亮。测试失败红色LED灯闪烁。
icore3l_18.1605061933.txt.gz · 最后更改: 2020/11/11 10:32 由 zgf