cubemx
目录
在cubemx中如何配置GPIO、串口、ADC、DMA、SPI、FSMC、RTC
-- 三种开发方式:
- 寄存器
- 库函数(标准库)
- Hal库
-- cubemx的介绍
STM32 CubeMX 简介
CubeMX (全称 STM32CubeMX) 是 ST 公司推出的一款用于 STM32 微控制器配置的图形化工具. 它能帮助开发者通过直观的图像界面快速完成 STM32 微控制器的硬件配置, 外设初始化以及中间件设置等工作. 通过 CubeMX, 开发者可以大幅提高开发效率, 降低开发难度, 尤其是对于刚接触 STM32 的新手.
-- CubeMX 的主要功能和特点如下:
- 1 硬件配置: 通过图形化界面, 我们可以方便地配置 STM32 微控制器的引脚, 时钟树以及电源设置等, 无需手动查阅数据手册
- 2 外设初始化: 支持 STM32 系列微控制器的各种外设, 包括定时器, UART, I2C, SPI 等. 我们可以通过简单的操作, 对外设进行参数设置和功能配置
- 3 中间件设置: 内置了 ST 公司提供的各种中间件, 如 FreeRTOS, LwIP, USB Device 等. 我们可以通过 CubeMX 轻松地为项目添加所需的中间件 代码生成: 根据配置的硬件和外设参数, CubeMX 可以自动生成初始化代码, 支持不同的 IDE, 如 AIR, Keil, STM32CubeIDE 等. 生成的代码遵循 HAL 库标准, 方便开发者进行二次开发
- 4 项目管理: 可以创建, 打开和保存项目, 方便开发者对多个项目进行管理. 同时, 还指出导入已有的项目, 便于后续的项目维护和优化
-- 为什么要学hal库呢?
- 因为现在ST公司开发出来的单片机都只提供hal库,不再提供标准库的内容了。
cubemx的安装
-- 安装CubeMx一共需要三个
- JRE (Java Runtime Environment) Java运行环境 运行JAVA程序所必须的环境的集合
- STM32CubeMX
- HAL库 STM32 HAL固件库 ST官方推出的另一套库
-- 1、安装JRE
-
由于 STM32CubeMX 软件是基于 JAVA 环境运行的,所以需要安装 JRE (Java Runtime Environment)才能使用,
-
百度云:百度网盘-链接不存在 提取码: e8gs (定时更新最新版本)
-
点击安装
-- 2、等待安装完成,关闭界面
-- 3、安装STM32CubeMX
-
官网:www.st.com/stm32cubemx
-
百度云:百度网盘 请输入提取码 提取码: wjmd
-
官网下载:
在官网下载需要注册下ST官网账号,目前最新为5.3.0版本,不想在官网下可以在百度云盘下载,
-- 4、打开安装包
-- 5、同意协议,下一步
-- 6、勾选第一个即可,第二个选项是-是否同意ST公司收集你的个人使用信息等
-- 7、点YES 这句话是安装本软件可能会与文件夹之前文件冲突,导致文件夹之前文件丢失 是否继续 (注意 安装路径最好不要选择中文)
点继续即可
-- 7、直接点NEXT,其他不用设置 之后开始安装
-- 8、安装完成,点Done退出
-- 9、安装HAL库
- 什么是HAL固件库?
STM32 HAL固件库是Hardware Abstraction Layer的缩写,中文名称是:硬件抽象层。HAL库是ST公司为STM32的MCU最新推出的抽象层嵌入式软件,为更方便的实现跨STM32产品的最大可移植性。HAL库的推出,可以说ST也慢慢的抛弃了原来的标准固件库,这也使得很多老用户不满。但是HAL库推出的同时,也加入了很多第三方的中间件,有RTOS,USB,TCP / IP和图形等等。
和标准库对比起来,STM32的HAL库更加的抽象,ST最终的目的是要实现在STM32系列MCU之间无缝移植,甚至在其他MCU也能实现快速移植。
并且从16年开始,ST公司就逐渐停止了对标准固件库的更新,转而倾向于HAL固件库和 Low-layer底层库的更新,停止标准库更新,也就表示了以后使用STM32CubeMX配置HAL/LL库是主流配置环境;
HAL库,有在线安装、离线安装两种方式
-- 在线安装
- 打开安装好的 STM32CubeMX 软件 点上面的Help -> Manage embedded software packages
- 会跳出来一个选择型号界面 勾选上你要安装的HAL库, 点击“Install Now” 直到安装成功。 如下图:
-- 离线安装
- 离线安装需要下载安装包,这里提供百度云和ST官方下载方式 PS:建议在线安装 速度快,又稳定
官网:www.st.com/stm32cubemx
-- 软件下载旁边一栏就是HAL库下载 下载对应芯片的安装包
- 百度云:百度网盘 请输入提取码 提取码: wjmd
-- 1、直接导入安装包 Help -> Manage embedded software packages ->From Local 选择离线包即可
-- 2、直接解压 Help->Updater Settings... 可以选择HAL库安装包路径 ,默认在C盘 可以自行修改
-- 解压到相对应路径即可
cubemx的使用
-- 1、点击第一个创建新工程
- 可能会出现更新,等待更新结束即可
-- 2、输入工程所用的芯片
-
选择ZET6,点击“Start Project”即可,也可以双击
-
配置
-- 3、首先配置时钟
- 都选择最后一个
-- 4、了解不同颜色代表着什么
-- 5、配置时钟源
-- 6、配置系统主时钟(这是单片机的时钟分配图,最好能记一下)
-- 7、生成工程
-- 8、更改代码选项
-- 9、最后点击“GENERATE CODE”即可生成代码,如果前面已经打开过工程了,就不再次打开。回到已经打开过的工程会出现是否更新工程的弹窗,点击是即可。
-- 10、如果不小心关闭了cubemx,要从哪里打开呢?
- 找到生成的工程所在位置
打开cubemx文件即可
在cubemx中如何配置GPIO、串口、ADC、DMA、SPI、FSMC、RTC
GPIO
-- 注意:生成的代码下载过后,必须点击复位,效果才能显示出来
-- 首先我们知道,一个引脚只有四种模式,输入输出模拟复用
-- 1、左键点击右边引脚,会让选择模式。
-- 2、先配置LED灯的引脚,全部配置成输出
-- 3、点击右边的GPIO,进行配置,将刚刚四个输出引脚进行配置
-- 4、配置之后点击生成,因为之前已经打开过工程了,直接叉掉即可,然后返回工程,点击更新
-- 5、注意:在hal库中不能用标准库的代码,但是寄存器的代码可以使用
-- 6、看生成的代码
-- 7、注意:编写代码,一定要写在BEGIN和GND之间(END和BEGIN之间都不行,一定是BEGIN先然后END在后面),否则代码会丢失
串口
-- 1、配置串口
-- 2、打开串口的中断(注意这里要额外打开)
-- 3、要想修改中断的优先级
-- 4、然后生成工程,编译,之后再开始配置
-- 5、编写代码,实现printf的操作
/* USER CODE BEGIN 1 */
#include "stdio.h"
int fputc(int ch,FILE *f)
{
HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,0xFFFF);
//HAL_UART_Receive();
return ch;
}
/* USER CODE END 1 */
- 注意:hal库有一个超时机制存在
-- 6、注意:
- 每次使用cumx重新生成代码,都要看一下这里,要选中
-- 7、在main.c中添加头文件,并在main函数中编写代码
-- 8、我们发现在中断初始化中,没有开启中断源
-- 9、我们发现hal库的函数很少,想要开中断,却找不到那个函数,怎么找呢?
- 打开串口使能函数
- 这个函数如果不会用,就可以直接百度了。
-- 10、在usart.c中开接收中断和空闲中断
/* USER CODE BEGIN USART1_Init 2 */
//开中断
__HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE);
__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);//空闲
/* USER CODE END USART1_Init 2 */
-- 11、接下来写应用,找中断服务函数,注意所有的中断服务函数都stm32f4xx_it.c中
-- 12、hal库除了用了超时机制,还用了大量的回调函数,这里我们需要在回调函数中写代码
-- 13、这里应该直接改回调函数的,但比较麻烦,所以这里我们直接写在中断服务函数中,检测中断是否被触发
- 注意:空闲中断有专门的清理函数
/* USER CODE BEGIN USART1_IRQn 0 */
if(__HAL_UART_GET_FLAG(&huart1,UART_IT_RXNE) == SET)
{
__HAL_UART_CLEAR_FLAG(&huart1,UART_IT_RXNE);
}
if(__HAL_UART_GET_FLAG(&huart1,UART_IT_IDLE) == SET)
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1);//注意:空闲中断有专门的清理函数
}
/* USER CODE END USART1_IRQn 0 */
ADC
-- 1、ADC模式
-- 2、选择两个通道
-- 3、配置ADC
-- 4、ADC和DMA一起用,配置DMA
-- 5、配置完后会发现时钟有个错误,因为之前配置时钟的时候没有考虑到ADC的时钟,因为adc时钟不能超过14HZ,所以这里需要重新配置时钟。
-- 6、重新填写72HZ,回车,就可以重新配置了。
-- 7、之后点击生成,编译,然后开始编写代码
-- 8、首先定义字符串用来存取数据
-- 9、那么怎么做才能将数据写入buff呢?
/* USER CODE BEGIN ADC1_Init 2 */
HAL_ADC_Start_DMA(&hadc1,(uint32_t *)adcmabuff, 20);
/* USER CODE END ADC1_Init 2 */
-- 可以通过调试,将adcmabuff变量放入窗口中,然后点击右键,选择“watch”即可看到数据,有数据代表正确。
SPI
-- 结合flash
-- 1、更改SPI模式
-- 2、选完之后看一下引脚是否对应
-- 3、配置spi
-- 4、还差一个cs片选信号,PB12,因为是片选信号,所以默认输出高电平
-- 5、生成,编译
-- 6、怎么验证SPI生成的正确呢?将我们之前工程写的函数移植到我们的当前工程
-
src放.c文件
-
inc放.h文件
-- 7、编译之后,会有很多错误,这是因为在hal库不能写有关标准库的内容。要将标准库改为hal库
- 先把涉及到标准库的代码屏蔽掉(报错的地方要屏蔽掉)
-- 8、更改头文件
#include "stm32f1xx_hal.h"
-- 9、更改宏定义
#define sFLASH_CS_LOW() HAL_GPIO_WritePin(sFLASH_CS_GPIO_PORT, sFLASH_CS_PIN,GPIO_PIN_RESET)
/**
* @brief Deselect sFLASH: Chip Select pin high
*/
#define sFLASH_CS_HIGH() HAL_GPIO_WritePin(sFLASH_CS_GPIO_PORT, sFLASH_CS_PIN,GPIO_PIN_SET)
-- 10、更改FLASH发送数据函数
#include "spi.h"
uint8_t sFLASH_SendByte(uint8_t byte)
{
uint8_t data = 0;
HAL_SPI_TransmitReceive(&hspi2,&byte,&data,1,100);
return data;
}
-- 11、在main函数中测试函数
/* USER CODE BEGIN 2 */
printf("你好:%x\r\n",sFLASH_ReadID());
/* USER CODE END 2 */
FSMC(用于屏幕)
-- 1、配置FSMC
-- 2、配置完后生成,编译,测试,将修改好的LCD.c和.h复制到工程中
- 因为还要用delay.h和fonts.h,所以也要复制
-- 3、需要改底层的初始化和IO,外设的初始化
-- 4、找到LCD的初始化函数
-- 5、在main函数中调用
- 记得加上头文件
#include "bsp_lcd.h"
-- 编译运行,我们可以明显的看出屏幕显示的比较慢,所以我们更改参数。
-- hal库运行速度比较慢,所以这些参数可以使用标准库里面的
-- 这些参数改完,我们就可以看到屏幕显示的比较快了。
RTC
-- 1、配置RTC
-- 2、如果想要打开中断,可以打开
-- 3、写代码
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
RTC_DateTypeDef GetData; //获取日期结构体
RTC_TimeTypeDef GetTime; //获取时间结构体
/* USER CODE END PTD */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_RTC_GetTime(&hrtc, &GetTime, RTC_FORMAT_BIN);
/* Get the RTC current Date */
HAL_RTC_GetDate(&hrtc, &GetData, RTC_FORMAT_BIN);
/* Display date Format : yy/mm/dd */
printf("%02d/%02d/%02d\r\n",2000 + GetData.Year, GetData.Month, GetData.Date);
/* Display time Format : hh:mm:ss */
printf("%02d:%02d:%02d\r\n",GetTime.Hours, GetTime.Minutes, GetTime.Seconds);
printf("\r\n");
HAL_Delay(1000);
LED1(1);
HAL_Delay(1000);//hal库自带延时ms
LED1(0);
HAL_Delay(1000);//hal库自带延时ms
}
-- 效果图
FREERTOS
-- 1、配置FreeRTOS
-- 2、创建任务
-- 3、加入工程中
-- 4、编写代码
- 在任务中写要执行的代码。
void StartTask03(void const * argument)
{
/* USER CODE BEGIN StartTask03 */
/* Infinite loop */
for(;;)
{
LED1(1);
HAL_Delay(1000);
LED1(0);
osDelay(1000);
}
/* USER CODE END StartTask03 */
}
void StartTask02(void const * argument)
{
/* USER CODE BEGIN StartTask02 */
/* Infinite loop */
for(;;)
{
/* Get the RTC current Time */
HAL_RTC_GetTime(&hrtc, &GetTime, RTC_FORMAT_BIN);
/* Get the RTC current Date */
HAL_RTC_GetDate(&hrtc, &GetData, RTC_FORMAT_BIN);
/* Display date Format : yy/mm/dd */
printf("%02d/%02d/%02d\r\n",2000 + GetData.Year, GetData.Month, GetData.Date);
/* Display time Format : hh:mm:ss */
printf("%02d:%02d:%02d\r\n",GetTime.Hours, GetTime.Minutes, GetTime.Seconds);
printf("\r\n");
HAL_Delay(1000);
osDelay(1);
}
/* USER CODE END StartTask02 */
}