Geehy极海半导体

当前位置:主页 > 服务支持 > 常见问题 > Geehy极海半导体 >

极海APM32E030基本定时器的使用与按键库的移植

作者: admin 时间:2025-07-31 来源:未知
摘要:本篇文章旨在分享 极海 APM32E030系列芯片的使用-关于基本定时器的使用与按键库的移植。 此例程在前一个GPIO使用基础上,加入基本定时器的使用,并整合定时器与GPIO,移植开源程序,...

  本篇文章旨在分享极海APM32E030系列芯片的使用-关于基本定时器的使用与按键库的移植。
 
  此例程在前一个GPIO使用基础上,加入基本定时器的使用,并整合定时器与GPIO,移植开源程序,通过事件驱动型按键模块,实现按键的长短按功能,开源链接找不到了,但有压缩包,可自行下载查看,部分介绍如图所示:
  APM32E030定时器操作之5ms定时器使用:
 
  极海APM32E030本次例程使用基本定时器(TMR6),产生5ms定时中断,定时器的初始化如下所示:
void timer_init(void)
{
        RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR6);        //打开定时器的时钟
        TMR_TimeBase_T TIM_TimeBaseInitStruct;                        //配置时基单元
        TIM_TimeBaseInitStruct.clockDivision=TMR_CKD_DIV1;                //1分频,时钟为72M
        TIM_TimeBaseInitStruct.counterMode=TMR_COUNTER_MODE_UP;        //只能向上计数
        TIM_TimeBaseInitStruct.div=50-1;                                //10k频率下记50个数=5ms
        TIM_TimeBaseInitStruct.period=7200-1;                        //72M进行7200的分频=10k 0.1ms
        TIM_TimeBaseInitStruct.repetitionCounter=0;                //重复计数器,不用
        TMR_ConfigTimeBase(TMR6,&TIM_TimeBaseInitStruct);                                
 
        TMR_ClearStatusFlag(TMR6,TMR_COUNTER_MODE_UP);
        TMR_EnableInterrupt(TMR6, TMR_INT_UPDATE);                //使能中断                                                                                                
        NVIC_EnableIRQRequest(TMR6_IRQn, 31);                        //配置NVIC 与优先级
        TMR_Enable(TMR6);                                                                //启动定时器
}
  在中断函数中添加IO口的翻转,测试定时器是否设置准确:
void TMR6_IRQHandler(void)
{
        if (TMR_ReadIntFlag(TMR6, TMR_INT_FLAG_UPDATE) == SET)
        {
            TMR_ClearIntFlag(TMR6, TMR_INT_FLAG_UPDATE);
            LED1_turn();     
        }
}
  按键库的移植
 
  在hardware文件夹下新建一个文件夹,将按键库文件添加进去,并新建一个app文件,存放自己的按键初始化、定时器等函数,如图:
  在工程文件中添加此文件夹路径并添加这四个文件,其中,multi_button.c/.h文件暂时不需要修改,我们在button_app.c中,添加按键与定时器的初始化


#include "button_app.h"
/*初始化按键*/
void button_key_init(void)
{
        RCM_EnableAHBPeriphClock(KEY1_GPIO_RCC);
        RCM_EnableAHBPeriphClock(KEY2_GPIO_RCC);
        GPIO_Config_T GPIO_InitStructure;
        GPIO_InitStructure.mode = GPIO_MODE_IN;
        GPIO_InitStructure.pin = KEY1_Pin;
        GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
        GPIO_InitStructure.pupd = GPIO_PUPD_PU;                        //上拉输入
        GPIO_Config(KEY1_GPIO, &GPIO_InitStructure);
        GPIO_InitStructure.mode = GPIO_MODE_IN;
        GPIO_InitStructure.pin = KEY2_Pin;
        GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
        GPIO_InitStructure.pupd = GPIO_PUPD_PU;                        //上拉输入
        GPIO_Config(KEY2_GPIO, &GPIO_InitStructure);
}
/**读电平**/
uint8_t read_button1_GPIO() 
{
        return GPIO_ReadInputBit(KEY1_GPIO, KEY1_Pin);
}
uint8_t read_button2_GPIO() 
{
        return GPIO_ReadInputBit(KEY2_GPIO, KEY2_Pin);
}
/**********/
/**定时器初始化**/
void button_timer_init(void)
{
    RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR6);        //打开定时器的时钟
        TMR_TimeBase_T TIM_TimeBaseInitStruct;                        //配置时基单元
        TIM_TimeBaseInitStruct.clockDivision=TMR_CKD_DIV1;                //1分频,时钟为72M
        TIM_TimeBaseInitStruct.counterMode=TMR_COUNTER_MODE_UP;        //只能向上计数
        TIM_TimeBaseInitStruct.div=50-1;                                //10k频率下记50个数=5ms
        TIM_TimeBaseInitStruct.period=7200-1;                        //72M进行7200的分频=10k 0.1ms
        TIM_TimeBaseInitStruct.repetitionCounter=0;                //重复计数器,不用
        TMR_ConfigTimeBase(TMR6,&TIM_TimeBaseInitStruct);                                
 
        TMR_ClearStatusFlag(TMR6,TMR_COUNTER_MODE_UP);
        TMR_EnableInterrupt(TMR6, TMR_INT_UPDATE);                //使能中断                                                                                                
        NVIC_EnableIRQRequest(TMR6_IRQn, 31);                        //配置NVIC 与优先级
        TMR_Enable(TMR6);                                                                //启动定时器                                                                                                                                        
}
 
void button_timer_callback(void)
{
        if (TMR_ReadIntFlag(TMR6, TMR_INT_FLAG_UPDATE) == SET)
    {
        TMR_ClearIntFlag(TMR6, TMR_INT_FLAG_UPDATE);
                button_ticks();     //需要周期调用按键处理函数
    }                                                                                                                
}
/**********/
  定时器的回调为自己定义的函数,此时硬件初始化完成;我们还需创建按键,并实现按键的回调函数,
struct Button btn1;                //创建第1个按键
struct Button btn2;                //创建第2个按键
 
void button_Init(void)
{
        button_key_init();                //按键硬件初始化
        button_timer_init();        //按键定时器初始化
        button_init(&btn1, read_button1_GPIO, 0);        //初始化按键1按下电平读取状态
        button_init(&btn2, read_button2_GPIO, 0);        //初始化按键2按下电平读取状态
        button_attach(&btn1, SINGLE_CLICK,        BTN1_PRESS_DOWN_Handler);        //短按一下
        button_attach(&btn1, DOUBLE_CLICK,        BTN1_PRESS_REPEAT_Handler);        //双击一下
        button_attach(&btn1, LONG_RRESS_START, BTN1_LONG_RRESS_START_Handler);        //长按
        button_attach(&btn2, SINGLE_CLICK,        BTN2_PRESS_DOWN_Handler);        //短按一下
        button_attach(&btn2, DOUBLE_CLICK,        BTN2_PRESS_REPEAT_Handler);        //双击一下
        button_attach(&btn2, LONG_RRESS_START, BTN2_LONG_RRESS_START_Handler);        //长按
        button_start(&btn1);
        button_start(&btn2);
         
}
 
void BTN1_PRESS_DOWN_Handler(void* btn)
{
        LED1_on();
}
void BTN1_PRESS_REPEAT_Handler(void* btn)
{
        LED1_off();
}
void BTN1_LONG_RRESS_START_Handler(void* btn)
{
        LED1_turn();
}
 
void BTN2_PRESS_DOWN_Handler(void* btn)
{
        LED2_on();
}
void BTN2_PRESS_REPEAT_Handler(void* btn)
{
        LED2_off();
}
void BTN2_LONG_RRESS_START_Handler(void* btn)
{
        LED2_turn();
}
  此时按键全部功能实现,只需在初始化中,调用button_Init();函数,即可实现按键的长短按功能
#include "apm32e030.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "button_app.h"
 
int main (void)
{
        LED_init();
        
        /*按键初始化*/
        button_Init();
        
        while(1)
        {
 
        }
}
  此时,我们单机按键1,可实现LED的点亮,双击可实现LED的熄灭,长按可实现LED的翻转,按键2同理,此时我们的按键库基本移植完成,此库中还有其它的功能,可根据自己的需求进行相应的更改。
  如需APM32E030相关资料,请联系极海代理商联科芯微电子。电话:15994707769,LEO WANG.

[向上]