基于LPC1114 DevKit口袋开发板,在Keil MDK 4.74上编写一段程序,系统上电,系统默认工作频率为48MHz,利用系统节拍定时器SysTick实现定时1s,控制LPC1114微控制器的GPIO引脚PIO1_9状态反转(LED灯BLINKY闪烁),设置按键BUTTON(PIO3_5)、WEAKUP(PIO1_4)为GPIO输入,使能滞后模式,设置中断方式判断按键状态。
按键功能:
1. BUTTON(PIO3_5)按键按下,闪烁频率为1Hz,再次按下,恢复闪烁频率为0.5Hz;
2. WEAKUP(PIO1_4)按键按下,闪烁频率为2Hz,再次按下,恢复闪烁频率为0.5Hz;
3. 适当考虑按键防抖功能。
#include "LPC11xx.h"
#define INT_TIME_1MS SystemCoreClock / 1000 //基础时间 | 1ms
#define BASIC_FREQUENCY 2000 //基础频率 | 0.5Hz
void Program_Init(void); // 程序初始化函数
void GPIO_Clock_Init(void); // 初始化GPIO时钟
void LED_Init(void); // 初始化LED
void Button_Init(void); // 初始化BUTTON按键
void WEAKUP_Init(void); // 初始化WAKEUP按键
void SysTick_Init(uint32_t ticks); // 初始化SysTick定时器
void SysTick_Handler(void); // SysTick定时器中断处理函数
void PIOINT3_IRQHandler(void); // GPIO3_5按键中断处理
void PIOINT1_IRQHandler(void); // GPIO1_4按键中断处理
/*
void Button_Frequency(void); // BUTTON按键处理函数,调整LED闪烁频率
void WEAKUP_Frequency(void); // WAKEUP按键处理函数,调整LED闪烁频率
*/
void LED_Toggle(void); // 翻转LED状态
/*
void Delay(uint32_t delayTime, uint32_t K); // 延时函数 | totalTime = delayTime*K
*/
static uint32_t msTicks = 0; // SysTick定时器计数,用于控制LED闪烁
static uint32_t COUNT_MAX = 2000; // 初始最大计数值 | 0.5Hz
static uint32_t GPIO3_5_flag = 0; // GPIO3_5按键频率状态标志
static uint32_t GPIO1_4_flag = 0; // GPIO1_4按键频率状态标志
/*
static uint32_t GPIO3_5_Down_flag = 0; // GPIO3_5按键按下标志
static uint32_t GPIO1_4_Down_flag = 0; // GPIO1_4按键按下标志
*/
int main(void){
Program_Init(); // 初始化程序,包括时钟、GPIO和按键
while (1) {
/*
if(GPIO3_5_Down_flag){ // 如果检测到BUTTON按键按下
Button_Frequency(); // 调整LED闪烁频率
GPIO3_5_Down_flag = 0; // 清除按下标志
}
if(GPIO1_4_Down_flag){ // 如果检测到WEAKUP按键按下
WEAKUP_Frequency(); // 调整LED闪烁频率
GPIO1_4_Down_flag = 0; // 清除按下标志
}
*/
if (msTicks >= COUNT_MAX) { // 当计数达到COUNT_MAX时翻转LED状态
LED_Toggle();
msTicks = 0; // 重置计数
}
}
}
void Program_Init(void){
GPIO_Clock_Init(); // 初始化GPIO时钟
LED_Init(); // 初始化LED
Button_Init(); // 初始化BUTTON按键
WEAKUP_Init(); // 初始化WAKEUP按键
SysTick_Init(INT_TIME_1MS); // 初始化SysTick定时器,每1ms产生中断
}
void GPIO_Clock_Init(void){
LPC_SYSCON->SYSAHBCLKCTRL |=
(1UL << 6)|(1UL << 16); // 启用GPIO和IO配置时钟
}
void LED_Init(void) {
LPC_GPIO1->DIR |= (1UL << 9); // 设置GPIO1_9为输出
}
// BUTTON按键初始化
void Button_Init(void){
// 配置PIO3_5为输入
LPC_IOCON->PIO3_5 &= ~(0x1F); // 清除之前的配置
LPC_IOCON->PIO3_5 |= 0x00; // 配置为GPIO功能
// 设置GPIO方向为输入
LPC_GPIO3->DIR &= ~(1UL << 5);
// 设置引脚中断
LPC_GPIO3->IE |= (1UL << 5); // 使能中断
LPC_GPIO3->IS &= ~(1UL << 5); // 设置为边沿触发
LPC_GPIO3->IBE &= ~(1UL << 5); // 不使能双边沿触发
LPC_GPIO3->IEV &= ~(1UL << 5); // 下降沿触发(按钮按下)
// 使能滞后模式
LPC_IOCON->PIO3_5 |= (1UL << 5); // 使能滞后模式
// 清除可能的中断标志
LPC_GPIO3->IC |= (1UL << 5);
// 使能GPIO3中断
NVIC_EnableIRQ(EINT3_IRQn);
}
// WEAKUP按键初始化
void WEAKUP_Init(void){
// 配置PIO1_4为输入
LPC_IOCON->PIO1_4 &= ~(0x1F); // 清除之前的配置
LPC_IOCON->PIO1_4 |= 0x00; // 配置为GPIO功能
// 设置GPIO方向为输入
LPC_GPIO1->DIR &= ~(1UL << 4);
// 设置引脚中断
LPC_GPIO1->IE |= (1UL << 4); // 使能中断
LPC_GPIO1->IS &= ~(1UL << 4); // 设置为边沿触发
LPC_GPIO1->IBE &= ~(1UL << 4); // 不使能双边沿触发
LPC_GPIO1->IEV &= ~(1UL << 4); // 下降沿触发(按钮按下)
// 使能滞后模式
LPC_IOCON->PIO1_4 |= (1UL << 5); // 使能滞后模式
// 清除可能的中断标志
LPC_GPIO1->IC |= (1UL << 4);
// 使能GPIO1中断
NVIC_EnableIRQ(EINT1_IRQn);
}
// SysTick定时器初始化,每1ms产生中断
void SysTick_Init(uint32_t ticks){
SysTick_Config(ticks); // 配置SysTick定时器
}
// SysTick定时器的中断处理函数,每1ms触发一次
void SysTick_Handler(void) {
msTicks++; // 每次中断时,SysTick计数增加1
}
// GPIO3_5的中断服务函数,处理BUTTON按键按下事件
void PIOINT3_IRQHandler(void){
if((LPC_GPIO3->MIS & (1UL << 5)) == (1UL << 5)){ // 检查是否是PIO3_5的中断
/*
GPIO3_5_flag = ~GPIO3_5_flag; // 翻转GPIO3_5的频率标志,用于频率切换
GPIO3_5_Down_flag = 1; // 设置按下标志,用于主循环中处理
GPIO1_4_flag = 0; // 复原GPIO1_4的频率标志
*/
// 判断频率标志
if(GPIO3_5_flag){
COUNT_MAX = BASIC_FREQUENCY; // 再次按下WAKEUP,恢复为0.5Hz
GPIO3_5_flag = 0; // 将标志置0
}else{
COUNT_MAX = 1000; // 第一次按下设置为1Hz
GPIO3_5_flag = 1; // 将标志置1
}
LPC_GPIO3->IC |= (1UL << 5); // 清除中断标志
}
}
// GPIO1_4的中断服务函数,处理WAKEUP按键按下事件
void PIOINT1_IRQHandler(void){
if((LPC_GPIO1->MIS & (1UL << 4)) == (1UL << 4)){ // 检查是否是PIO1_4的中断
/*
GPIO1_4_flag = ~GPIO1_4_flag; // 翻转GPIO1_4的标志,用于频率切换
GPIO1_4_Down_flag = 1; // 设置按下标志,用于主循环中处理
GPIO3_5_flag = 0; // 复原GPIO3_5的频率标志
*/
// 判断频率标志
if(GPIO1_4_flag){
COUNT_MAX = BASIC_FREQUENCY; // 再次按下WAKEUP,恢复为0.5Hz
GPIO1_4_flag = 0; // 将标志置0
}else{
COUNT_MAX = 500; // 第一次按下设置为2Hz
GPIO1_4_flag = 1; // 将标志置1
}
LPC_GPIO1->IC |= (1UL << 4); // 清除中断标志
}
}
/*
// 根据BUTTON按键的状态,调整LED的闪烁频率
void Button_Frequency(void){
Delay(INT_TIME_1MS, 50); // 按键防抖,延时50ms
if(GPIO3_5_flag){ // 第一次按下设置为1Hz
COUNT_MAX = 1000; // 按下BUTTON,设置LED频率为1Hz
}
else{
COUNT_MAX = BASIC_FREQUENCY; // 再次按下BUTTON,恢复为0.5Hz
}
}
// 根据WAKEUP按键的状态,调整LED的闪烁频率
void WEAKUP_Frequency(void){
Delay(INT_TIME_1MS, 50); // 按键防抖,延时50ms
if(GPIO1_4_flag){ // 第一次按下设置为2Hz
COUNT_MAX = 500; // 按下WAKEUP,设置LED频率为2Hz
}
else{
COUNT_MAX = BASIC_FREQUENCY; // 再次按下WAKEUP,恢复为0.5Hz
}
}
*/
// 翻转LED状态
void LED_Toggle(void){
LPC_GPIO1->DATA ^= (1UL << 9); // 翻转GPIO1_9,控制LED亮灭
}
/*
// 延时函数,用于按键防抖
void Delay(uint32_t delayTime, uint32_t K){
int i = delayTime * K; // 计算延时时间
while (--i); // 忙等待,循环消耗时间
}
*/