STM32F429IGT6项目准备5——使用STM32CubeMX配置SDRAM

1 前言

第五次记录一下使用CubeMX配置SDRAM的过程。STM32F429IGT6有两个SDRAM Bank,地址分别从0xC0000000, 0xD0000000开始,对应CubeMX配置里的SDRAM1和SDRAM2。每一个SDRAM控制器只可以连接一块SDRAM芯片。
在这里插入图片描述
注意:本文以前文为基础。默认配置好了FREERTOS,printf重定向

2 硬件

w9825G6KH-6I(32M字节16位宽)

3 Cubemx配置

3.1 SDRAM 2 的配置

芯片使能的选择需要看硬件上接的引脚。
其余参数参考芯片手册
在这里插入图片描述
在这里插入图片描述

4 工程内的修改

注意:到此为止,只是初始化好了单片机对RAM的接口,这块RAM需要发送一些初始化指令才可以正常工作,所以我们需要移植SDRAM的初始化文件,再进行测试。

以下代码仅供参考

4.1 移植文件

#include "sdram.h"   
#include "stdio.h"   
#include "fmc.h"
FMC_SDRAM_CommandTypeDef command;	// 控制指令

/*************************0*****************************************************************************
*	函 数 名: SDRAM_delay
*	入口参数: 无
*	返 回 值: 无
*	函数功能: 简易延时函数,单位约为5ms
*	说    明: 无
*******************************************************************************************************/

void SDRAM_delay(__IO uint32_t nCount)
{
  __IO uint32_t index = 0; 
	
  for(index = (100000 * nCount); index != 0; index--);

}

/******************************************************************************************************
*	函 数 名: SDRAM_Initialization_Sequence
*	入口参数: hsdram - SDRAM_HandleTypeDef定义的变量,即表示定义的sdram
*				 Command	- 控制指令
*	返 回 值: 无
*	函数功能: SDRAM 参数配置
*	说    明: 配置SDRAM相关时序和控制方式
*******************************************************************************************************/

void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command)
{
  __IO uint32_t tmpmrd = 0;
  
  /* Configure a clock configuration enable command */
  Command->CommandMode 					= FMC_SDRAM_CMD_CLK_ENABLE;	// 开启SDRAM时钟 
  Command->CommandTarget 				= FMC_COMMAND_TARGET_BANK; 	// 选择要控制的区域
  Command->AutoRefreshNumber 			= 1;
  Command->ModeRegisterDefinition 	= 0;
  
  HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);	// 发送控制指令
  SDRAM_delay(1);		// 延时等待
  
  /* Configure a PALL (precharge all) command */ 
  Command->CommandMode 					= FMC_SDRAM_CMD_PALL;		// 预充电命令
  Command->CommandTarget 				= FMC_COMMAND_TARGET_BANK;	// 选择要控制的区域
  Command->AutoRefreshNumber 			= 1;
  Command->ModeRegisterDefinition 	= 0;
  
  HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);  // 发送控制指令
  
  /* Configure a Auto-Refresh command */ 
  Command->CommandMode 					= FMC_SDRAM_CMD_AUTOREFRESH_MODE;	// 使用自动刷新
  Command->CommandTarget 				= FMC_COMMAND_TARGET_BANK;          // 选择要控制的区域
  Command->AutoRefreshNumber			= 8;                                // 自动刷新次数
  Command->ModeRegisterDefinition 	= 0;
  
  HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);	// 发送控制指令
  
  /* Program the external memory mode register */
  tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_2          |
                     SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL   |
                     SDRAM_MODEREG_CAS_LATENCY_3           |
                     SDRAM_MODEREG_OPERATING_MODE_STANDARD |
                     SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
  
  Command->CommandMode					= FMC_SDRAM_CMD_LOAD_MODE;	// 加载模式寄存器命令
  Command->CommandTarget 				= FMC_COMMAND_TARGET_BANK;	// 选择要控制的区域
  Command->AutoRefreshNumber 			= 1;
  Command->ModeRegisterDefinition 	= tmpmrd;
  
  HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);	// 发送控制指令
  
  hsdram->Instance->SDRTR |= ((uint32_t)((1386)<< 1));	// 设置刷新计数器 
}

/******************************************************************************************************
*	函 数 名: MX_FMC_Init
*	入口参数: 无
*	返 回 值: 无
*	函数功能: SDRAM初始化
*	说    明: 初始化FMC和SDRAM配置
*******************************************************************************************************/
void SDRAM_Cmd_Init(void)
{
	SDRAM_Initialization_Sequence(&hsdram2,&command);
}

uint8_t SDRAM_Test(void)
{
	uint32_t i = 0;		// 计数变量
	uint16_t ReadData = 0; 	// 读取到的数据
	uint8_t  ReadData_8b;
	
	printf("STM32F429 SDRAM test\r\n");
	printf("test start, 16bits dat write in...\r\n");	

	for (i = 0; i < SDRAM_Size/2; i++)
	{
 		*(__IO uint16_t*) (SDRAM_BANK_ADDR + 2*i) = (uint16_t)i;		// 写入数据
	}
	
	printf("write done. read and compare...\r\n");
	for(i = 0; i < SDRAM_Size/2;i++ )
	{
		ReadData = *(__IO uint16_t*)(SDRAM_BANK_ADDR + 2 * i );  // 从SDRAM读出数据	
		if( ReadData != (uint16_t)i )      //检测数据,若不相等,跳出函数,返回检测失败结果。
		{
			printf("16bit SDRAM test fail\r\n");
			return ERROR;	 // 返回失败标志
		}
	}
	
	printf("16bit test pass, 8 bit test start\r\n");
	for (i = 0; i < 255; i++)
	{
 		*(__IO uint8_t*) (SDRAM_BANK_ADDR + i) =  (uint8_t)i;
	}	
	printf("write done. read and compare....\r\n");
	for (i = 0; i < 255; i++)
	{
		ReadData_8b = *(__IO uint8_t*) (SDRAM_BANK_ADDR + i);
		if( ReadData_8b != (uint8_t)i )      //检测数据,若不相等,跳出函数,返回检测失败结果。
		{
			printf("8bit SDRAM test fail\r\n");
			printf("check NBL0 NBL1\r\n");	
			return ERROR;	 // 返回失败标志
		}
	}		
	printf("16bit test pass\r\n");
	printf("SDRAM  test pass\r\n");
	return SUCCESS;	 // 返回成功标志
}
#ifndef  __SDRAM_H
#define	__SDRAM_H

#include "main.h"

#define SDRAM_Size 0x02000000  //32M字节
#define SDRAM_BANK_ADDR     ((uint32_t)0xD0000000) 				// FMC SDRAM 数据基地址
#define FMC_COMMAND_TARGET_BANK   FMC_SDRAM_CMD_TARGET_BANK2	//	SDRAM 的bank选择
#define SDRAM_TIMEOUT     ((uint32_t)0x1000) 						// 超时判断时间

#define SDRAM_MODEREG_BURST_LENGTH_1             ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_LENGTH_2             ((uint16_t)0x0001)
#define SDRAM_MODEREG_BURST_LENGTH_4             ((uint16_t)0x0002)
#define SDRAM_MODEREG_BURST_LENGTH_8             ((uint16_t)0x0004)
#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL      ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED     ((uint16_t)0x0008)
#define SDRAM_MODEREG_CAS_LATENCY_2              ((uint16_t)0x0020)
#define SDRAM_MODEREG_CAS_LATENCY_3              ((uint16_t)0x0030)
#define SDRAM_MODEREG_OPERATING_MODE_STANDARD    ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000) 
#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE     ((uint16_t)0x0200) 

/*--------------------------------------- 函数声明 -------------------------------------*/

uint8_t 	SDRAM_Test(void);     		// SDRAM测试函数
void SDRAM_Cmd_Init(void);

#endif 

4.2 测试

主函数里调用 SDRAM_Cmd_Init(),SDRAM_Test();
在这里插入图片描述
注意,如果初始化指令出问题,或者忘记初始化直接测试的话,会出现以下状况
在这里插入图片描述
不需要改动BOOT引脚重新烧录,修改下载方式为under reset,然后按着复位键,点击keil下载键,复位立即松开即可。
在这里插入图片描述
有问题请留言,需要源码请评论区下方留邮箱
.
.
.
——END

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
### 回答1: STM32F767IGT6和STM32F429IGT6是STMicroelectronics推出的两款32位ARM Cortex-M微控制器。下面是两者的比较: 1. 处理器性能:STM32F767IGT6采用了ARM Cortex-M7内核,主频可达216 MHz,提供了更高的处理能力和更快的执行速度。而STM32F429IGT6使用了ARM Cortex-M4内核,主频为180 MHz。 2. 存储容量:STM32F767IGT6具有1MB的闪存和320KB的SRAM,而STM32F429IGT6则仅有1MB的闪存和256KB的SRAM。因此,前者提供了更大的存储容量,可以用于存储更多的程序和数据。 3. 外设和接口:两者均具有丰富的外设和接口,如多个USART、SPI、I2C、USB等。然而,STM32F767IGT6还拥有更多的接口和外设,如以太网MAC、SDIO、SDMMC、QSPI等,可以提供更多的连接和扩展选项。 4. 电源管理:STM32F767IGT6支持更多的低功耗模式,包括多个待机模式和休眠模式。这样可以进一步降低功耗,延长电池寿命。 5. 其他特性:STM32F767IGT6在外设和性能方面拥有一些额外的特性,如更多的定时器、DMA通道和ADC转换通道。同时,它还提供了更多的扩展功能,如温度传感器和自检。 综上所述,STM32F767IGT6在处理能力、存储容量、外设和接口等方面都更为强大,适用于对性能要求较高的应用场景。而STM32F429IGT6则适用于对功耗和成本有更高要求的应用。选择适合的芯片需根据具体应用需求来决定。 ### 回答2: STM32F767IGT6和STM32F429IGT6是两种不同型号的STM32单片机。它们在处理器核心、性能、外设等方面存在一些不同。 首先,STM32F767IGT6采用了ARM Cortex-M7内核,而STM32F429IGT6采用了ARM Cortex-M4内核。相对于Cortex-M4内核,Cortex-M7内核具有更强大的计算性能和更高的操作速度。 其次,STM32F767IGT6拥有更大的闪存和SRAM容量。它有2MB的闪存和512KB的SRAM,而STM32F429IGT6只有1MB的闪存和256KB的SRAM。更大的存储容量使得STM32F767IGT6能够运行更复杂的应用程序和存储更多的数据。 此外,STM32F767IGT6和STM32F429IGT6在外设方面也有一些差异。两者都配备了通用I/O端口、定时器、串行通信接口、USB接口等常见外设,但STM32F767IGT6还集成了以太网控制器、SDIO接口、CAN接口等更多功能。 总体上看,STM32F767IGT6相对于STM32F429IGT6具有更强大的处理器和更大的存储空间,可以支持更复杂的应用程序,并且集成了更多的外设功能。然而,选择适合的型号还要根据具体的应用需求和成本考虑。 ### 回答3: STM32F767IGT6和STM32F429IGT6STM32系列微控制器的两个不同型号。以下是它们之间的比较: 处理器性能:STM32F767IGT6采用Cortex-M7内核,主频为216 MHz,而STM32F429IGT6采用Cortex-M4内核,主频为180 MHz。因此,STM32F767IGT6具有更高的处理性能和更快的时钟速度。 存储容量:STM32F767IGT6具有更大的Flash存储器,容量为2 MB,而STM32F429IGT6的Flash容量为1 MB。此外,STM32F767IGT6还具有更大的RAM容量,为512 KB,而STM32F429IGT6RAM容量为256 KB。 外设功能:STM32F767IGT6和STM32F429IGT6都具有许多通用和专用外设,如UART、SPI、I2C、ADC和定时器等。然而,STM32F767IGT6具有更多的GPIO脚,为216个,比STM32F429IGT6的112个更多。此外,STM32F767IGT6还具有更多的专用外设,如以太网MAC、USB OTG等。 功耗:由于采用了不同的内核和处理器架构,STM32F767IGT6在性能方面可能会更耗电。对于更低功耗要求的应用,STM32F429IGT6可能是更好的选择。 总结:STM32F767IGT6和STM32F429IGT6在处理器性能、存储容量、外设功能和功耗方面有所区别。选择哪个型号主要取决于具体的应用需求和性能要求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菠萝地亚狂想曲

送我一瓶农夫山泉?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值