历史上的今天
今天是:2024年12月24日(星期二)
2021年12月24日 | 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
}
}
}
史海拾趣
|
本帖最后由 paulhyde 于 2014-9-15 03:05 编辑 74HC595驱动两位数码管74HC595驱动两位数码管 … 查看全部问答> |
|
菜鸟一名, 请教各位高手如何#improt一个ActiveX控件, 主要是不知道#improt之后,如何在代码中使用自己的控件, 谢谢各位高手指教,比较急,还望能详细指教。… 查看全部问答> |
|
各位好.我是CE6.0 RIL层开发的新手。请教几个问题: 1、TCP/IP数据的封装是否工作在RIL层的上层。也就是说是当我用Socket将一个数据send(str);的时候。系统是通过一个怎样的过程将数据按TCP协议封装好,然后是否调用了一些RIL的接口。并通过RIL 驱 ...… 查看全部问答> |
|
马上换工作了,目前有两家公司供选择,一个做WINCE驱动,一个做LINUX驱动的 我两个系统都做过,对LINUX更熟悉,不知道究竟选哪个好,有没有大侠帮我分析下啊,谢谢先… 查看全部问答> |
|
中文参考译文。 相关链接:https://bbs.eeworld.com.cn/upfiles/img/20093/2009318231910906.pdf… 查看全部问答> |




