你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32CubeMX底层配置代码自动代码生成

[复制链接]
STMCU-管管 发布时间:2020-10-16 16:00
STM32CubeMX + HAL
一些说明
底层配置

使用STM32CubeMX代码生成工具,不用关注底层配置的细节,真舒服。

使用教程:
https://sxf1024.lanzoui.com/b09rf2dwj   密码:bgvi
虽然Cube+HAL很舒服,但新手不建议用。最好还是先去学一下标准库怎么用,有个大致概念后,再来学这一套。
Cube基本使用
新建工程

选择芯片
Pinout&Configuration,选择RCC(HSE:Crystal/Ceramic Resonator)、SYS(Debug:Serial Wiire)
Clock Configuration,配置时钟树
11.png
Project Manager,配置工程输出项
12.png
Pinout&Configuration,选择功能(若是选GPIO相关,可以直接在Pinout view选择;若是其他功能,可以在左边Categories打开,会自动配置引脚)、设置Parameter Settings/NVIC等
13.png
GENERATE CODE,生成工程,用KEIL打开编辑
HAL库函数
函数形式:均以HAL_开头

寻找过程:在驱动文件stm32f4xx_hal_XXX.c或其.h文件中找函数定义,一般在靠后位置
其他说明:
HAL库并没有把所有的操作都封装成凼数。
对于底层的寄存器操作(如读取捕获/比较寄存器),还有修改外设的某个配置参数(如改变输入捕获的极性),HAL库会使用宏定义来实现。而且会用__HAL_作为这类宏定义的前缀。
获取某个参数,宏定义中一般会有_GET;而设置某个参数的,宏定义中就会有_SET。
在开发过程中,如果遇到寄存器级别或者更小范围的操作时,可以到该外设的头文件中查找,一般都能找到相应的宏定义。
HAL库函数第一个参数一般都是句柄(一个包含了当前对象绝大部分状态的结构体),虽然增加了开销,但是用起来便捷了非常多。
中断回调函数
函数形式:HAL_XXX_XXXCallback()。

寻找过程:中断文件stm32f4xx_it.c - > 中断函数XXX_IRQHandler(void) -> HAL库中断函数HAL_XXX_IRQHandler(GPIO_PIN_13) -> 回调函数HAL_XXX_XXXCallback()
外设对应时钟
随便进入一个外设初始化函数,如MX_GPIO_Init()

随便进入一个时钟使能函数,如__HAL_RCC_GPIOC_CLK_ENABLE()
随便进入一个RCC宏定义,如RCC_AHB1ENR_GPIOCEN
或者直接进入stm32f429xx.h文件
里面有所有外设与时钟对应关系,如RCC_AHB1ENR_DMA1EN




配置示例
小编有话说
例子源码:

https://sxf1024.lanzoui.com/b09rf535a  密码:bf5q
如果配置过程中,参数不知道怎么设置,可以去标准库例程(如野火、正点原子)中看对应的参数是什么Cube软件只是帮你配置了底层,一些初始化代码还是需要自己手动加的,如SDRAM充电初始化、读写函数等
RTC
14.png
15.png
16.png


  1. RTC_DateTypeDef sDate;
  2. RTC_TimeTypeDef sTime;
  3. uint8_t second_tmp = 0;


  4. HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN); // 读取时间
  5. HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN); // 读取日期
  6. if(second_tmp != sTime.Seconds) { // 读取秒
  7.      second_tmp = sTime.Seconds;
  8.      printf("20%d%d-%d%d-%d%d\r\n",
  9.             sDate.Year/10%10, sDate.Year%10,
  10.             sDate.Month/10%10, sDate.Month%10,
  11.             sDate.Date/10%10, sDate.Date%10);
  12.      printf("%d%d:%d%d:%d%d\r\n",
  13.             sTime.Hours/10%10, sTime.Hours%10,
  14.             sTime.Minutes/10%10, sTime.Minutes%10,
  15.             sTime.Seconds/10%10, sTime.Seconds%10);
  16. }
复制代码


SDIO + FATFS
选择SDIO功能,Pinout&Clock Configuration,Connectivity -> SDIO -> Mode: SD 4bit Wide bus -> 勾选NVIC

17.png
配置SDIO时钟,Clock Configuration,SDIO模块输入要求为48MHz,系统提示可以自动设置时钟问题,选择Yes。SDIO时钟分频系数CLKDIV,计算公式为SDIO_CK=48MHz/(CLKDIV+2)也可手动修改时钟配置。
18.png
启用文件系统中间件,Pinout&Clock Configuration,Middleware -> FATFS,模式选择SD卡,配置文件系统:
如果要支持中文文件名,则配置CODE_PAGE为Simplified Chinese
如果要支持长文件名,则要使能USE_LEN
19.png
继续上面界面,Advanced Settings勾选Use dma template
20.png
设置DMA传输,Pinout&Clock Configuration,Connectivity -> SDIO-> DMA Settings
21.png
配置NVIC,Pinout&Clock Configuration,System Core -> NVIC。
注意,SDIO中断优先级必须高于DMA2 stream3和DMA2 stream6的中断优先级
22.png
堆栈设置,Progect Manager -> Project -> Linker Settings,加大堆栈大小(注意:由于刚才设置长文件名动态缓存存储在堆中,故需要增大堆大小,如果不修改则程序运行时堆会生成溢出,程序进入硬件错误中断(HardFault),死循环)。
23.png
生成工程,GENERATE CODE ,用KEIL打开
24.png
  1. UINT bw;
  2. retSD = f_mount(&SDFatFS, SDPath, 0);
  3. if(retSD != FR_OK) {
  4.      printf("Mount Error :%d\r\n", retSD);
  5. }
  6. retSD = f_open(&SDFile, "0:/test.txt", FA_CREATE_ALWAYS | FA_WRITE);
  7. if(retSD != FR_OK){
  8.      printf("Open Error :%d\r\n", retSD);
  9. }
  10. retSD = f_write(&SDFile, "abcde", 5, &bw);
  11. if(retSD != FR_OK){
  12.      printf("Write Error :%d\r\n", retSD);
  13. }
  14. f_close(&SDFile);
  15. retSD = f_open(&SDFile, "0:/test.txt", FA_READ);
  16. char buff[10] = {0};
  17. retSD = f_read(&SDFile, buff, 5, &bw);
  18. if(retSD == FR_OK){
  19.      printf("%s\r\n", buff);
  20. }
  21. f_close(&SDFile);
复制代码


DRAM
开启FMC功能,Pinout&Configuration ,Connectivity -> FMC -> SDRAM2

SDRAM1的起始地址为0XC0000000,SDRAM2的起始地址为0XD0000000。
一般SDRAM都含有4个bank。
Configuration中的参数可从SDRAM的数据手册上找到。


各个选项的配置(只做解释,不对应上图):
Clock and chip enable:FMC_SDCKE0 和FMC_SDCLK0对应的存储区域1 的地址范围是0xC000 0000-0xCFFF FFFF;而FMC_SDCKE1 和FMC_SDCLK1 对应的存储区域2 的地址范围是0xD000 0000- 0xDFFF FFFF
Bank由硬件连接决定需要选择SDRAM bank 2
Column bit number表示列数,8位
Row bit number表示行数,12位
CAS latency表示CAS潜伏期,即上面说的CL,该配置需要与之后的SDRAM模式寄存器的配置相同,这里先配置为2 memory clock cycles(对于SDRAM时钟超过133MHz的,则需要配置为3 memory clock cycles)
Write protection 表示写保护,一般配置为Disabled
SDRAM common clock为SDRAM 时钟配置,可选HCLK的2分频\3分频\不使能SDCLK时钟。前面主频配置为216MHz,SDRAM common clock设置为2分频,那SDCLK时钟为108MHz,每个时钟周期为9.25ns
SDRAM common burst read 表示突发读,这里选择使能
SDRAM common read pipe delay 表示CAS潜伏期后延迟多少个时钟在进行读数据,这里选择0 HCLK clock cycle
Load mode register to active delay 加载模式寄存器命令和激活或刷新命令之间的延迟,按存储器时钟周期计


Exit self-refresh delay从发出自刷新命令到发出激活命令之间的延迟,按存储器时钟周期数计查数据手册知道其最小值为70ns,由于我们每个时钟周期为9.25ns,所以设为8 (70÷9.25,向上取整)


SDRAM common row cycle delay刷新命令和激活命令之间的延迟,以及两个相邻刷新命令之间的延迟, 以存储器时钟周期数表示
查数据手册知道其最小值为63ns,由于我们每个时钟周期为9.25ns,所以设为7 (63÷9.25,向上取整)


Write recovery time写命令和预充电命令之间的延迟,按存储器时钟周期数计


SDRAM common row precharge delay预充电命令与其它命令之间的延迟,按存储器时钟周期数计
查数据手册知道其最小值为15ns,由于我们每个时钟周期为9.25ns,所以设为2 (15÷9.25,向上取整)


Row to column delay激活命令与读/写命令之间的延迟,按存储器时钟周期数计
查数据手册知道其最小值为15ns,由于我们每个时钟周期为9.25ns,所以这里本应该设为2 (15÷9.25,向上取整)
但要注意,时序必须满足以下式子:
TWR ≥ TRAS - TRCD
TWR ≥ TRC - TRCD - TRP
其中:TWR = Write recovery time = 2
TRAS = Self refresh time = 5
TRC = SDRAM common row cycle delay = 7
TRP = SDRAM common row precharge delay = 2
TRCD = Row to column delay
所以这里Row to column delay应该取3


生成代码,GENERATE CODE, 用KEIL打开
  1. uint8_t temp[100]__attribute__((at(0xD0000000)));
  2. for(int i=0;i<100;i++){
  3.      temp[i] = i;
  4. }
  5. for(int i=0;i<100;i++){
  6.      printf("%d ", temp[i]);
  7. }
复制代码


到这里只是借助Cube完成了引脚配置,还需要SDRAM初始化操作和读写函数,可从官方例程里获取,路径:
C:\Users\10617\STM32Cube\Repository\STM32Cube_FW_F4_V1.25.0\Drivers\BSP\STM32F429I-Discovery\XXX


  1. /*****************************SDRAM使能函数******************************/

  2. /**
  3.    * @brief 对SDRAM芯片进行初始化配置
  4.    * @param None.
  5.    * @retval None.
  6.    */
  7. static void USER_SDRAM_ENABLE(void)
  8. {
  9. FMC_SDRAM_CommandTypeDef Command;

  10.    __IO uint32_t tmpmrd =0;
  11.    
  12.    /* Step 1: Configure a clock configuration enable command */
  13.    Command.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
  14.    Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
  15.    Command.AutoRefreshNumber = 1;
  16.    Command.ModeRegisterDefinition = 0;

  17.    /* Send the command */
  18.    HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);

  19.    /* Step 2: Insert 100 us minimum delay */
  20.    /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
  21.    HAL_Delay(1);

  22.    /* Step 3: Configure a PALL (precharge all) command */
  23.    Command.CommandMode = FMC_SDRAM_CMD_PALL;
  24.    Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
  25.    Command.AutoRefreshNumber = 1;
  26.    Command.ModeRegisterDefinition = 0;

  27.    /* Send the command */
  28.    HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
  29.    
  30.    /* Step 4: Configure an Auto Refresh command */
  31.    Command.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
  32.    Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
  33.    Command.AutoRefreshNumber = 4;
  34.    Command.ModeRegisterDefinition = 0;

  35.    /* Send the command */
  36.    HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
  37.    
  38.    /* Step 5: Program the external memory mode register */
  39.    tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_2 |
  40.                       SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
  41.                       SDRAM_MODEREG_CAS_LATENCY_3 |
  42.                       SDRAM_MODEREG_OPERATING_MODE_STANDARD |
  43.                       SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
  44.    
  45.    Command.CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
  46.    Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
  47.    Command.AutoRefreshNumber = 1;
  48.    Command.ModeRegisterDefinition = tmpmrd;

  49.    /* Send the command */
  50.    HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
  51.    
  52.    /* Step 6: Set the refresh rate counter */
  53.    /* Set the device refresh rate */
  54.    HAL_SDRAM_ProgramRefreshRate(&hsdram1, REFRESH_COUNT);
  55. }
  56. /*****************************使能函数结束******************************/
复制代码


或者以我的野火STM32F429IGT6的版本,源码链接:
https://sxf1024.lanzoui.com/b09rf535a  密码:bf5q
添加到工程Core路径下,然后在KEIL中初始化操作:
  1. #include "bsp_sdram.h"
  2. MX_FMC_Init();
  3. SDRAM_InitSequence();
复制代码










收藏 1 评论0 发布时间:2020-10-16 16:00

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版