HAL+M4学习记录_3

一、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文件如下
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文件如下
c 复制代码
#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文件如下
c 复制代码
#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);
	}
}
相关推荐
小林熬夜学编程13 分钟前
【Linux网络编程】第十四弹---构建功能丰富的HTTP服务器:从状态码处理到服务函数扩展
linux·运维·服务器·c语言·网络·c++·http
Jackey_Song_Odd25 分钟前
C语言 单向链表反转问题
c语言·数据结构·算法·链表
QQ同步助手34 分钟前
如何正确使用人工智能:开启智慧学习与创新之旅
人工智能·学习·百度
流浪的小新41 分钟前
【AI】人工智能、LLM学习资源汇总
人工智能·学习
A懿轩A2 小时前
C/C++ 数据结构与算法【数组】 数组详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·数组
半盏茶香2 小时前
在21世纪的我用C语言探寻世界本质 ——编译和链接(编译环境和运行环境)
c语言·开发语言·c++·算法
字节高级特工3 小时前
【C++】深入剖析默认成员函数3:拷贝构造函数
c语言·c++
计算机学长大白4 小时前
C中设计不允许继承的类的实现方法是什么?
c语言·开发语言
yutian06067 小时前
Keil MDK下载程序后MCU自动重启设置
单片机·嵌入式硬件·keil
XH华9 小时前
初识C语言之二维数组(下)
c语言·算法