定时器搭配GPIO做定时扫描按键 您所在的位置:网站首页 金融计算器按键不灵 定时器搭配GPIO做定时扫描按键

定时器搭配GPIO做定时扫描按键

2024-07-09 22:50| 来源: 网络整理| 查看: 265

STM32学习 定时器(TIM)定时器工作原理定时器相关参数相关函数和配置参数 通用输入/输出(GPIO)GPIO原理GPIO相关函数 实现定时扫描按键总结 在STM32F103系列的单片机应用中,定时器(TIM)和通用输入/输出(GPIO)是常用的模块之一。这两个模块结合起来,可以实现非常多的实际应用,其中,定时器可以用来实现定时扫描按键,而GPIO可以用来控制LED等设备。

本文将介绍,在STM32F103系列的单片机中如何通过定时器和GPIO模块,实现定时扫描按键功能。 本文将从定时器、GPIO原理入手,讲解使用到的函数以及配置参数,最后做总结。

定时器(TIM)

使用定时器,需要先了解定时器的原理及其相关参数。

定时器工作原理

定时器是一种计算时间的模块,可以用来触发一些事件、完成一些操作或者调度系统任务。定时器的核心部分为计数器和控制寄存器。

定时器开始计数后,计数值会每次增加1,当计数值达到设定的上限值时,会触发一个中断或者其他的事件。同时,可以通过调整定时器的各个参数来控制计数器的计数速率、计数上限以及触发中断的条件。 在这里插入图片描述

定时器相关参数

在使用定时器前,需要对其相关参数进行配置,常用的定时器参数包括:

周期(ARR):定时器计数器的上限值,当计数器增加到该值时,会触发定时器的中断或其他操作。预分频器(PSC):用于降低计数器输入时钟的频率,从而达到降低定时器计数速率的目的。计数模式(Counter Mode):定时器可以分为向上计数模式和向下计数模式,可以根据具体需求进行配置。输出比较通道(Output Compare Channel):可以通过定时器的输出比较通道来产生PWM波形等复杂的定时信号。 相关函数和配置参数

常用的配置定时器的函数包括:

void TIM_DeInit(TIM_TypeDef* TIMx); //TIMx 定时器的初始化 void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct); //定时器基本配置 void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState); //开启或关闭定时器 void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1); //设置定时器输出比较通道 1 的占空比 void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState); //允许或禁止定时器中断 void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG); //清除定时器的中断标志位

其中,TIM_TimeBaseInitTypeDef 结构体用于初始化定时器的基本配置参数,常用的配置参数包括:

//定时器基本配置结构体 typedef struct { uint16_t TIM_Prescaler; //定时器计数器的预分频值 uint16_t TIM_CounterMode; //定时器的计数模式(向上或向下) uint32_t TIM_Period; //定时器计数器的上限值 uint16_t TIM_ClockDivision; //采样分频 uint8_t TIM_RepetitionCounter; //自动重载计数器值 } TIM_TimeBaseInitTypeDef;

在使用定时器时,需要对其进行初始化并配置相关参数。以下代码段为一个示例初始化函数:

void Timer_Init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); TIM_TimeBaseInitStruct.TIM_Prescaler = 7200; TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStruct.TIM_Period = 1000-1; TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct); TIM_Cmd(TIM3, ENABLE); }

该函数使用的是 TIM3 定时器,采用向上计数模式。定时器预分频器值为7200,计数到1000后(即从0计数到999),会触发定时器中断。TIM_Cmd() 函数用于启用定时器。

推荐查看之前文章:https://blog.csdn.net/hongyun1221/article/details/130973099

通用输入/输出(GPIO)

通用输入/输出(GPIO)是单片机上最为基础,也是最常用的模块之一。GPIO模块包含多个引脚,每个引脚具有输入和输出两种模式,可以用来控制各种外设,例如LED、按键等。

GPIO原理

GPIO模块的输入输出控制是通过寄存器进行的,每个IO口都与一个寄存器相关联,我们可以通过修改该寄存器的值来控制IO口的状态,从而实现相应的输入/输出功能。常见的GPIO寄存器包括:GPIOx_CRL、GPIOx_CRH、GPIOx_ODR、GPIOx_IDR、GPIOx_BSRR、GPIOx_BRR、GPIOx_LCKR等。

GPIO相关函数

在STM32F103系列单片机中,使用GPIO模块时,常用的函数包括:

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct); //初始化GPIO引脚 void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); //GPIO引脚锁定 void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal); //设置或清除GPIO引脚的输出状态 uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); //读取GPIO引脚的输入状态

其中,GPIO_InitTypeDef 结构体用于配置GPIO引脚的具体参数,常用的配置参数包括:

//GPIO 配置结构体 typedef struct { uint16_t GPIO_Pin; //需要初始化的GPIO引脚 GPIOMode_TypeDef GPIO_Mode; //GPIO引脚工作模式 GPIOSpeed_TypeDef GPIO_Speed; //GPIO引脚速度 GPIOOType_TypeDef GPIO_OType; //GPIO引脚输出类型 GPIOPuPd_TypeDef GPIO_PuPd; //GPIO引脚上下拉模式 } GPIO_InitTypeDef;

使用GPIO模块,需要对相关引脚进行初始化并配置其相应的工作模式、输出类型、上下拉模式等参数。以下为一个示例初始化函数:

void GPIO_InitExample(void) { GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能GPIOB的时钟 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; //初始化GPIOB的0号引脚 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; //输入上拉模式 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //50MHz速度 GPIO_Init(GPIOB, &GPIO_InitStruct); //初始化GPIOB }

该函数使用的是GPIOB模块的0号引脚,初始化为输入上拉模式。

实现定时扫描按键

下面我们结合以上的知识,来实现简单的定时扫描按键功能。该功能的基本实现思路为:

初始化GPIO引脚,设置为输入上拉模式初始化TIM定时器,启用定时中断在定时器中断处理函数中检测按键状态

为了便于演示,我们使用开发板上的资源做一个示例:定时器每20ms扫描一次按键,按键配置LED亮灭。

主程序代码

int main(void){ LED_GPIO_Init(); KEY_GPIO_Init(); TIM_EXIT_Init(20000-1, 72-1); while(1){ } }

定时器头文件

#ifndef __TIMER_H #define __TIMER_H #include "stm32f10x.h" #define TIM TIM3 #define TIM_CLK RCC_APB1Periph_TIM3 #define TIM_IRQ TIM3_IRQn #define TIM_IRQHandler TIM3_IRQHandler void TIM_EXIT_Init(uint16_t arr, uint16_t psc); #endif /* __TIMER_H */

定时器源代码

#include "bsp_timer.h" void TIM_NVIC_Init(void){ NVIC_InitTypeDef NVIC_InitStruct; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); NVIC_InitStruct.NVIC_IRQChannel = TIM_IRQ; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct); } void TIM_EXIT_Init(uint16_t arr, uint16_t psc){ TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_NVIC_Init(); RCC_APB1PeriphClockCmd(TIM_CLK, ENABLE); TIM_TimeBaseInitStruct.TIM_Prescaler = psc; TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStruct.TIM_Period = arr; TIM_TimeBaseInit(TIM, &TIM_TimeBaseInitStruct); TIM_ITConfig(TIM, TIM_IT_Update, ENABLE); TIM_Cmd(TIM, ENABLE); }

按键源文件

#ifndef __KEY_H #define __KEY_H #include "stm32f10x.h" typedef enum { key_button = 0, key_release = 1 } KeyStatus; #define KEY_GPIO_PORT GPIOB #define KEY_GPIO_CLK RCC_APB2Periph_GPIOB #define KEY_GPIO_PIN GPIO_Pin_1 void KEY_GPIO_Init(void); void KEY_GPIO_Scan(void); #endif /* __KEY_H */ 总结

本文介绍了在STM32F103单片机中,如何使用定时器和GPIO模块实现定时扫描按键功能。通过学习定时器和GPIO的相关原理和函数,我们可以更加深入地了解STM32F103单片机的工作原理,从而更好地完成各类实际应用。

总的来说,定时器和GPIO模块是STM32F103单片机非常常用和重要的模块,掌握其相关知识和应用技巧,对于提高单片机的应用水平和开发效率具有重要的作用。

程序代码资源下载:https://download.csdn.net/download/hongyun1221/87852606

在这里插入图片描述



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有