单片机
返回首页

STM32 GPIO的输入输出-HAL库

2021-12-24 来源:eefocus

本文将介绍STM32基于HAL库的GPIO使用,利用上文创建好的HAL库工程模板,可以方便的编写应用程序。


我们目标是编写一个LED灯和按键的使用例子,每按下一次按键,LED的亮灭状态将进行一次反转。


1. LED软件设计

我们创建'led.h'和'led.c'在工程模板的inc和src文件夹中。


1.1 头文件定义

该模块代码作用是防止在某一个代码文件中引入多个.h文件时,防止重复引入同一个.h文件,如果重复引入的话,在编译时候汇报“redefine”错误。


'ifndef'全称是'if not define',当在一个代码中第一次引入led.h文件时__LED_H未定义,则代码会继续往下执行,同时定义了__LED_H,如果存在第二次引入led.h文件时,由于在第一次引入时已经定义了__LED_H宏,所以“ifndef”判断为假,则往下代码不会被重复执行。


#ifndef __LED_H

#define __LED_H

.

.

.

#endif


1.2 LED引脚的宏定义

在led.h文件中对led的引脚进行宏定义。


#define LED_PIN GPIO_PIN_5

#define LED_GPIO_PORT GPIOB

#define LED_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()


1.3 LED引脚控制宏定义

在led.h文件中对led引脚控制进行宏定义。


/* HAL库函数控制IO */

#define ON  GPIO_PIN_RESET

#define OFF GPIO_PIN_SET

 

#define LED(a) HAL_GPIO_WritePin(LED_GPIO_PORT, LED_PIN, a)

 

/* 操作寄存器控制IO */

#define digitalHi(p,i) {p->BSRR=i;} //设置为高电平,

#define digitalLo(p,i) {p->BSRR=(uint32_t)i << 16;} //输出低电平

#define digitalToggle(p,i) {p->ODR ^=i;} //输出反转状态

 

/* 控制LED的IO */

#define LED_TOGGLE digitalToggle(LED_GPIO_PORT, LED_PIN)

#define LED_OFF digitalHi(LED_GPIO_PORT, LED_PIN)

#define LED_ON digitalLo(LED_GPIO_PORT, LED_PIN)


1.4 LED IO口初始化函数

在led.c文件中编写led管脚初始化函数


void LED_GPIO_Config(void)

{

LED_GPIO_CLK_ENABLE(); // 开启GPIO外设时钟

GPIO_InitTypeDef GPIO_InitStruct; // 定义GPIO_InitTypeDef结构体

GPIO_InitStruct.Pin = LED_PIN; // 管脚

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出

GPIO_InitStruct.Pull = GPIO_PULLUP; // 上拉模式

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; // 管脚速率为高速

HAL_GPIO_Init(LED_GPIO_PORT, &GPIO_InitStruct);

LED_OFF

}


2.按键软件设计

我们创建'key.h'和'key.c'在工程模板的inc和src文件夹中。


2.1按键宏定义

在'key.h'文件中定义引脚。


/* 按键引脚宏定义 */

#define KEY_PIN GPIO_PIN_0

#define KEY_GPIO_PORT GPIOA

#define KEY_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()

 

#define KEY_ON 1

#define KEY_OFF 0


2.2按键初始化函数

在'key.c'定义引脚配置。


void Key_GPIO_Config(void)

{

KEY_GPIO_CLK_ENABLE();

GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.Pin = KEY_PIN;

GPIO_InitStructure.Mode = GPIO_MODE_INPUT; // 输入模式

GPIO_InitStructure.Pull = GPIO_NOPULL; // 不上拉也不下拉

HAL_GPIO_Init(KEY_GPIO_PORT, &GPIO_InitStructure);

}


2.3按键扫描

在'key.c'中定义按键扫描函数。


uint8_t Key_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin)

{

if(HAL_GPIO_ReadPin(GPIOx, GPIO_Pin) == KEY_ON){ // 按键是否按下

HAL_Delay(50); // 软件销抖

while(HAL_GPIO_ReadPin(GPIOx, GPIO_Pin) == KEY_ON);     // 按键是否松开

return KEY_ON;

} else{

return KEY_OFF;

}

}


3.主函数

在main.c“”中整合逻辑,在按键被按下后,led的亮灭状态翻转一次。


int main(void)

{

  HAL_Init();

 

  /* Configure the system clock to 64 MHz */

  SystemClock_Config();

 

  LED_GPIO_Config();

  Key_GPIO_Config();

  while (1)

  {

if(Key_Scan(KEY_GPIO_PORT, KEY_PIN) == KEY_ON){

LED_TOGGLE

}

  }

}

进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 光控音效发生器电路

  • 非常简单的150W功放电路图

  • 一个简单的警笛电路图

  • 一个简单的立体声平衡指示器电路

  • 分享一个电网倾角计电路

  • 使用NE555和磁簧开关的橱柜照明电路

    相关电子头条文章