STM32 GPIO的输入输出-HAL库

本文将介绍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
		}
  }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值