第一课:什么是树莓派
第二课:基于树莓派的10个经典项目
第三课:购买您的第一个树莓派
第四课:如何安装树莓派系统
第五课:树莓派C语言编程手册
第六课:树莓派led控制
如果要实现按下一个按钮让灯亮,再按下让灯灭这样的功能,就需要实现按键编程了,按键编程属于输入设备范畴。
什么是输入设备,什么是输出设备
大家参考第六课中的“什么是IO,什么是GPIO”
用什么做实验
我们一般用第一种按键(左边),淘宝上几毛钱就可以买到,右边的按键,还需要自己去加电阻搭电路,不方便。
编程思路
很多学生总是喜欢看,迟迟不动手,我发现原因是他还没有思路,就是不知如何动手,或者有几种方法,不确定用哪一种比较好,所以在茫茫博客中找到理论依据,其实这种情况,还是动手比较好,编程就是要多写,即时尝试的方法不是最好的,也可以让你搞清楚这种方法的弊端在哪里,然后一步步逼近正确方法,如果没有经验,没有人能够一步到位,所以不尝试是最好的,也最直接的学习方法。
这里的编程思路,其实就是要搞清楚这个按键的工作原理。
我先上一张图:
我们这里拿S1来说明,当我们按下时,有什么现象,不按的时候有什么现象呢?
这里的p0.4就是我们树莓派接线时候的引脚,所以现象就是当不按的时候,p0.4这个点是高电平(比3.3v低一点),按下的时候,p0.4是低电平,因为跟GND(地)连通了。这样我们就可以写程序来读取p0.4引脚的电平,当读到高,说明没有按键,当读到低说明按键了。
——这就是编程思路,了解到这里,你应该迫不及待了吧!
如何连线
VCC接5V,out接wiringPi的第1脚。
开始写程序了
成程序的步骤还是跟led的控制差不多,但是因为这里是要控制输入设备,稍微有些不同,步骤如下:
- 包含头文件
#include <wiringPi.h>
#include <stdlib.h>
#define KEY 1 //按键接到wiringPi编码的#1号脚 - 设置wiringPi编码模式
if(wiringPiSetup()<0)
{
perror(“树莓派启动失败…”);
exit(-1);
} - 设置引脚功能
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控制