基于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. 适当考虑按键防抖功能。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#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); // 忙等待,循环消耗时间
}
*/