STM32CubeMX配置SDRAM
一、软件硬件说明
软件:STM32CubeMX V6.6.1 /KEIL5 V5.29
硬件:STM32F429ZET6
原理图:
芯片引脚:
二、FMC简介
三、SDRAM简介
SDRAM信号线说明:
存储单元
四、STM32CubeMX配置
RCC配置
SYS配置
USART1配置,参数默认,方便输出调试信息
FMC配置,SDRAM驱动接口,参数配置如下
正点原子配置参数如下:
查看《W9825G6KH》数据手册,即可看到对应的参数:
时钟配置
工程配置
生成代码
五、代码介绍
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相关推荐
- STM32利用STM32CubeMX驱动SDRAM
STM32利用STM32CubeMX驱动SDRAM 本次发布FMC总线驱动SDRAM的博客,为下次发布LTDC外设驱动RGB屏的博客做准备.利用STM32CubeMX和HAL库,生成的工程代码具有很强 ...
- 1:STM32CubeMX配置STM32F103C8T6驱动-下载软件配置RCC,CAN1,USART1
1:下载软件 点击 这里立即下载,共454M. 2:通过STM32CubeMX配置USART1,CAN1 1:创建工程 创建文件夹存放工程 添加工程名称及路径: 为每个驱动单独创建.c和.h文件. 2 ...
- 2:STM32CubeMX配置STM32F103C8T6驱动-TIM1配置
1:STM32CubeMX配置 1:确定时钟 2:设置1ms触发一次,72M/72/1000= 1000/s 定时器触发中断: 2:代码配置 在main.c中 /* USER CODE BEGIN 2 ...
- 用STM32CubeMX配置输出PWM信号控制多路舵机(HAL)
1.软件准备 (1)编程平台:Keil5 (2)CubeMX 2.硬件准备 (1)本此使用最小核心板STM32F103C8T6为例 (2)一个舵机:SG90或者MG996等均可 (3)ST-link ...
- STM32CUBEMX配置教程(八)STM32串口轮询发送中断接收+重定义+优化
STM32CUBEMX配置教程(八)STM32串口轮询发送中断接收+重定义+优化 基于STM32H743VI 使用STM32CUBEMX两年了,始终觉得这个工具非常的方便,但因为不是经常使用,导致有些 ...
- STM32CubeMX配置SD卡+DMA+Fatfs文件系统
STM32CubeMX配置SD卡+DMA+Fatfs文件系统 一.设备及软件 1.keil 2.STM32CubeMX 3.正点原子STM32F407探索者开发板 二.配置步骤 1.配置RCC外部晶振 ...
- 利用STM32CubeMX配置基于STMF32F407的FREERTOS操作系统控制直流电机速度和超声波测距实验
前两周做基于STM32F407芯片的嵌入式系统设计的实验,主要完成利用超声波测距(电脑上用串口显示超声波所测距离,障碍物近于20cm时,使LED灯闪烁,并且可以通过串口更改报警距离)和利用编码器读取电 ...
- STM32CubeMX 配置CAN总线进行双板通信(STM32F103C8T6)
本篇详细的记录了如何使用STM32CubeMX配置 STM32F103C8T6 的硬件CAN接口与另一个开发板之间通信. 1.硬件设计 我这里使用的TJA1050T作为CAN通信收发器,连接f103的 ...
- STM32CubeMX配置freertos配置任务(一)
使用STM32CubeMX 配置Freertos 生成一个任务点亮LED stm32cubemx STM32CubeMX 是 ST 意法半导体近几年来大力推荐的STM32 芯片图形化配置工具, 允许用 ...
最新文章
- 学习Spring中遇到关于BeanFactory及测试类的问题
- Oracle 11gR2构建RAC之(3)--安装grid前环境检测
- Qt IFW基本用法
- 网络编程 socket介绍
- 大数据处理与分析方向主要干什么_不了解干法制砂?6个影响干法制砂效果的主要因素及干法制砂生产加工7大技术要点分析...
- show interface counter
- python--简易员工信息系统编写
- aqua data studio 连接db2
- 勤哲excel服务器点击修改,用勤哲Excel服务器实现工作任务管理系统
- 中职学校计算机教学中,探析中职学校计算机教学中的一些体会和思考.doc
- 并查集详解(C/C++)
- 测试苹果电脑性能软件xbench在哪,Mac OS操作系统性能对比测试
- 基于STM32F103C8T6 HAL库 TM7705数据读取
- java项目:基于springboot高校党建管理系统(springboot+vue+mysql+redis) 1010
- codevs1253 超级市场(dp)
- PHP快速输出26大小写字母
- 统计字符串英文字母个数
- linux sh文件执行情况,Linux下SH执行
- SEO关键词(关键词策略连载1,2022更新)
- 我常去的几家GIS论坛