本篇文章旨在分享极海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.