第七课:树莓派按键控制

第一课:什么是树莓派
第二课:基于树莓派的10个经典项目
第三课:购买您的第一个树莓派
第四课:如何安装树莓派系统
第五课:树莓派C语言编程手册
第六课:树莓派led控制

如果要实现按下一个按钮让灯亮,再按下让灯灭这样的功能,就需要实现按键编程了,按键编程属于输入设备范畴。

什么是输入设备,什么是输出设备

大家参考第六课中的“什么是IO,什么是GPIO”

用什么做实验

我们一般用第一种按键(左边),淘宝上几毛钱就可以买到,右边的按键,还需要自己去加电阻搭电路,不方便。
在这里插入图片描述

编程思路

很多学生总是喜欢看,迟迟不动手,我发现原因是他还没有思路,就是不知如何动手,或者有几种方法,不确定用哪一种比较好,所以在茫茫博客中找到理论依据,其实这种情况,还是动手比较好,编程就是要多写,即时尝试的方法不是最好的,也可以让你搞清楚这种方法的弊端在哪里,然后一步步逼近正确方法,如果没有经验,没有人能够一步到位,所以不尝试是最好的,也最直接的学习方法。
这里的编程思路,其实就是要搞清楚这个按键的工作原理。
我先上一张图:
在这里插入图片描述
我们这里拿S1来说明,当我们按下时,有什么现象,不按的时候有什么现象呢?
这里的p0.4就是我们树莓派接线时候的引脚,所以现象就是当不按的时候,p0.4这个点是高电平(比3.3v低一点),按下的时候,p0.4是低电平,因为跟GND(地)连通了。这样我们就可以写程序来读取p0.4引脚的电平,当读到高,说明没有按键,当读到低说明按键了。
——这就是编程思路,了解到这里,你应该迫不及待了吧!

如何连线

VCC接5V,out接wiringPi的第1脚。
在这里插入图片描述

开始写程序了

成程序的步骤还是跟led的控制差不多,但是因为这里是要控制输入设备,稍微有些不同,步骤如下:

  1. 包含头文件
    #include <wiringPi.h>
    #include <stdlib.h>
    #define KEY 1 //按键接到wiringPi编码的#1号脚
  2. 设置wiringPi编码模式
    if(wiringPiSetup()<0)
    {
    perror(“树莓派启动失败…”);
    exit(-1);
    }
  3. 设置引脚功能
    pinMode(KEY,INPUT);//设置引脚为输入
    4)判断是否按下
    这个地方有一点小经验,很多人是直接控制灯,对于一个初学者来说,把问题分割开来永远是最好的策略,所以,我们这里先实现打印一个消息,然后再来整合灯的代码。
    所以,代码应该是这样
    while(1){
    if(digitalRead(KEY)==0){//按下低电平,松手高电平
    puts(“按下…”);
    }
    }
    最后的完整代码:
pi@xiajiashan:~/pi-c-blog$ cat -n key.c 
     1   #include <stdio.h>
     2   #include <stdlib.h>
     3   #include <wiringPi.h>
     4   #define KEY      1    //wiringPi模式第1号脚
     5   int main()
     6   {
     7     if(wiringPiSetup()==-1)
     8     {
     9       perror("树莓派启动失败");
    10       exit(-1);
    11     }
    12     pinMode(KEY,INPUT);//设置按键为输入
    13     //判断是否按下
    14     while(1){
    15       if(digitalRead(KEY)==0){//按下低电平,松手高电平
    16          puts("按下...");
    17       }
    18     }
    19     return 0;
    20   }
pi@xiajiashan:~/pi-c-blog$ 

编译运行

编译运行会出现很多打印语句,可以说是铺天盖地,就像这样
在这里插入图片描述
甚至,手一碰过去,就出现了一大波打印语句。

如何解决按键不灵敏的问题

上面的问题,其实是正常现象,造成这一现象的原因,是按键有机械抖动,怎么解决这个问题呢?
我们先来看一张图:
在这里插入图片描述
之所以我们的程序出现很多的打印语句,是因为在前沿抖动区间,这个区间是10~20ms,感觉很短,但是对树莓派cpu来说,足可以执行几千次了。
所以,我们需要想办法绕过这段时间,思路是:
先判断低电平,然后延时20ms,跨到稳定区间,再判断一次,如果还是低电平,那么就确认是一个真实的按键了。
代码如下:

pi@xiajiashan:~/pi-c-blog$ vim key_shake.c 
  1  #include <stdio.h>
  2  #include <stdlib.h>
  3  #include <wiringPi.h>
  4  #define KEY      1    //wiringPi模式第1号脚
  5  int main() 
  6  {
  7    if(wiringPiSetup()==-1)
  8    {
  9      perror("树莓派启动失败");
 10      exit(-1); 
 11    } 
 12    pinMode(KEY,INPUT);//设置按键为输入
 13    //判断是否按下
 14    while(1){ 
 15      if(digitalRead(KEY)==0){//按下低电平,松手高电平
 16         //第一次判断是否按下
 17         delayMicroseconds(20000);//延时20ms
 18         if(digitalRead(KEY)==0){
 19            //第二次判断是否按下
 20            while(digitalRead(KEY)==0);//等待松手
 21            puts("按下...");
 22          }
 23      }   
 24    } 
 25    return 0;
 26  } 

这里的20行,是等待手松开的意思。

如何让按键控制灯或者蜂鸣器

我在这里贴出控制蜂鸣器的代码,因为单个的原理已经讲过了,这里只是整合问题,大家还有不懂的可以购买我的教学视频:
https://edu.csdn.net/course/play/28051/383620?spm=1002.2001.3001.4143

pi@xiajiashan:~/pi-c-blog$ vim key_beep_shake.c 
  1  #include <stdio.h>
  2  #include <stdlib.h>
  3  #include <wiringPi.h>
  4  #define KEY      1    //wiringPi模式第1号脚
  5  #define BEEP     7    //wiringPi模式第7号脚
  6  int FLAG = 0;
  7  int main()
  8  {
  9    if(wiringPiSetup()==-1)
 10    {
 11      perror("树莓派启动失败");
 12      exit(-1);
 13    }
 14    pinMode(KEY,INPUT);//设置按键为输入
 15    pinMode(BEEP,OUTPUT);//设置蜂鸣器为输出
 16    digitalWrite(BEEP,1);//初始不响
 17    //判断是否按下
 18    while(1){
 19      if(digitalRead(KEY)==0){//按下低电平,松手高电平
 20         //第一次判断是否按下
 21         puts("按下...");
 22         delayMicroseconds(20000);//延时20ms
 23         if(digitalRead(KEY)==0){
 24            //第二次判断是否按下
 25            while(digitalRead(KEY)==0);//等待松手
 26            if(digitalRead(BEEP)
 27               digitalWrite(BEEP,0);
 28            else    
 29               digitalWrite(BEEP,1);
 30 
 31          }
 32      }
 33    }
 34    return 0;
 35  }

如何实现长按三秒,让树莓派重启

如何用C实现长按3秒重启树莓派,感觉很复杂高深,其实原理非常简单。
完整代码如下:

#include <wiringPi.h>  
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define KEY   7   
int main()
{
   int t1,t2;
   wiringPiSetup()pinMode(KEY,INPUT);   
   while(1)
   {   
       if(digitalRead(KEY))
       {
          usleep(20000);//延时20ms
          if(digitalRead(KEY))
          {          
             t1 = time(NULL);
            while(digitalRead(KEY));            
             t2 = time(NULL);
             if(t2-t1>3){                
                system("sudo reboot");
              }
          }
       }
   }
   
   return 0;
}

想系统学习的同学可以购买我的教学视频:
长按3秒实现树莓派重启视频C语言版

END

希望这篇文章对大家有价值,如果有帮助就收藏吧!

第一课:什么是树莓派
第二课:基于树莓派的10个经典项目
第三课:购买您的第一个树莓派
第四课:如何安装树莓派系统
第五课:树莓派C语言编程手册
第六课:树莓派led控制

猜你喜欢

转载自blog.csdn.net/qq_27320195/article/details/107533570