一、HAL库开发框架
记录HAL学习过程
1.1 CMSIS
CMSIS(Cortex微控制器软件接口标准),用于提供用户和硬件间的接口,用户通过CMSIS标准对Cortex微控制器内部寄存器单元进行读写
1.2 HAL库
HAL(硬件抽象层)为降低直接操作寄存器的成本,推出HAL库,使用HAL库函数完成对寄存器的读写
1.3 基于CMSIS的应用程序开发框架
基于CMSIS的应用程序开发框架可分为三层
- 用户程序层:用户自定义的应用程序文件
- 设备驱动层:HAL库资源
- CMSIS层:内核相关文件、外设寄存器和中断向量定义层
1.4 编译过程文件
MDK编译过程文件
.o
文件:可重定向文件.axf
文件:可执行对象文件.hex
文件:用于下载.map
文件:列表文件,用于分析程序存储占用情况- 其他:一般用不到
二、GPIO
2.1 功能简介
- 输入模式
- 浮空输入
IC内部上下拉电阻均断开,完全取决于外部电路。 - 上拉输入
IC内部上拉电阻使能、下拉电阻断开,在输入高电平信号或无输入信号时,读取到的是高电平;在输入低电平信号时,读取到的是低电平。 - 下拉输入
IC内部上拉电阻断开、下拉电阻使能,在输入低电平信号或无输入信号时,读取到的是低电平;在输入高电平信号时,读取到的是高电平。 - 模拟输入
外部信号不经过施密特触发器,直接连接内部ADC,输入信号电压范围是 V R E F − ≤ V I N ≤ V R E F + V_{REF-}\leq V_{IN}\leq V_{REF+} VREF−≤VIN≤VREF+
- 浮空输入
- 输出模式
- 开漏输出
开漏电路相当于一个MOS管的漏极,要得到高电平必须外接上拉电阻,由外部高电平提供驱动能力,可减少IC内部驱动;未接外部上拉电阻时只能输出低电平;可将多个开漏输出连接在一条线上,通过一只上拉电阻实现线与功能。 - 推挽输出
推挽电路是两个参数相同的三极管或MOS管以推挽方式组成,工作时每次只有一个开关管导通,既可以向负载灌电流,也可以从负载抽电流,使用IC内部高电平,具有电压驱动能力。 - 复用开漏输出
不作为普通IO使用,而是由内部设备直接驱动,特征同开漏输出。 - 复用推挽输出
不作为普通IO使用,而是由内部设备直接驱动,特征同推挽输出。
- 开漏输出
2.2 HAL库配置GPIO
在文件stm32f4xx_hal_gpio.c
中提供了GPIO初始化函数和去初始化函数以及操作函数。系统在上电后,引脚默认状态是模拟模式,要使用这一驱动按以下步骤
- 通过函数
__HAL_RCC_GPIOx_CLK_ENABLE()
使能AHB时钟 - 通过函数
HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
初始化GPIO - 通过函数
HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin)
去初始化GPIO - 通过函数
HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
读取引脚电平 - 通过函数
HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
设置引脚电平
三、通过GPIO点亮LED
这里给出点亮板载电路,两个LED分别在PA6和PA7引脚
这里给出驱动代码
.c
文件如下
/*
*********************************************************************************************************
* Func Statement
*
* 板载两颗LED,LED1是PA6引脚,LED2是PA7引脚,低电平点亮,高电平熄灭
*********************************************************************************************************
*/
#include "bsp.h"
/* private define */
#define LED_GPIO_CLK_ALLENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define GPIO_PIN_LED1 GPIO_PIN_6
#define GPIO_PIN_LED2 GPIO_PIN_7
/*
**********************************************************************************
* @brief 配置板载LED
* @param None
* @return None
* @use
**********************************************************************************
*/
void bsp_InitLed()
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
/* 开启GPIO端口时钟 */
LED_GPIO_CLK_ALLENABLE();
/* 初始熄灭LED */
bsp_LedOff(1);
bsp_LedOff(2);
/* 配置LED */
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStructure.Pin = GPIO_PIN_LED1 | GPIO_PIN_LED2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/*
**********************************************************************************
* @brief 点亮指定LED
* @param __no:LED序号,范围 1 - 2
* @return None
* @use
**********************************************************************************
*/
void bsp_LedOn(uint8_t __no)
{
if(__no == 1)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_LED1, GPIO_PIN_RESET);
}
else if(__no == 2)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_LED2, GPIO_PIN_RESET);
}
}
/*
**********************************************************************************
* @brief 熄灭指定LED
* @param __no:LED序号,范围 1 - 2
* @return None
* @use
**********************************************************************************
*/
void bsp_LedOff(uint8_t __no)
{
if(__no == 1)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_LED1, GPIO_PIN_SET);
}
else if(__no == 2)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_LED2, GPIO_PIN_SET);
}
}
/*
**********************************************************************************
* @brief 翻转指定LED
* @param __no:LED序号,范围 1 - 2
* @return None
* @use
**********************************************************************************
*/
void bsp_LedToggle(uint8_t __no)
{
if(__no == 1)
{
GPIOA->ODR ^= GPIO_PIN_LED1;
}
else if(__no == 2)
{
GPIOA->ODR ^= GPIO_PIN_LED2;
}
}
.h
文件如下
#ifndef __BSP_LED_H
#define __BSP_LED_H
/* public statement */
void bsp_InitLed();
void bsp_LedOn(uint8_t __no);
void bsp_LedOff(uint8_t __no);
void bsp_LedToggle(uint8_t __no);
#endif
main
文件如下
#include "bsp.h"
/* public statement */
static void PrintInfo();
/* public define */
uint32_t sys_clk = 0;
int main()
{
bsp_Init();
//PrintInfo(); /* 打印开发板信息 */
while(1)
{
bsp_LedOff(1);
bsp_LedOn(2);
bsp_DelayMs(200);
bsp_LedOn(1);
bsp_LedOff(2);
bsp_DelayMs(1000);
}
}