赞
踩
本文将介绍,在STM32F103系列的单片机中如何通过定时器和GPIO模块,实现定时扫描按键功能。
本文将从定时器、GPIO原理入手,讲解使用到的函数以及配置参数,最后做总结。
使用定时器,需要先了解定时器的原理及其相关参数。
定时器是一种计算时间的模块,可以用来触发一些事件、完成一些操作或者调度系统任务。定时器的核心部分为计数器和控制寄存器。
定时器开始计数后,计数值会每次增加1,当计数值达到设定的上限值时,会触发一个中断或者其他的事件。同时,可以通过调整定时器的各个参数来控制计数器的计数速率、计数上限以及触发中断的条件。
在使用定时器前,需要对其相关参数进行配置,常用的定时器参数包括:
常用的配置定时器的函数包括:
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模块包含多个引脚,每个引脚具有输入和输出两种模式,可以用来控制各种外设,例如LED、按键等。
GPIO模块的输入输出控制是通过寄存器进行的,每个IO口都与一个寄存器相关联,我们可以通过修改该寄存器的值来控制IO口的状态,从而实现相应的输入/输出功能。常见的GPIO寄存器包括:GPIOx_CRL、GPIOx_CRH、GPIOx_ODR、GPIOx_IDR、GPIOx_BSRR、GPIOx_BRR、GPIOx_LCKR等。
在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号引脚,初始化为输入上拉模式。
下面我们结合以上的知识,来实现简单的定时扫描按键功能。该功能的基本实现思路为:
为了便于演示,我们使用开发板上的资源做一个示例:定时器每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 © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。