LPC1114:按键控制LED灯闪烁频率

       基于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);                               // 忙等待,循环消耗时间
}
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值