bigbat

  • 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的板子基本上都是使用问题,坑很少。  

统计信息

已有1019人来访过

  • 芯积分:3951
  • 好友:8
  • 主题:471
  • 回复:2105
  • 课时:--
  • 资源:2

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言