当前位置: 移动技术网 > 网络运营>服务器>Linux > STM32单片机利用定时器实现按键采集

STM32单片机利用定时器实现按键采集

2020年08月12日  | 移动技术网网络运营  | 我要评论
源码下载链接:工程项目结构如下图所示:其中画红色方框部分为重要函数来进行讲解TIMx.c#include "TIMx/TIMx.h"#include "LED/LED.h"#include "UART/uart.h"#include "stdio.h"#include "KEY/key.h"extern u8 key_value; // 全局变量/** * 功能:初始化定时器 * 参数: * TIMx:指定待设置的定时器,TIM1-TIM4 *

源码下载链接:https://taileliekaishi.lanzous.com/ifhJffitozg

工程项目结构如下图所示:

其中画红色方框部分为重要函数来进行讲解

TIMx.c

#include "TIMx/TIMx.h"
#include "LED/LED.h"
#include "UART/uart.h"
#include "stdio.h"
#include "KEY/key.h"

extern u8 key_value; // 全局变量
/**
 * 功能:初始化定时器
 * 参数:
 *      TIMx:指定待设置的定时器,TIM1-TIM4
 *      prescaler:设置预分频值 0-65535
 *      period:设置中断周期,即设置重装载寄存器的值 0-65535
 *      IT_Source:中断源,比如更新中断,四个通道的输入比较中断,取值查看:TIM_interrupt_sources 
 *      NewState:是否使能IT_Source参数指定的中断,ENABLE,DISENABLE
 * 返回值:None
 */
void initTIMx(TIM_TypeDef* TIMx,u16 prescaler,u16 period,u16 IT_Source,FunctionalState NewState)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

    switch((u32)TIMx)
    {
        case (u32)TIM1: RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);break; //开启定时器1时钟
        case (u32)TIM2: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);break; //开启定时器2时钟
        case (u32)TIM3: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);break; //开启定时器3时钟
        case (u32)TIM4: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);break; //开启定时器4时钟
        /*其他密度的单片机对case进行删减即可兼容,本程序针对中密度单片机*/
        default  :                                                     		break;
    }

    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;                     //向上计数模式
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;                         //设置时钟分频因子,该分频不是预分频值,要区分
		TIM_TimeBaseStructure.TIM_Period = period;                                      //设置定时器周期
		TIM_TimeBaseStructure.TIM_Prescaler =prescaler;                                 //设置预分频值
    TIM_TimeBaseInit(TIMx, &TIM_TimeBaseStructure);                                 //生效更改

    TIM_Cmd(TIMx, ENABLE);                                                          //开启计数器

    TIM_ITConfig(TIMx,IT_Source,NewState);                                        //使能定时器更新中断      
}

/**
 * 功能:设置定时器周期,即设置重装载寄存器的值
 * 参数:
 *      TIMx:指定待设置的定时器,TIM1-TIM4
 *      period:设置中断周期,即设置重装载寄存器的值 0-65535
 * 返回值:None
 */
void setPeriod(TIM_TypeDef* TIMx,u16 period)
{
    TIM_SetAutoreload(TIMx, period);  //设置重装载值
}

/**
 * 功能:设置定时器预分频值
 * 参数:
 *      TIMx:指定待设置的定时器,TIM1-TIM4
 *      period:设置中断周期,即设置重装载寄存器的值 0-65535
 * 返回值:None
 */
void setPrescaler(TIM_TypeDef* TIMx,u16 prescaler)
{
    /*设置预分频值等于fCK_PSC/(PSC[15:0]+1)
     *fCK_PSC为内部输入时钟,默认72MHz,假如我们想要72000倍分频,即时钟周期1ms  
     *则我们传入的值应该是71999*/
    TIM_PrescalerConfig(TIMx, prescaler,TIM_PSCReloadMode_Update); //设置定时器周期
}


/****************************************定时器中断服务函数************************************************/
void TIM3_IRQHandler(void)   
{
	u8 key_cache = 0;
	
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET)  //由于定时器中断源很多,因此要判断是哪个中断源触发的中断
	{
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //软件清除中断挂起位,否则会一直卡死在中断服务函数
		key_cache = getKeyValue(KEY_PRESS);
		
		/*在主函数执行Delay_ms延时函数时,在此期间30ms时间按键按下值更新为KEY_UP
		在此期间又过了30ms此时按键是没有按下的,但是值被更新为key_No
		等100ms执行完成后,明明在这100ms的时间段内按下了按键但是没有改变灯的闪烁的频率
		因为我们只需要采集按下的值 所以为了避免没有按下的值影响按下的值就进行下面的判断
		*/
		if(key_cache != KEY_NO)
		{
			key_value = key_cache;
		}
		
	}
}

main.c

#include "DELAY/Delay.h"
#include "NVIC/NVIC.h"
#include "TIMx/TIMx.h"
#include "KEY/key.h"
#include "LED/LED.h"

u8 key_value = KEY_NO;

int main(void)
{
    u16 xms = 100;
	/*初始化各外设*/ 
    initSysTick();  
	initLED();
	initKey();
    initNVIC(NVIC_PriorityGroup_2);
 // 每隔30ms执行一次中断服务函数:采集一次按键的值
	initTIMx(TIM3,7199,299,TIM_IT_Update,ENABLE);
	TIM_ARRPreloadConfig(TIM3,ENABLE);
    while (1)
    {
        if(key_value==KEY_UP)               //UP键按下
        { 
            xms = 100;
        }else if(key_value==KEY_DOWN)       //DOWN键按下
        {
            xms = 800;
        }else                               //没有按键按下或全按时不进行任何操作
        {

        }
		toggleLED();
		Delay_ms(xms);
    }
}

 

本文地址:https://blog.csdn.net/weixin_39903708/article/details/107944421

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网