- 2023-12-07
-
回复了主题帖:
如何修改嵌入式程序的Heap和Stack的大小
lugl4313820 发表于 2023-12-7 08:40
大大佬,修改栈堆空间后,lvgl还出状况吗?分享一下呗!
正常了,我将heap和stack都各加0x200,可以正常使用了
- 2023-12-06
-
发表了主题帖:
如何修改嵌入式程序的Heap和Stack的大小
在一些项目中,如RTOS或GUI项目中默认的Heap和Stack的大小可能不能运行,如我的一个lvgl项目,由于这两者的size使用默认值,导致程序经常死机。所以在项目生成后需要修改Heap和Stack的尺寸,那么针对keil项目和GNU项目如何修改呢,下面就分别说明:
keil项目的Heap和Stack的尺寸在startup_stm32fxxxx.s文件中,
修改Stack_Size和Heap_Size的值,就可以修改需要的值了。
GNU项目的Stack Size和Heap Size的值,不在startup_stm32f746xx.s里,而是在LinkerScript.ld连接脚本里。
修改上面的_Min_Heap_Size和_Min_Stack_Size就可以修改默认的值了。
对于不同的项目,Heap和Stack到底需要多大,根据项目需求而异,如果函数中的参数较多或全套较深则Stack较大,动态参数较多较大则Heap较大。虽然这两个值越大越好,但是也要根据项目的实际内存而定。
-
回复了主题帖:
STM32的keil和GNU项目有何区别
谢谢@lugl4313820,我将Stack_Size和Heap_Size都各加了0x200,问题真的没有了。
再次的感谢。
-
回复了主题帖:
STM32的keil和GNU项目有何区别
各位能不能说说如何查看gnu项目的内存分配设置。这个不知道是在哪个文件里设置。
-
回复了主题帖:
STM32的keil和GNU项目有何区别
韵湖葱白 发表于 2023-12-6 17:19
直接可以查到hardfault的地址啊
怎么查看hardfault是什么故障引起的。
-
回复了主题帖:
STM32的keil和GNU项目有何区别
lugl4313820 发表于 2023-12-6 16:44
你要看看栈堆分配合理不合理,想要知道在哪里出错了,打开lvgl的日志打印开关。我在前面的调试中总结就是lv ...
谢谢,我这就去看一下参数是不是合理,你说的很有道理。
-
发表了主题帖:
Vscode+openocd配置的技巧
如果想使用GNU gcc-arm-none-eabi-gcc来开发项目,遇到的挑战就是如何在烧写和debug代码了,开源的ide常见的有基于eclipse、CLion和vscode,基于前面两种的都是java平台的,无论内存和效率都有点高,但是优点是项目的配置较少,vscode的效率和内存占用少但是项目的配置较复杂。本文是我自己的一点经验总结,配置过程如下:
一、准备工作:
需要的软件,VSCode-win32-x64-1.84.2.zip ,这个到https://code.visualstudio.com/download下载
编译器 gcc-arm-none-eabi-10.3-2021.10.zip https://developer.arm.com/downloads/-/gnu-rm/10-3-2021-10
下载和调试工具 openocd xpack-openocd-0.12.0-2,https://github.com/xpack-dev-tools/openocd-xpack/releases/tag/v0.12.0-2/
项目工具CMAKE,https://cmake.org/download/
项目工具ninja,https://github.com/ninja-build/ninja/releases
其它的就是调试器jlink、stlink的驱动了。
二、安装各种软件
这个很少简单,将所有的软件解压到磁盘的项目下,
向我这样,比较省事都统统放在C盘,然后就是设置环境变量,PATH
在加入一个变量
这个变量是配置openocd vscode时用到地。
完成后加入CMD命令,检验一下
如果成功,进行下一步。
三、安装vscode插件,
上面的插件确保安装成功,
四、构建CMAKE项目,
我使用的是STM32CubeMX构建项目,使用stlink调试项目。
使用vscode打开项目,
运行debug编译项目既可以,这是生成debug项目
到此时项目就算成功了一半了。
五、配置debug设置
这是最最关键的一步,谁也不是神仙,写代码难免会出错,所以调试就是最关键的了。
如果你向我一样比较急切地去debug,很可能是失败的。
参考上面地设置,
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Debug (Remote OpenOCD)",
"type":"cortex-debug",
// "cortex-debug.armToolchainPath":"${env:ARM_NONE_EABI_TOOLCHAIN_PATH}/bin",
"cwd": "${workspaceRoot}",
"executable": "${workspaceRoot}/build/debug/lv_stm32f746.elf",
"request": "launch",
"servertype": "external",
// This may need to be arm-none-eabi-gdb depending on your system
// "gdbPath" : "${env:ARM_NONE_EABI_TOOLCHAIN_PATH}/bin/arm-none-eabi-gdb",
// Connect to an already running OpenOCD instance
"gdbTarget": "localhost:3333",
"svdFile": "${workspaceRoot}/.vscode/STM32F746.svd",
"runToMain": false,
// Work around for stopping at main on restart
"postRestartCommands": [
"break main",
"continue"
]
},
{
"cwd": "${workspaceRoot}",
"executable": "${workspaceRoot}/build/debug/lv_stm32f746.elf",
"cortex-debug.armToolchainPath":"${env:ARM_NONE_EABI_TOOLCHAIN_PATH}/bin",
"device": "STM32F746NGH6",
"configFiles": [
"interface/stlink.cfg",
"target/stm32f7x.cfg"
],
"name": "Debug (Local OpenOCD)",
"request": "launch",
"type": "cortex-debug",
"showDevDebugOutput": false,
"gdbPath" : "${env:ARM_NONE_EABI_TOOLCHAIN_PATH}/bin/arm-none-eabi-gdb",
"svdFile": "${workspaceRoot}/.vscode/STM32F746.svd",
"servertype": "openocd",
"runToMain": true,
}
]
}
关键地是: "gdbPath" : "${env:ARM_NONE_EABI_TOOLCHAIN_PATH}/bin/arm-none-eabi-gdb",和 "cortex-debug.armToolchainPath":"${env:ARM_NONE_EABI_TOOLCHAIN_PATH}/bin",
这里面的设置指向了调试工具的目录,上面配置的ARM_NONE_EABI_TOOLCHAIN_PATH环境参数
然后就是启动调试了
看到断点可以调试了。
-
回复了主题帖:
STM32的keil和GNU项目有何区别
wangerxian 发表于 2023-12-6 16:29
你可以看看是从哪里跳到硬件错误的。
这个难度非常的高,因为使用的程序不能单步的进行,必须连续运行,除非调试器有回溯功能,在断电处上溯代码。
-
发表了主题帖:
STM32的keil和GNU项目有何区别
实验的板子是STM32F746G-DISCO,板子上带有lcd屏幕,mcu STM32 F7 ARM® Cortex®-M7 MCU 32-位,带有网络和麦克风等外设,
但是软件是ST的GUI,所以想把LVGL移植到板子上面,开始想使用keil来开发项目,但是总是不成功直到找到这个项目lv_port_stm32f746_disco,但是该项目是使用IAR和GNU类型地,所以自己就参考这个项目进行移植,非常辛苦的完成了项目。
但是最好的效果就是,界面出现后,只要使用屏幕滑动一下就死机了。以后就再也不能使用了。
滑动以后
就再也不能移动了。
程序就死在了这里,而且这时中断SysTick_Handler也无法进入,好像是出现了什么硬件故障。我的处理是把所有的关于所有的初始化和驱动代码都使用项目lv_port_stm32f746_disco的代码进行了替换,故障仍然依旧。
如果使用gcc-arm-none-eabi和CMAKE编译的lv_port_stm32f746_disco项目,却可以正常运行,该问题不止我遇到了,在网上也有其它人也出现了。
不知道有没有人知道这是为什么?
- 2023-12-05
-
回复了主题帖:
CPU自制入门
先下载,有时间好好的研究一下,CPU的结构大体知道,就是不知道编译器怎么做。呵呵
- 2023-12-04
-
回复了主题帖:
一起读《奔跑吧Linux内核(第2版)卷1:基础架构》——初识
看了好多关于linux内核的东西,其实关于系统的和编译器的知识感觉更重要一些,没有这些知识阅读内核很可以只是范范的了解一下,不能实践和项目应用。
- 2023-12-03
-
回复了主题帖:
【STM32U599J-DK】视频分享:从零创建touchGFX示例工程
touchGFX是ST的主要图形系统,微软的GUIX都没有什么吸引力了。
- 2023-12-02
-
回复了主题帖:
如何使用STM32 LTDC显示图像
这个问题我也解决了,主要是没有打开显示开关造成的。加入GPIO设置后,使用
/* USER CODE BEGIN LTDC_Init 2 */
/* Assert display enable LCD_DISP pin */
HAL_GPIO_WritePin(LCD_DISP_GPIO_Port, LCD_DISP_Pin, GPIO_PIN_SET);
/* Assert backlight LCD_BL_CTRL pin */
HAL_GPIO_WritePin(LCD_BL_CTRL_GPIO_Port, LCD_BL_CTRL_Pin, GPIO_PIN_SET);
/* USER CODE END LTDC_Init 2 */
static void MX_LTDC_Init(void)
{
/* USER CODE BEGIN LTDC_Init 0 */
/* USER CODE END LTDC_Init 0 */
LTDC_LayerCfgTypeDef pLayerCfg = {0};
/* USER CODE BEGIN LTDC_Init 1 */
/* USER CODE END LTDC_Init 1 */
hltdc.Instance = LTDC;
hltdc.Init.HSPolarity = LTDC_HSPOLARITY_AL;
hltdc.Init.VSPolarity = LTDC_VSPOLARITY_AL;
hltdc.Init.DEPolarity = LTDC_DEPOLARITY_AL;
hltdc.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
hltdc.Init.HorizontalSync = 40;
hltdc.Init.VerticalSync = 9;
hltdc.Init.AccumulatedHBP = 53;
hltdc.Init.AccumulatedVBP = 11;
hltdc.Init.AccumulatedActiveW = 533;
hltdc.Init.AccumulatedActiveH = 283;
hltdc.Init.TotalWidth = 565;
hltdc.Init.TotalHeigh = 285;
hltdc.Init.Backcolor.Blue = 0;
hltdc.Init.Backcolor.Green = 0;
hltdc.Init.Backcolor.Red = 0;
if (HAL_LTDC_Init(&hltdc) != HAL_OK)
{
Error_Handler();
}
pLayerCfg.WindowX0 = 0;
pLayerCfg.WindowX1 = 480;
pLayerCfg.WindowY0 = 0;
pLayerCfg.WindowY1 = 272;
pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;
pLayerCfg.Alpha = 255;
pLayerCfg.Alpha0 = 0;
pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;
pLayerCfg.FBStartAdress = 0xC0000000;
pLayerCfg.ImageWidth = 480;
pLayerCfg.ImageHeight = 272;
pLayerCfg.Backcolor.Blue = 0;
pLayerCfg.Backcolor.Green = 0;
pLayerCfg.Backcolor.Red = 0;
if (HAL_LTDC_ConfigLayer(&hltdc, &pLayerCfg, 0) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN LTDC_Init 2 */
/* Assert display enable LCD_DISP pin */
HAL_GPIO_WritePin(LCD_DISP_GPIO_Port, LCD_DISP_Pin, GPIO_PIN_SET);
/* Assert backlight LCD_BL_CTRL pin */
HAL_GPIO_WritePin(LCD_BL_CTRL_GPIO_Port, LCD_BL_CTRL_Pin, GPIO_PIN_SET);
/* USER CODE END LTDC_Init 2 */
}
然后就可以显示了
-
回复了主题帖:
【STM32MP135F-DK】 篇一:开箱&硬件测评
"ST非常慷慨,设计资源不藏着掖着,这是国产单片机厂家不所具备的。我感觉我在看一件艺术品。"
这一点我感觉说到点子上了,国产的某志、某芯微都是这个德行。搞得你想使用它家的产品时有点不知所措
- 2023-12-01
-
发表了主题帖:
如何使用STM32 LTDC显示图像
我使用STM32Cube生成的MX_LTDC_Init()初始化,将代码中的 pLayerCfg.FBStartAdress = 0xC00000000;修改成pLayerCfg.FBStartAdress = (uint32_t)&RGB565_480x272;可以显示图像,
但是,如果将pLayerCfg.FBStartAdress = 0xC00000000初始化,然后向0xC00000000写数据,则不会有任何显示。不知道除了向pLayerCfg.FBStartAdress写数据还需要什么其它操作。
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();
/* Configure the peripherals common clocks */
PeriphCommonClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ADC3_Init();
MX_CRC_Init();
MX_DCMI_Init();
MX_DMA2D_Init();
MX_ETH_Init();
MX_FMC_Init();
MX_I2C1_Init();
MX_I2C3_Init();
MX_LTDC_Init();
MX_QUADSPI_Init();
MX_RTC_Init();
MX_SAI2_Init();
MX_SDMMC1_SD_Init();
MX_SPDIFRX_Init();
MX_SPI2_Init();
MX_TIM1_Init();
MX_TIM2_Init();
MX_TIM3_Init();
MX_TIM5_Init();
MX_TIM8_Init();
MX_TIM12_Init();
MX_USART1_UART_Init();
MX_USART6_UART_Init();
MX_FATFS_Init();
MX_USB_OTG_FS_HCD_Init();
/* USER CODE BEGIN 2 */
for(uint16_t i=0;i<65280;i++)
{
sdram[i] = RGB565_480x272[i];
}
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
HAL_Delay(1000);
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
- 2023-11-29
-
回复了主题帖:
SDRAM让人迷惑的地址访问问题
常见泽1 发表于 2023-11-29 14:19
是因为除了MX_FMC_Init()函数外,还需要启动FMC SDRAM外设的初始化,需要加入的函数
__
是的 这个必 ...
能使用的是那个型号的芯片。
-
发表了主题帖:
SDRAM让人迷惑的地址访问问题
使用的编译器是keil V5.38.0.0版本,编译器是: 'V5.06 update 7 (build 960)',使用过 'V6.19',程序无法执行会死机的。
我在本站发的 STM32 SDRAM奇怪的读写问题,这个已经解决了,是因为除了MX_FMC_Init()函数外,还需要启动FMC SDRAM外设的初始化,需要加入的函数如下:
/**
* [url=home.php?mod=space&uid=159083]@brief[/url] Perform the SDRAM external memory initialization sequence
* @param hsdram: SDRAM handle
* @param Command: Pointer to SDRAM command structure
* @retval None
*/
static void BSP_SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command)
{
__IO uint32_t tmpmrd =0;
/* Step 3: Configure a clock configuration enable command */
Command->CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
/* Step 4: Insert 100 us minimum delay */
/* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
HAL_Delay(1);
/* Step 5: Configure a PALL (precharge all) command */
Command->CommandMode = FMC_SDRAM_CMD_PALL;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
/* Step 6 : Configure a Auto-Refresh command */
Command->CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command->AutoRefreshNumber = 8;
Command->ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
/* Step 7: Program the external memory mode register */
tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
SDRAM_MODEREG_CAS_LATENCY_2 |
SDRAM_MODEREG_OPERATING_MODE_STANDARD |
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
Command->CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = tmpmrd;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
/* Step 8: Set the refresh rate counter */
/* (15.62 us x Freq) - 20 */
/* Set the device refresh counter */
hsdram->Instance->SDRTR |= ((uint32_t)((1292)<< 1));
}
执行BSP_SDRAM_Initialization_Sequence()函数以后就可以访问SDRAM了。
虽然可以访问SDRAM了,但是带来了更加让我困惑的问题。先上代码
/* USER CODE BEGIN Header */
/**
******************************************************************************
* [url=home.php?mod=space&uid=1307177]@File[/url] : main.c
* @brief : Main program body
******************************************************************************
* [url=home.php?mod=space&uid=1020061]@attention[/url] *
* Copyright (c) 2023 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"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* Exported constants --------------------------------------------------------*/
#define SDRAM_BANK_ADDR ((uint32_t)0xC0000000)
/* #define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_8 */
#define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_16
#define SDCLOCK_PERIOD FMC_SDRAM_CLOCK_PERIOD_2
/* #define SDCLOCK_PERIOD FMC_SDRAM_CLOCK_PERIOD_3 */
#define SDRAM_TIMEOUT ((uint32_t)0xFFFF)
#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)
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
static void BSP_SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command);
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart1;
SDRAM_HandleTypeDef hsdram1;
/* USER CODE BEGIN PV */
#ifdef __GNUC__
/* With GCC, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1 , 0xffff);
return ch;
}
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_FMC_Init(void);
static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP */
uint16_t sdramv[1000] __attribute__ ((at(SDRAM_BANK_ADDR)));
//uint16_t sdramv[1000];
/* 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("UART Printf Example: retarget the C library printf function to the UART\n");
for(int16_t i=0;i<16;i++)
{
sdramv[i] = i;
}
for(int16_t i=0;i<16;i++)
{
printf("sdramv[%d]=%d\n",i,sdramv[i]);
}
/* USER CODE END 2 */
printf("sdramv[0]=%d\n",sdramv[0]);
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
HAL_Delay(100);
/* 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 LSE Drive Capability
*/
HAL_PWR_EnableBkUpAccess();
/** 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_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 25;
RCC_OscInitStruct.PLL.PLLN = 400;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Activate the Over-Drive mode
*/
if (HAL_PWREx_EnableOverDrive() != 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_6) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief USART1 Initialization Function
* @param None
* @retval None
*/
static 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;
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
}
/* FMC initialization function */
static void MX_FMC_Init(void)
{
/* USER CODE BEGIN FMC_Init 0 */
FMC_SDRAM_CommandTypeDef command;
/* USER CODE END FMC_Init 0 */
FMC_SDRAM_TimingTypeDef SdramTiming = {0};
/* USER CODE BEGIN FMC_Init 1 */
/* USER CODE END FMC_Init 1 */
/** Perform the SDRAM1 memory initialization sequence
*/
hsdram1.Instance = FMC_SDRAM_DEVICE;
/* hsdram1.Init */
hsdram1.Init.SDBank = FMC_SDRAM_BANK1;
hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;
hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
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_3;
hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
/* SdramTiming */
SdramTiming.LoadToActiveDelay = 2;
SdramTiming.ExitSelfRefreshDelay = 7;
SdramTiming.SelfRefreshTime = 4;
SdramTiming.RowCycleDelay = 7;
SdramTiming.WriteRecoveryTime = 3;
SdramTiming.RPDelay = 2;
SdramTiming.RCDDelay = 2;
if (HAL_SDRAM_Init(&hsdram1, &SdramTiming) != HAL_OK)
{
Error_Handler( );
}
/* USER CODE BEGIN FMC_Init 2 */
BSP_SDRAM_Initialization_Sequence(&hsdram1, &command);
/* USER CODE END FMC_Init 2 */
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}
/* USER CODE BEGIN 4 */
/**
* @brief Perform the SDRAM external memory initialization sequence
* @param hsdram: SDRAM handle
* @param Command: Pointer to SDRAM command structure
* @retval None
*/
static void BSP_SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command)
{
__IO uint32_t tmpmrd =0;
/* Step 3: Configure a clock configuration enable command */
Command->CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
/* Step 4: Insert 100 us minimum delay */
/* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
HAL_Delay(1);
/* Step 5: Configure a PALL (precharge all) command */
Command->CommandMode = FMC_SDRAM_CMD_PALL;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
/* Step 6 : Configure a Auto-Refresh command */
Command->CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command->AutoRefreshNumber = 8;
Command->ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
/* Step 7: Program the external memory mode register */
tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
SDRAM_MODEREG_CAS_LATENCY_2 |
SDRAM_MODEREG_OPERATING_MODE_STANDARD |
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
Command->CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = tmpmrd;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
/* Step 8: Set the refresh rate counter */
/* (15.62 us x Freq) - 20 */
/* Set the device refresh counter */
hsdram->Instance->SDRTR |= ((uint32_t)((1292)<< 1));
}
/* 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[0]的值应该是0,而不应该是1,而且好像数组的位置都向后移动了。
但是如果使用芯片的SRAM内存就没有这个问题。代码调整如下:
运行结果如下:
以上的问题不知道为什么?
还有就是:uint16_t sdramv[1000] __attribute__ ((at(SDRAM_BANK_ADDR)));
这个的at 语句如何理解。
-
回复了主题帖:
STM32 SDRAM奇怪的读写问题
这个问题搞定了,是因为除了MX_FMC_Init外还需要启动SDRAM外设的操作。
static void BSP_SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command)
{
__IO uint32_t tmpmrd =0;
/* Step 3: Configure a clock configuration enable command */
Command->CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
/* Step 4: Insert 100 us minimum delay */
/* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
HAL_Delay(1);
/* Step 5: Configure a PALL (precharge all) command */
Command->CommandMode = FMC_SDRAM_CMD_PALL;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
/* Step 6 : Configure a Auto-Refresh command */
Command->CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command->AutoRefreshNumber = 8;
Command->ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
/* Step 7: Program the external memory mode register */
tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
SDRAM_MODEREG_CAS_LATENCY_2 |
SDRAM_MODEREG_OPERATING_MODE_STANDARD |
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
Command->CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = tmpmrd;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
/* Step 8: Set the refresh rate counter */
/* (15.62 us x Freq) - 20 */
/* Set the device refresh counter */
hsdram->Instance->SDRTR |= ((uint32_t)((1292)<< 1));
}
否则无法使用FMC外设。
-
回复了主题帖:
spi flash是否可以位写?
辛昕 发表于 2023-11-29 10:37
你考虑这么一个情况。
如果我要不断地往前覆盖,就是不在同一个地址写数据,
假如是 int a b c d
...
软件行业有一则谚语:“输入的是垃圾,输出也是垃圾!”,谚语的原文我忘记了,普遍的翻译是这样的,我当时理解的是“输入如为null,输出也是null”,(还请知道原文的小伙伴告诉我一下)。
你没有时间维度的任何信息还想查找最后一个覆盖写位置,还谈论什么“最坏情况就是 O(n)”,这很无语!
除非在数据上有“时间戳”或其它什么标记时间的方案,否则就是在搞笑哦!
-
回复了主题帖:
STM32MP135DA板裸机开发,下载不了程序
去看看手册,这种BOOT模式是用来烧写程序的,使用STM32Programmer,看这里好好研究一下,不要动不动就是大坑之类的,ST的板子基本上都是使用问题,坑很少。