vs如何自动生成基本的代码_STM32CubeMX底层配置代码自动代码生成
STM32CubeMX + HAL 一些说明 底层配置 Cube基本使用 HAL库函数 中断回调函数 外设对应时钟 配置示例 小编有话说 RTC SDIO + FATFS SDRAM LTDC + DMA2D
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,配置时钟树
Project Manager,配置工程输出项
Pinout&Configuration,选择功能(若是选
GPIO
相关,可以直接在Pinout view选择;若是其他功能,可以在左边Categories打开,会自动配置引脚)、设置Parameter Settings/NVIC
等
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
RTC_DateTypeDef sDate; RTC_TimeTypeDef sTime; uint8_t second_tmp = 0;
HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN); // 读取时间 HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN); // 读取日期 if(second_tmp != sTime.Seconds) { // 读取秒 second_tmp = sTime.Seconds; printf("20%d%d-%d%d-%d%d\r\n", sDate.Year/10%10, sDate.Year%10, sDate.Month/10%10, sDate.Month%10, sDate.Date/10%10, sDate.Date%10); printf("%d%d:%d%d:%d%d\r\n", sTime.Hours/10%10, sTime.Hours%10, sTime.Minutes/10%10, sTime.Minutes%10, sTime.Seconds/10%10, sTime.Seconds%10); }
SDIO + FATFS
选择SDIO功能,Pinout&Clock Configuration,
Connectivity -> SDIO -> Mode: SD 4bit Wide bus -> 勾选NVIC
配置SDIO时钟,Clock Configuration,SDIO模块输入要求为48MHz,系统提示可以自动设置时钟问题,选择
Yes
。SDIO时钟分频系数CLKDIV
,计算公式为SDIO_CK=48MHz/(CLKDIV+2)
也可手动修改时钟配置。
启用文件系统中间件,Pinout&Clock Configuration,
Middleware -> FATFS
,模式选择SD卡,配置文件系统:如果要支持中文文件名,则配置
CODE_PAGE
为Simplified Chinese
如果要支持长文件名,则要使能
USE_LEN
继续上面界面,Advanced Settings勾选
Use dma template
设置DMA传输,Pinout&Clock Configuration,
Connectivity -> SDIO-> DMA Settings
配置NVIC,Pinout&Clock Configuration,
System Core -> NVIC
。
注意,SDIO中断优先级必须高于DMA2 stream3和DMA2 stream6的中断优先级
堆栈设置,Progect Manager -> Project -> Linker Settings,加大堆栈大小(注意:由于刚才设置长文件名动态缓存存储在堆中,故需要增大堆大小,如果不修改则程序运行时堆会生成溢出,程序进入硬件错误中断(HardFault),死循环)。
生成工程,GENERATE CODE ,用KEIL打开
UINT bw; retSD = f_mount(&SDFatFS, SDPath, 0); if(retSD != FR_OK) { printf("Mount Error :%d\r\n", retSD); } retSD = f_open(&SDFile, "0:/test.txt", FA_CREATE_ALWAYS | FA_WRITE); if(retSD != FR_OK){ printf("Open Error :%d\r\n", retSD); } retSD = f_write(&SDFile, "abcde", 5, &bw); if(retSD != FR_OK){ printf("Write Error :%d\r\n", retSD); } f_close(&SDFile); retSD = f_open(&SDFile, "0:/test.txt", FA_READ); char buff[10] = {0}; retSD = f_read(&SDFile, buff, 5, &bw); if(retSD == FR_OK){ printf("%s\r\n", buff); } f_close(&SDFile);
SDRAM
开启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 FFFFBank
由硬件连接决定需要选择SDRAM bank 2Column bit number
表示列数,8位Row bit number
表示行数,12位CAS latency
表示CAS潜伏期,即上面说的CL,该配置需要与之后的SDRAM模式寄存器的配置相同,这里先配置为2 memory clock cycles(对于SDRAM时钟超过133MHz的,则需要配置为3 memory clock cycles)Write protection
表示写保护,一般配置为DisabledSDRAM common clock
为SDRAM 时钟配置,可选HCLK的2分频\3分频\不使能SDCLK时钟。前面主频配置为216MHz,SDRAM common clock设置为2分频,那SDCLK时钟为108MHz,每个时钟周期为9.25nsSDRAM common burst read
表示突发读,这里选择使能SDRAM common read pipe delay
表示CAS潜伏期后延迟多少个时钟在进行读数据,这里选择0 HCLK clock cycleLoad 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打开
uint8_t temp[100]__attribute__((at(0xD0000000))); for(int i=0;i<100;i++){ temp[i] = i; } for(int i=0;i<100;i++){ printf("%d ", temp[i]); }
到这里只是借助Cube完成了引脚配置,还需要SDRAM初始化操作和读写函数,可从官方例程里获取,路径:
C:\Users\10617\STM32Cube\Repository\STM32Cube_FW_F4_V1.25.0\Drivers\BSP\STM32F429I-Discovery\XXX
/*****************************SDRAM使能函数******************************/
/** * @brief 对SDRAM芯片进行初始化配置 * @param None. * @retval None. */ static void USER_SDRAM_ENABLE(void) { FMC_SDRAM_CommandTypeDef Command;
__IO uint32_t tmpmrd =0;
/* Step 1: Configure a clock configuration enable command */ Command.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE; Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2; Command.AutoRefreshNumber = 1; Command.ModeRegisterDefinition = 0;
/* Send the command */ HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
/* Step 2: Insert 100 us minimum delay */ /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */ HAL_Delay(1);
/* Step 3: Configure a PALL (precharge all) command */ Command.CommandMode = FMC_SDRAM_CMD_PALL; Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2; Command.AutoRefreshNumber = 1; Command.ModeRegisterDefinition = 0;
/* Send the command */ HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
/* Step 4: Configure an Auto Refresh command */ Command.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE; Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2; Command.AutoRefreshNumber = 4; Command.ModeRegisterDefinition = 0;
/* Send the command */ HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
/* Step 5: Program the external memory mode register */ tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_2 | SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL | SDRAM_MODEREG_CAS_LATENCY_3 | SDRAM_MODEREG_OPERATING_MODE_STANDARD | SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
Command.CommandMode = FMC_SDRAM_CMD_LOAD_MODE; Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2; Command.AutoRefreshNumber = 1; Command.ModeRegisterDefinition = tmpmrd;
/* Send the command */ HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
/* Step 6: Set the refresh rate counter */ /* Set the device refresh rate */ HAL_SDRAM_ProgramRefreshRate(&hsdram1, REFRESH_COUNT); } /*****************************使能函数结束******************************/
或者以我的野火STM32F429IGT6的版本,源码链接:
https://sxf1024.lanzoui.com/b09rf535a 密码:bf5q
添加到工程Core
路径下,然后在KEIL中初始化操作:
#include "bsp_sdram.h"MX_FMC_Init();SDRAM_InitSequence();
LTDC + DMA2D
教程看这个:https://zzttzz.gitee.io/blog/posts/7109b92c
源码人家也给了,只不过需要改改才能运行成功...
累了,不细讲了,调了好多天都没成功...
待补充...
vs如何自动生成基本的代码_STM32CubeMX底层配置代码自动代码生成相关推荐
- idea自动生成get set_CTO:不要在Java代码中写set/get方法了,逮一次罚款
前言 what?你的 Java 代码中还充斥着大量的 set/get 方法? 我们在刚开始学习 Java 语言的时候讲过,面向对象的三大特征就是封装,继承,和多态.在 Java 中,要保证封装性,需要 ...
- 在SAP API hub自动生成使用ABAP调用API的胶水代码
登录api.sap.com, 找到自己想用ABAP调用的API: API References里,点击Code Snippt, 即可看到API Hub自动生成的使用ABAP调用该API的代码: 要获取 ...
- c 自动生成mysql表结构_EntityFrameworkCore 根据实体类自动创建数据库
1.首先新建 Asp.Net Core WebApi 项目 2.添加一下引用 : 2.1 Pomelo.EntityFrameworkCore.MySql(我用的Mysql 根据自己情况引用就行) ...
- mybatis-generator自动生成dao、mapping、bean配置详解(转)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration ...
- linux系统中自动生成snap文件_在Linux操作系统下自动生成Makefile的方法
在Linux操作系统下进行开发,编写Makefile似乎是不可缺少的事情.但是对于一个比较大的工程,编写一个符合规范的Makefile并非易事.而且由于Makefile的各种显式,隐式规则,加之平时并 ...
- 自动生成PDF文件(Java通过PDF模板自动生成PDF)
思路: 1.创建PDF模板(先创建对应的excel文件,创建好后另存为PDF文件)即可. 2.使用Adobe Acrobat DC工具打开PDF文件,设置自己想要替换的内容. 3.maven项目引入依 ...
- [易飞]自动生成分录底稿和凭证:无法自动生成凭证号码底稿手工执行补充空号与系统规则冲突
无法自动生成凭证号码&底稿手工执行补充空号与系统规则冲突 常见抛转失败原因 问题 按正常解决思路检查设置 可能存在的原因 常见抛转失败原因 单据分录性质是否已设置 所设置的客户是否都是末级别客 ...
- 网易见外不能用?自动生成字幕,免费快速上字幕, 自动加字幕!自动加字幕!视频字幕自动生成 语音转换字幕 极速上字幕
字幕酱是一款在线免费语音转字幕软件线上工具. 体验地址: https://www.zimujiang.com/ 主要功能 1.支持常见 flac,opus,mp3,m4a,wav,mp4 格式音视频自 ...
- html相框自动生成功能,网页制作HTML5拖放API实现自动生成相框功能
实现功能: 将桌面图片拖入指定地方,生成相框和相关信息. 相框需要自己配置,设置为背景,在CSS中设置. 效果如图: html部分: H5拖放API之图片相框效果 > 请将图片拖放至此处 CSS ...
最新文章
- 关于USART接收中断的BUG和注意事项
- Picasso-源码解析(二)
- golang模板语法
- 正则表达式 RegularExpressions
- unity和python通讯_Python 与 Unity mlagents 交互 API
- 大数据工程师技能图谱
- controller层个人信息查询模块_风险控制平台架构+模块
- 什么是https安全证书
- STM32F103基于HAL库移植uC/OS-III
- 牛客网刷题记录——数理统计(累积记录)
- Eclipse的JVM语言Xtend达到2.3 M7
- IOS APP程序发布IPA以及发布上传到AppStore
- BUAA OJ 722 Gzh之表达式求值
- mysql 原子操作
- 26万人的巨复杂考勤自动核算,比亚迪搞定了!
- 计算机教师个人业绩成果自述,个人评价自述
- LM小型可编程控制器软件(基于CoDeSys)笔记四:如何用rs232下载plc程序
- 用Qt实现计算器(实现了运算符优先级)
- php 摇骰子,php实现的中秋博饼游戏之掷骰子并输出结果功能详解
- 二阶线性偏微分方程的分类和标准式 | 椭圆型、抛物线形、双曲线型 | 偏微分方程(十一)