树莓派系列教程9:按键

上两章我们讲解了在树莓派上如何点亮一个LED灯,这一章我们讲解一下按键以及事件中断。

一、bcm2835
01#include <bcm2835.h>
02#include <stdio.h>
03 
04#define  KEY  20
05int main(int argc, char **argv)
06{
07    if (!bcm2835_init())return 1;
08    bcm2835_gpio_fsel(KEY, BCM2835_GPIO_FSEL_INPT);
09    bcm2835_gpio_set_pud(KEY, BCM2835_GPIO_PUD_UP);
10    printf("Key Test Program!!!!\n");  
11    while (1)
12    {  
13        if(bcm2835_gpio_lev(KEY) == 0)
14        {  
15            printf ("KEY PRESS\n") ;
16            while(bcm2835_gpio_lev(KEY) == 0)
17                bcm2835_delay(100);
18        }  
19        bcm2835_delay(100);
20    }  
21    bcm2835_close();
22    return 0;
23}

编译并执行,按下按键会看到窗口显示”KEY PRESS”,按Ctrl+C结束程序。

1gcc –Wall key.c –o key –lbcm2835
2 
3sudo ./key

注:(1)bcm2835_gpio_fsel(KEY, BCM2835_GPIO_FSEL_INPT);设置管脚为输入模式

      (2)bcm2835_gpio_set_pud(KEY, BCM2835_GPIO_PUD_UP);设置为上拉模式

      (3) bcm2835_gpio_lev(KEY);读取管脚状态

    二、wiringPi

01#include <stdio.h>
02#include <wiringpi.h>
03 
04char KEY = 28;
05 
06int main()
07{
08    if (wiringPiSetup() < 0)return 1 ;
09    pinMode (KEY,INPUT);
10    pullUpDnControl(KEY, PUD_UP);
11    printf("Key Test Program!!!\n");
12    while(1)
13    {  
14        if (digitalRead(KEY) == 0) 
15        {  
16            printf ("KEY PRESS\n") ;
17            while(digitalRead(KEY) == 0)
18                delay(100);
19        }  
20        delay(100);
21    }  
22}

     编译并执行,按下按键会看到窗口显示”KEY PRESS”,按Ctrl+C结束程序。

1gcc –Wall key.c –o key –wiringPi
2 
3sudo ./key

注:(1)pinMode (KEY,INPUT);设置管脚为输入模式

      (2)pullUpDnControl(KEY, PUD_UP);设置为上拉模式

      (3) digitalRead(KEY);读取管脚状态

通过中断的方式编程

01/* Interrupt.c
02 * you can build this like:
03 * gcc -Wall Interrupt.c -o Interrupt -lwiringPi
04 * sudo ./Interrupt
05*/
06#include <stdio.h>
07#include <wiringPi.h>
08 
09#define button 28
10char flag = 0;
11void myInterrupt()
12{
13    flag ++;
14}
15 
16int main()
17{
18    if(wiringPiSetup() < 0)return 1;
19    pinMode(button,INPUT);
20    pullUpDnControl(button,PUD_UP);
21    if(wiringPiISR(button,INT_EDGE_RISING,&myInterrupt) < 0)
22    {
23        printf("Unable to setup ISR \n");
24    }
25    printf("Interrupt test program\n");
26    while(1)
27    {
28        if(flag)
29        {
30            while(digitalRead(button) ==0);
31            printf("button press\n");
32            flag = 0;
33        }
34    }
35}

编译并执行

1gcc –Wall Interrupt.c –o Interrupt -lwirngPi
2 
3sudo ./Interrupt

注:(1)wiringPiISR(button,INT_EDGE_FALLING,&myInterrupt);设置中断下降沿触发,myInterrupt为中断处理函数。

      三、python

01#!/usr/bin/python
02# -*- coding:utf-8 -*-
03import RPi.GPIO as GPIO
04import time
05 
06KEY = 20
07 
08GPIO.setmode(GPIO.BCM)
09GPIO.setup(KEY,GPIO.IN,GPIO.PUD_UP)
10while True:
11    time.sleep(0.05)
12    if GPIO.input(KEY) == 0:
13        print("KEY PRESS")
14        while GPIO.input(KEY) == 0:
15            time.sleep(0.01)

执行程序,按下按键会看到窗口显示”KEY PRESS”,按Ctrl+C结束程序。

1sudo python key.py

注:(1)GPIO.setup(KEY,GPIO.IN,GPIO.PUD_UP) 设置管脚为上拉输入模式

    (2)GPIO.input(KEY) 读取管脚值

通过中断模式编程

01#!/usr/bin/python
02# -*- coding:utf-8 -*-
03import RPi.GPIO as GPIO
04import time
05 
06KEY = 20
07 
08def MyInterrupt(KEY):
09    print("KEY PRESS")
10 
11GPIO.setmode(GPIO.BCM)
12GPIO.setup(KEY,GPIO.IN,GPIO.PUD_UP)
13GPIO.add_event_detect(KEY,GPIO.FALLING,MyInterrupt,200)
14 
15while True:
16    time.sleep(1)

注:(1)def MyInterrupt(KEY): 定义中断处理函数

 (2) GPIO.add_event_detect(KEY,GPIO.FALLING,MyInterrupt,200) 增加事件检测,下降沿触发,忽略由于开关抖动引起的小于200ms的边缘操作。

关于树莓派事件中断编程请参考:http://www.guokr.com/post/480073/focus/1797650173/