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