一、软件硬件说明

软件:STM32CubeMX V6.6.1 /KEIL5 V5.29

硬件:STM32F429ZET6

原理图:

芯片引脚:

二、FMC简介

三、SDRAM简介

SDRAM信号线说明:

存储单元

四、STM32CubeMX配置

  1. RCC配置

  1. SYS配置

  1. USART1配置,参数默认,方便输出调试信息

  1. FMC配置,SDRAM驱动接口,参数配置如下

正点原子配置参数如下:

查看《W9825G6KH》数据手册,即可看到对应的参数:

  1. 时钟配置

  1. 工程配置

  1. 生成代码

五、代码介绍

sdram.c

/*** @file sdram.c* @brief  SDRAM 的底层驱动(W9825G6KH-6 32M字节容量)* *//* 包含头文件 ----------------------------------------------------------*/  #include "sdram.h"
#include "fmc.h"/*
*********************************************************************************************************
*    函 数 名: SDRAM_Send_Cmd
*    功能说明: 向SDRAM发送命令
*    形    参: hsdram : SDRAM_HandleTypeDef 结构体
*              bankx :0,向BANK5上面的SDRAM发送指令 ; 1,向BANK6上面的SDRAM发送指令
*              cmd :指令(0,正常模式/1,时钟配置使能/2,预充电所有存储区/3,自动刷新/4,加载模式寄存器/5,自刷新/6,掉电)
*             refresh:自刷新次数
*             regval:模式寄存器的定义
*    返 回 值: 0,正常;1,失败.
*********************************************************************************************************
*/
uint8_t SDRAM_Send_Cmd(SDRAM_HandleTypeDef *hsdram,uint8_t bankx,uint8_t cmd,uint8_t refresh,uint16_t regval)
{uint32_t target_bank=0;FMC_SDRAM_CommandTypeDef Command;if(bankx==1) target_bank=FMC_SDRAM_CMD_TARGET_BANK1;       else if(bankx==2) target_bank=FMC_SDRAM_CMD_TARGET_BANK2;   Command.CommandMode=cmd;                //命令Command.CommandTarget=target_bank;      //目标SDRAM存储区域Command.AutoRefreshNumber=refresh;      //自刷新次数Command.ModeRegisterDefinition=regval;  //要写入模式寄存器的值if(HAL_SDRAM_SendCommand(hsdram,&Command,0X1000)==HAL_OK) //向SDRAM发送命令{return 0;  }else return 1;
}/*
*********************************************************************************************************
*    函 数 名: SDRAM_Init
*    功能说明: 发送SDRAM初始化序列
*    形    参: hsdram : SDRAM_HandleTypeDef 结构体
*    返 回 值: 无
*    备    注: 刷新频率计数器(以SDCLK频率计数),计算方法: COUNT=SDRAM刷新周期/行数-20=SDRAM刷新周期(us)*SDCLK频率(Mhz)/行数
*            我们使用的SDRAM刷新周期为64ms,SDCLK=168/2=84Mhz,行数为8192(2^13).    所以,COUNT=64*1000*84/8192-20=636
*********************************************************************************************************
*/
void SDRAM_Init(SDRAM_HandleTypeDef *hsdram)
{uint32_t temp=0;//SDRAM控制器初始化完成以后还需要按照如下顺序初始化SDRAMSDRAM_Send_Cmd(hsdram,1,FMC_SDRAM_CMD_CLK_ENABLE,1,0); //时钟配置使能      HAL_Delay(1);                                  //至少延时200usSDRAM_Send_Cmd(hsdram,1,FMC_SDRAM_CMD_PALL,1,0);       //对所有存储区预充电   SDRAM_Send_Cmd(hsdram,1,FMC_SDRAM_CMD_AUTOREFRESH_MODE,8,0);//设置自刷新次数   //配置模式寄存器,SDRAM的bit0~bit2为指定突发访问的长度,//bit3为指定突发访问的类型,bit4~bit6为CAS值,bit7和bit8为运行模式//bit9为指定的写突发模式,bit10和bit11位保留位temp=(uint32_t)SDRAM_MODEREG_BURST_LENGTH_1          |    //设置突发长度:1(可以是1/2/4/8)SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL   |    //设置突发类型:连续(可以是连续/交错)SDRAM_MODEREG_CAS_LATENCY_3           |    //设置CAS值:3(可以是2/3)SDRAM_MODEREG_OPERATING_MODE_STANDARD |   //设置操作模式:0,标准模式SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;     //设置突发写模式:1,单点访问SDRAM_Send_Cmd(hsdram,1,FMC_SDRAM_CMD_LOAD_MODE,1,temp);   //设置SDRAM的模式寄存器    HAL_SDRAM_ProgramRefreshRate(hsdram,636);//设置刷新频率
}/*
*********************************************************************************************************
*    函 数 名: FMC_SDRAM_WriteBuffer
*    功能说明: 在指定地址(WriteAddr+Bank5_SDRAM_ADDR)开始,连续写入n个字节.
*    形    参: pBuffer:字节指针
*             WriteAddr:要写入的地址
*             n:要写入的字节数
*    返 回 值: 无
*********************************************************************************************************
*/
void FMC_SDRAM_WriteBuffer(uint8_t *pBuffer,uint32_t WriteAddr,uint32_t n)
{for(;n!=0;n--){*(__IO uint8_t *)(Bank5_SDRAM_ADDR+WriteAddr)=*pBuffer;WriteAddr++;pBuffer++;}
}/*
*********************************************************************************************************
*    函 数 名: FMC_SDRAM_ReadBuffer
*    功能说明: 在指定地址((ReadAddr+Bank5_SDRAM_ADDR))开始,连续读出n个字节.
*    形    参: pBuffer:字节指针
*             WriteAddr:要读出的起始地址
*             n:要读出的字节数
*    返 回 值: 无
*********************************************************************************************************
*/
void FMC_SDRAM_ReadBuffer(uint8_t *pBuffer,uint32_t ReadAddr,uint32_t n)
{for(;n!=0;n--){*pBuffer++=*(__IO uint8_t *)(Bank5_SDRAM_ADDR+ReadAddr);ReadAddr++;}
}

sdram.h

#ifndef _SDRAM_H
#define _SDRAM_H#ifdef __cplusplus
extern "C" {
#endif/* 包含头文件 --------------------------------------------------------------------------------------------------------------------*/#include "main.h"/* 宏定义 ------------------------------------------------------------------------------------------------------------------------*/#define EXT_SDRAM_ADDR      ((uint32_t)0xC0000000)
#define EXT_SDRAM_SIZE        (32 * 1024 * 1024)#define Bank5_SDRAM_ADDR    ((uint32_t)(0XC0000000)) //SDRAM开始地址//SDRAM配置参数
#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)/* 类型定义 ---------------------------------------------------------------------------------------------------------------------*//* 扩展变量 --------------------------------------------------------------------------------------------------------------------*//* 函数声明 --------------------------------------------------------------------------------------------------------------------*/void FMC_SDRAM_WriteBuffer(uint8_t *pBuffer,uint32_t WriteAddr,uint32_t n);void FMC_SDRAM_ReadBuffer(uint8_t *pBuffer,uint32_t ReadAddr,uint32_t n);void SDRAM_Init(SDRAM_HandleTypeDef *hsdram);#ifdef __cplusplus
}
#endif#endif/******************* (C) COPYRIGHT 2021-2030  **********************************************END OF FILE***************************/

usart.c

/* USER CODE BEGIN Header */
/********************************************************************************* @file    usart.c* @brief   This file provides code for the configuration*          of the USART instances.******************************************************************************* @attention** Copyright (c) 2022 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "usart.h"/* USER CODE BEGIN 0 */
#include "stdio.h"
/* USER CODE END 0 */UART_HandleTypeDef huart1;/* USART1 init function */void MX_USART1_UART_Init(void)
{/* USER CODE BEGIN USART1_Init 0 *//* USER CODE END USART1_Init 0 *//* USER CODE BEGIN USART1_Init 1 *//* USER CODE END USART1_Init 1 */huart1.Instance = USART1;huart1.Init.BaudRate = 115200;huart1.Init.WordLength = UART_WORDLENGTH_8B;huart1.Init.StopBits = UART_STOPBITS_1;huart1.Init.Parity = UART_PARITY_NONE;huart1.Init.Mode = UART_MODE_TX_RX;huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;huart1.Init.OverSampling = UART_OVERSAMPLING_16;if (HAL_UART_Init(&huart1) != HAL_OK){Error_Handler();}/* USER CODE BEGIN USART1_Init 2 *//* USER CODE END USART1_Init 2 */}void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{GPIO_InitTypeDef GPIO_InitStruct = {0};if(uartHandle->Instance==USART1){/* USER CODE BEGIN USART1_MspInit 0 *//* USER CODE END USART1_MspInit 0 *//* USART1 clock enable */__HAL_RCC_USART1_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();/**USART1 GPIO ConfigurationPA9     ------> USART1_TXPA10     ------> USART1_RX*/GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF7_USART1;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);/* USER CODE BEGIN USART1_MspInit 1 *//* USER CODE END USART1_MspInit 1 */}
}void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{if(uartHandle->Instance==USART1){/* USER CODE BEGIN USART1_MspDeInit 0 *//* USER CODE END USART1_MspDeInit 0 *//* Peripheral clock disable */__HAL_RCC_USART1_CLK_DISABLE();/**USART1 GPIO ConfigurationPA9     ------> USART1_TXPA10     ------> USART1_RX*/HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);/* USER CODE BEGIN USART1_MspDeInit 1 *//* USER CODE END USART1_MspDeInit 1 */}
}/* USER CODE BEGIN 1 */
//加入以下代码,支持printf函数,而不需要选择use MicroLIB#pragma import(__use_no_semihosting)
struct __FILE
{int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{while((USART1->SR&0X40)==0);//循环发送,直到发送完毕USART1->DR = (int) ch;return ch;
}/* USER CODE END 1 */

main.c

/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** Copyright (c) 2022 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usart.h"
#include "gpio.h"
#include "fmc.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "sdram.h"
#include "stdio.h"
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV */
uint8_t writebuf[8]  __attribute__((at(EXT_SDRAM_ADDR)));//将数组定义在外部SDRAM中
uint8_t writebuf1[8] = {0x11,0x22,0x33,0x44,0x55,0x66,0x5a,0xa5};
uint8_t readbuf[8];
uint8_t readbuf1[8];
uint8_t i = 0;
/* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *//* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_FMC_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */printf("SDRAM Test\r\n");SDRAM_Init(&hsdram1);
//    for(i = 0;i<8;i++)
//    {
//        writebuf[i] = 0x5a;
//    }
//
//    FMC_SDRAM_ReadBuffer(readbuf,0,8);FMC_SDRAM_WriteBuffer(writebuf1,0,8);HAL_Delay(100);FMC_SDRAM_ReadBuffer(readbuf1,0,8);for(i=0;i<8;i++){printf("%#x ",readbuf1[i]);}/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Configure the main internal regulator output voltage*/__HAL_RCC_PWR_CLK_ENABLE();__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;RCC_OscInitStruct.PLL.PLLM = 8;RCC_OscInitStruct.PLL.PLLN = 168;RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;RCC_OscInitStruct.PLL.PLLQ = 4;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK){Error_Handler();}
}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

六、程序运行结果

两种验证方式:

第一种,直接将数组定义在外部SDRAM中,初始化时给数组赋值,然后读取SDRAM里面的数据

    printf("SDRAM Test\r\n");SDRAM_Init(&hsdram1);for(i = 0;i<8;i++){writebuf[i] = 0x5a;}FMC_SDRAM_ReadBuffer(readbuf,0,8);

串口调试助手截图;

程序DEBUG截图:

第二种验证方式,初始化时先写入数据到SDRAM,然后再读出数据,进行比对

/*第二种验证方式*/FMC_SDRAM_WriteBuffer(writebuf1,0,8);HAL_Delay(100);FMC_SDRAM_ReadBuffer(readbuf1,0,8);for(i=0;i<8;i++){printf("%#x ",readbuf1[i]);}

串口调试助手截图:

程序DEBUG截图:

至此,SDRAM测试成功。

七、工程链接

百度网盘链接:

链接:https://pan.baidu.com/s/1BvXDRRaWepTVMPznlEXFXw

提取码:93fx

STM32CubeMX配置SDRAM相关推荐

  1. STM32利用STM32CubeMX驱动SDRAM

    STM32利用STM32CubeMX驱动SDRAM 本次发布FMC总线驱动SDRAM的博客,为下次发布LTDC外设驱动RGB屏的博客做准备.利用STM32CubeMX和HAL库,生成的工程代码具有很强 ...

  2. 1:STM32CubeMX配置STM32F103C8T6驱动-下载软件配置RCC,CAN1,USART1

    1:下载软件 点击 这里立即下载,共454M. 2:通过STM32CubeMX配置USART1,CAN1 1:创建工程 创建文件夹存放工程 添加工程名称及路径: 为每个驱动单独创建.c和.h文件. 2 ...

  3. 2:STM32CubeMX配置STM32F103C8T6驱动-TIM1配置

    1:STM32CubeMX配置 1:确定时钟 2:设置1ms触发一次,72M/72/1000= 1000/s 定时器触发中断: 2:代码配置 在main.c中 /* USER CODE BEGIN 2 ...

  4. 用STM32CubeMX配置输出PWM信号控制多路舵机(HAL)

    1.软件准备 (1)编程平台:Keil5 (2)CubeMX 2.硬件准备 (1)本此使用最小核心板STM32F103C8T6为例 (2)一个舵机:SG90或者MG996等均可 (3)ST-link ...

  5. STM32CUBEMX配置教程(八)STM32串口轮询发送中断接收+重定义+优化

    STM32CUBEMX配置教程(八)STM32串口轮询发送中断接收+重定义+优化 基于STM32H743VI 使用STM32CUBEMX两年了,始终觉得这个工具非常的方便,但因为不是经常使用,导致有些 ...

  6. STM32CubeMX配置SD卡+DMA+Fatfs文件系统

    STM32CubeMX配置SD卡+DMA+Fatfs文件系统 一.设备及软件 1.keil 2.STM32CubeMX 3.正点原子STM32F407探索者开发板 二.配置步骤 1.配置RCC外部晶振 ...

  7. 利用STM32CubeMX配置基于STMF32F407的FREERTOS操作系统控制直流电机速度和超声波测距实验

    前两周做基于STM32F407芯片的嵌入式系统设计的实验,主要完成利用超声波测距(电脑上用串口显示超声波所测距离,障碍物近于20cm时,使LED灯闪烁,并且可以通过串口更改报警距离)和利用编码器读取电 ...

  8. STM32CubeMX 配置CAN总线进行双板通信(STM32F103C8T6)

    本篇详细的记录了如何使用STM32CubeMX配置 STM32F103C8T6 的硬件CAN接口与另一个开发板之间通信. 1.硬件设计 我这里使用的TJA1050T作为CAN通信收发器,连接f103的 ...

  9. STM32CubeMX配置freertos配置任务(一)

    使用STM32CubeMX 配置Freertos 生成一个任务点亮LED stm32cubemx STM32CubeMX 是 ST 意法半导体近几年来大力推荐的STM32 芯片图形化配置工具, 允许用 ...

最新文章

  1. 学习Spring中遇到关于BeanFactory及测试类的问题
  2. Oracle 11gR2构建RAC之(3)--安装grid前环境检测
  3. Qt IFW基本用法
  4. 网络编程 socket介绍
  5. 大数据处理与分析方向主要干什么_不了解干法制砂?6个影响干法制砂效果的主要因素及干法制砂生产加工7大技术要点分析...
  6. show interface counter
  7. python--简易员工信息系统编写
  8. aqua data studio 连接db2
  9. 勤哲excel服务器点击修改,用勤哲Excel服务器实现工作任务管理系统
  10. 中职学校计算机教学中,探析中职学校计算机教学中的一些体会和思考.doc
  11. 并查集详解(C/C++)
  12. 测试苹果电脑性能软件xbench在哪,Mac OS操作系统性能对比测试
  13. 基于STM32F103C8T6 HAL库 TM7705数据读取
  14. java项目:基于springboot高校党建管理系统(springboot+vue+mysql+redis) 1010
  15. codevs1253 超级市场(dp)
  16. PHP快速输出26大小写字母
  17. 统计字符串英文字母个数
  18. linux sh文件执行情况,Linux下SH执行
  19. SEO关键词(关键词策略连载1,2022更新)
  20. 我常去的几家GIS论坛

热门文章

  1. CRC校验的理解和计算过程
  2. 360°透视:云原生架构演进
  3. 感染Nimda蠕虫病毒
  4. python编程案例-几个Python小案例,爱上Python编程!
  5. 联系苹果开发者客服的一些情况须知 App Store发布更新延迟原因
  6. Googlenbsp;Earth中高级使用技巧(一)
  7. win7怎么掉出计算机,win7输入法不见了要怎么调出来【详解】
  8. 【在线仿真】Arduino UNO PWM 控制直流电机转速
  9. 每位架构师都应该熟知的 10 个 SOA 设计模式
  10. LNK ERROR 2005