最近在做一款机器人的开发,使用到了STM32CubeIDE,这里记录一些使用技巧方便后续查阅。
STM32CubeIDE使用过程记录
- 快捷键
- 开启代码自动补全功能
- 看门狗设置
- CRC设置
- IO口取反
- 定时器设置 及 定时器中断
- 外部中断
- GPIO配置
- STC15单片机GPIO模式配置
- 片内闪存(Flash)的读写操作
快捷键
界面字体放大:“ctrl” + “shift” + “+”
界面字体缩小:“ctrl” + “-”
注释代码:“ctrl” + “/”
补全代码:“alt” + “/”
右缩进:“tab”
左缩进: “shift” + “tab”
开启代码自动补全功能
首先,打开程序Window菜单下Preferences选项
在 C/C++ --> Editor --> Content Assist --> Advanced 设置里勾选上下两部分的 Parsing-based Proposals
然后,我们需要设置相应的快捷键。在 General --> Keys 下面搜索content assist, 设置C/C++ Content Assist (Parsing-based Proposals)的Binding快捷键为你所想设置的,在这里笔者设置成了content Alt+Z,,When 设置成 C/C++ Editor。设置到这里便完成了。
看门狗设置
看门狗的时钟:
时间设置:
设定时间=(prescale/看门狗的时钟(KHZ))*reload value
喂狗:
HAL_IWDG_Refresh(&hiwdg);//喂看门狗
CRC设置
设置界面:
uint32_t crcBuf[1];
uint32_t crcValue=0;
uint8_t *crcValueList;
crcBuf[0] = (uint32_t)aRxBuffer2[0];
crcValue = HAL_CRC_Calculate(&hcrc, crcBuf, sizeof(crcBuf)/sizeof(crcBuf[0])); //计算CRC校验
crcValueList = (uint8_t*)&crcValue;
IO口取反
HAL_GPIO_TogglePin(GPIOC, LED_test_Pin); //toggle the pin
定时器设置 及 定时器中断
定时器分类
- 基本定时器(TIM6~TIM7)
功能:作为时基,定时功能。 - 通用定时器(TIM2~TIM5)
功能:具有多路独立通道,输入捕获,输出比较,也可作为时基。 - 高级定时器(TIM1和TIM8)
功能:除具备通用定时器所有功能外,还具备带死区控制的互补信号输出、刹车输入等功能 (可用于电机控制、数字电源设计等)。
定时器时钟设置
-
选择定时器时钟来源(内部时钟)
Clock Source(时钟来源) -
定时器设置
Prtscaler (定时器预分频系数):72-1
Counter Mode(计数模式) : Up(向上计数模式)
Counter Period(自动重装载值) : 5000-1
CKD(时钟分频因子) : No Division 不分频 (可以选择二分频和四分频 )
auto-reload-preload(自动重装载) : Enable 使能 -
计数器周期计算公式
T = (psc+1)(arr+1)/Tclk
psc:定时器预分频系数
arr:自动重装载值
Tclk:系统时钟频率 -
计算举例
1/[72/(71+1)]*(4999+1)=5ms
打开定时器1计数溢出中断
首先要开启定时器中断:
HAL_TIM_Base_Start_IT(&htim6);
编写中断回调函数:
/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM6)
{
HAL_GPIO_TogglePin(GPIOC, LED_test_Pin); //toggle the pin
}
}
/* USER CODE END 4 */
外部中断
端口功能配置如下:
1、模式配置为上升沿、下降沿和双边沿触发模式。
2、更据硬件原理图来设置输出上拉或下拉。
3、User Label建议定义一个自己喜欢见名知意的名字,方便写程序时查看和方便使用。
模式配置说明如下:
优先级分为:抢占优先级,子优先级。都是 值越小,优先级越大。即 为0 时,优先级最大。
配置完EXTI了之后,就可以进行配置NVIC了,主要设置中断使能、中断分组、中断优先级等信息。如下图所示:
下面就是GPIO的中断回调函数,别的中断回调函数函数名不一样,此函数入口参数是引脚号,PA1就是GPIO_PIN_1
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == GPIO_PIN_1)
{
//执行的代码
}
}
GPIO配置
1.配置GPIO的输出电平
2.GPIO的输出模式
3.是否有上拉电阻
4.输出速率
5.用户标签
-
GPIO的输出电平
低(Low)
高(High) -
GPIO的输出模式
开漏输出 (Output Open Drain)
推挽输出 (Output Push Pull) -
是否有上拉电阻
浮空输入 (No pull-up and no pull-down)
上拉输入 (Pull-up)
下拉输入 (Pull-down) -
输出速率
低(Low)
中(Medium)
高(High) -
用户标签
用户自定义,以便于阅读
推挽 开漏 高阻 这都是谁想出来的词??
STC15单片机GPIO模式配置
配置PXM0
和PXM1
寄存器即可:
片内闪存(Flash)的读写操作
因为STM32的内部FLASH大小不一,不同的大小划分是不一样的,但是大同小异这里是以STM32F103C8T6为例进行说明。
1 字节 = 8 位(bit)
1 千字节(KB)= 1024 字节
1 兆字节(MB)= 1024 千字节(KB)
STM32F103C8T6的内部Flash容量为64KB,即64 * 1024字节,属于小容量产品。
扇区划分
内部Flash存储器被划分为多个扇区,每个扇区的大小为2KB或4KB,具体划分取决于具体的芯片型号。
Flash大小为 64KB,
地址范围:0x08000000-0x08010000-1,单个扇区大小:1KB=0x400,最后一个扇区地址:0x0800FC00Flash大小为
128KB,地址范围:0x08000000-0x08020000-1,单个扇区大小:1KB=0x400,最后一个扇区地址:0x0801FC00Flash大小为
256KB,地址范围:0x08000000-0x08040000-1,单个扇区大小:2KB=0x800,最后一个扇区地址:0x0803F800Flash大小为
512KB,地址范围:0x08000000-0x08080000-1,单个扇区大小:2KB=0x800,最后一个扇区地址:0x0807F800
HAL库提供的代码
HAL_FLASH_Unlock(void); //解锁函数
HAL_FLASH_Lock(void); //锁定函数
HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data); //写操作函数
HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError); //擦除函数
HAL_FLASH_WaitForLastOperation(uint32_t Timeout); //等待操作完成函数
Flash.c文件
/*
* Flash.c
*
* Created on: Apr 13, 2024
* Author: 猪猪侠
*/
#include "main.h"
#include "Flash.h"
#include "stdio.h"
/*FLASH写入程序*/
void FlashWrite(uint32_t Address, uint16_t *Data, uint8_t Length)
{
uint8_t i=0;
/* 1/4解锁FLASH*/
HAL_FLASH_Unlock();
/* 2/4擦除FLASH*/
/*初始化FLASH_EraseInitTypeDef*/
/*擦除方式页擦除FLASH_TYPEERASE_PAGES,块擦除FLASH_TYPEERASE_MASSERASE*/
/*擦除页数*/
/*擦除地址*/
FLASH_EraseInitTypeDef FlashSet;
FlashSet.TypeErase = FLASH_TYPEERASE_PAGES;
FlashSet.PageAddress = Address;
FlashSet.NbPages = 1;
/*设置PageError,调用擦除函数*/
uint32_t PageError = 0;
HAL_FLASHEx_Erase(&FlashSet, &PageError);
/* 3/4对FLASH烧写*/
for(i=0; i<Length; i++)
{
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, Address+2*i, Data[i]); //以半个字节的大小存储
}
/* 4/4锁住FLASH*/
HAL_FLASH_Lock();
}
void FlashRead(uint32_t Address, uint8_t *Data, uint8_t Length)
{
uint8_t i;
for (i=0; i<Length; i++)
{
Data[i] = *(__IO uint8_t *)(Address + i); // 以字节bit为单位读取Flash
}
}
Flash.h文件
/*
* Flash.h
*
* Created on: Apr 13, 2024
* Author: 猪猪侠
*/
#ifndef INC_FLASH_H_
#define INC_FLASH_H_
#define FLASH_SAVE_ADDR (0x0800FC00) //将数据存储在最后一个扇区
void FlashWrite(uint32_t Address, uint16_t *Data, uint8_t Length);
void FlashRead(uint32_t Address, uint8_t *Data, uint8_t Length);
#endif /* INC_FLASH_H_ */