STM32HAL库总结与Cubemx配置——蓝桥杯嵌入式速成指南
复习一周进国赛,只讲具体配置方法,原理网上找。
用到最新版的STM32G431,一口气配置完(熟练的话全部配置亲测40分钟搞定)。
把省赛所有基础配置过一遍,内容很多,都是干货,觉得有用记得点赞收藏。
包括时钟配置、中断配置;
外设中常用的GPIO(KEY,LED)、ADC、UART、LCD、I2C、TIM(pwm,cap)、RTC
1.Cubemx配置
1.1 选择芯片
1.2 时钟配置
1.3 GPIO
根据官方的原理图
配置led的GIPO PC8-PC15+PD2(别把这个忘了)
和key的GPIO PB0-PB2 PA0
GPIO配置默认状态就好
1.4 ADC
板上电阻R37和R38连接到PB15和PB12
配置如下 两个ADC同样配置方法,以ADC1为例
选择ADC时钟
1.5 UART 串口通信
配置接受中断
1.6 TIM
1.6.1 输入捕获cap
选择TIM2(PA15)作为输入捕获 可以捕捉信号发生器555的信号
中断
1.6.2 PWM
选择TIM17(PA7)作为PWM发生器,可以产生PWM信号
1.7 RTC时钟
1.8 创建文件
2 基础文件和功能配置
说明:模板创建后保留一份,后期如果修改Cubemx配置在备份的文件里修改,否则后面写的代码会被覆盖掉!!!!
2.1 添加启动文件
1.在官方给的任意项目里找到启动文件复制添加到自己项目中的MDK-ARM文件夹中
2. 打开Keil5,添加到项目文件夹中
3.编译通过
2.2 烧录到单片机中
记得板子得插上
烧录完成
3 代码编写
3.1 LED和KEY
在inc文件夹里创建头文件
在 src文件夹里创建.c文件
和前面同样的方法,把.c文件加入项目
左侧可以看到添加的文件,打开编写代码
代码如下:
#include "ledAndKey.h"
//led1-led8
void Led_Disp(unsigned char c)
{
//关闭所有灯
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8
|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
//根据输入打开灯
HAL_GPIO_WritePin(GPIOC, c<<8, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}
//按键检测
unsigned char Key_Scan(void)
{
unsigned char s;
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0) == GPIO_PIN_RESET)
{
s = 1;
}
else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == GPIO_PIN_RESET)
{
s = 2;
}
else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2) == GPIO_PIN_RESET)
{
s = 3;
}
else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == GPIO_PIN_RESET)
{
s = 4;
}
return s;
}
打开头文件
#include "main.h"
void Led_Disp(unsigned char c);
unsigned char Key_Scan(void);
主函数实现(通过灯来测试配置是否成功):
添加头文件
3.2 lcd配置
添加官方给的lcd的文件
和前面一样的方法添加进项目
主函数添加头文件
#include "lcd.h"
lcd初始化
LCD_Init();
lcd例程中可以找到常用的lcd函数
LCD_Clear(Blue);
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
LCD_DisplayStringLine(Line0, (uint8_t *)" ");
3.3 ADC配置
在ADC的.c文件末尾处添加两个函数
int GetADC1(void)
{
int Value;
HAL_ADC_Start(&hadc1);
Value = HAL_ADC_GetValue(&hadc1);
return Value;
}
int GetADC2(void)
{
int Value;
HAL_ADC_Start(&hadc2);
Value = HAL_ADC_GetValue(&hadc2);
return Value;
}
头文件声明
int GetADC1(void);
int GetADC2(void);
初始化
MX_ADC1_Init();
MX_ADC2_Init();
3.4 UART串口配置
MX_USART1_UART_Init(); //初始化
HAL_UART_Transmit(&huart1,str,strlen(str),50); //发送
HAL_UART_Receive_IT(&huart1,str,1); //接受中断
接受中断函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
3.5 I2C配置
添加官方给的.c文件和.h文件
在i2c.c文件后添加读和写函数,并在头文件添加函数声明
void I2CWrite(unsigned char *p,unsigned char data,unsigned char num)
{
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(data);
I2CWaitAck();
while(num--)
{
I2CSendByte(*p++);
I2CWaitAck();
}
I2CStop();
delay1(500);
}
void I2Cread(unsigned char *p,unsigned char data,unsigned char num)
{
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(data);
I2CWaitAck();
I2CStart();
I2CSendByte(0xa1);
I2CWaitAck();
while(num--)
{
*p++ = I2CReceiveByte();
if(num)
I2CSendAck();
else
I2CSendNotAck();
}
I2CStop();
}
主函数初始化
I2CInit();
3.6 TIM配置
3.6.1 输入捕获配置
初始化,打开定时器,开启捕获中断
MX_TIM2_Init();
HAL_TIM_Base_Start(&htim2);
HAL_TIM_OC_Start_IT(&htim2,HAL_TIM_ACTIVE_CHANNEL_1);
HAL_TIM_OC_Start_IT(&htim2,HAL_TIM_ACTIVE_CHANNEL_2);
捕获中断回调函数
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
{
//上升沿中断
}
else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
{
//下降沿中断
}
}
3.6.2 PWM函数
MX_TIM17_Init();
HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);
__HAL_TIM_SET_COMPARE (&htim17,TIM_CHANNEL_1,500);//设置占空比
__HAL_TIM_SET_AUTORELOAD(&htim17,4999); //设置频率
3.7 RTC时钟
创建日期和时间结构体
RTC_TimeTypeDef TIME;
RTC_DateTypeDef DATE;
初始化 获得时间
MX_RTC_Init();
HAL_RTC_GetDate(&hrtc,&DATE,FORMAT_BIN);
HAL_RTC_GetTime(&hrtc,&TIME,FORMAT_BIN);