本文是基于韦东山视频的学习笔记
按键原理
按键原理图如下,按键分别是EINT0、2、11, 分别对应引脚是GPF0、GPF2、GPG3,原理图就不详贴了。
同样的,关于GPF寄存器可以看回 Linux嵌入式学习——点个灯(二),关于GPG寄存器如下图,大同小异。GPFCON寄存器是0x56000050,而GPGCON寄存器是0x560000060,如此类推。需要注意的是,设置按键需要把寄存器设置为输入(Input)模式。
那么,GPFCON寄存器应是这样的。
bit | bit | bit | bit | bit | bit | bit | bit |
---|---|---|---|---|---|---|---|
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 |
- | - | 1 | 0 | 1 | 0 | 1 | 0 |
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
- | - | 0 | 0 | - | - | 0 | 0 |
GPGCON寄存器应是这样的。
bit | bit | bit | bit | bit | bit | bit | bit |
---|---|---|---|---|---|---|---|
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 |
- | - | - | - | - | - | - | - |
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
0 | 0 | - | - | - | - | - | - |
原理过后
判断按键状态
结合按键的原理图看,在按键没有按下的时候,引脚是拉高状态,也就是1,在按下的时候,就是0。根据这个信息,就可以读取引脚的状态来判断按键是否按下:0 - 按下
1 - 松开
GPFDAT
bit | bit | bit | bit | bit | bit | bit | bit |
---|---|---|---|---|---|---|---|
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
- | - | - | - | - | ? | - | ? |
GPGDAT
bit | bit | bit | bit | bit | bit | bit | bit |
---|---|---|---|---|---|---|---|
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
- | - | - | - | ? | - | - | - |
代码
详码如下。
因为按键和LED很多,容易混淆,所以做了宏定义处理
void delay(volatile d)
{
while(d--);
}
#define GPFCON (*((volatile unsigned int *)0X56000050))
#define GPFDAT (*((volatile unsigned int *)0X56000054))
#define GPGCON (*((volatile unsigned int *)0X56000060))
#define GPGDAT (*((volatile unsigned int *)0X56000064))
/* LED寄存器 */
#define C_LED1 8 //GPF4
#define C_LED2 10 //GPF5
#define C_LED3 12 //GPF6
#define D_LED1 4 //GPF4
#define D_LED2 5 //GPF5
#define D_LED3 6 //GPF6
/* 按键寄存器 */
#define C_S2 0 /* GPF0 */
#define C_S3 4 /* GPF2 */
#define C_S4 6 /* GPG3 */
#define D_S2 0 /* GPF0 */
#define D_S3 2 /* GPF2 */
#define D_S4 3 /* GPG3 */
int main(void)
{
/* 设置GPFCON的GPF4/5/6为输出引脚
* GPF4(8/9位) GPF5(10/11位) GPF6(12/13位)
*/
GPFCON &= ~((3<<C_LED1)| (3<<C_LED2) | (3<<C_LED3)); /* 把GPFCON 需要位置清零 */
GPFCON |= ((1<<C_LED1)| (1<<C_LED2) | (1<<C_LED3)); /* 把GPFCON 需要位置1,即设置为输出模式*/
/* 设置GPFCON的GPF0/2、GPG3为输入引脚
* GPF0(0/1位) GPF2(4/5位)
*/
GPFCON &= ~((3<<C_S2) | (3<<C_S3)); /* 把GPGCON 需要位置清零 */
GPGCON &= ~(3<<C_S4); /* 把GPGCON 6~7 位清零 */
/* S2-GPF0 、 S3-GPF2 、 S4 - GPG3
* S2控制GPF6、S3控制GPF5、S4控制GPF4
* 如果按键对应DAT寄存器是零,即按键按下,反之
*/
while(1)
{
/* S2控制LED3 */
if (GPFDAT&(1<<D_S2)){
GPFDAT |= (1<<D_LED3);
}
else{
GPFDAT &= ~(1<<D_LED3);
}
/* S3控制LED2 */
if (GPFDAT&(1<<D_S3)){
GPFDAT |= (1<<D_LED2);
}
else{
GPFDAT &= ~(1<<D_LED2);
}
/* S4控制LED1 */
if (GPGDAT&(1<<D_S4)){
GPFDAT |= (1<<D_LED1);
}
else{
GPFDAT &= ~(1<<D_LED1);
}
}
}