今天开始编写按键程序,首先还是按友善提供的例程来学习,例程实现的功能是按下某个键,输出相应的按键序号UP,松开则输出相应的按键序号DOWN。运行完全没问题,输出也正常。例程源代码如下:
/*******filename:test_buttons*******/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/time.h>
#include <errno.h>
int main(void)
{
int buttons_fd;
char buttons[6] = {'0', '0', '0', '0', '0', '0'};
buttons_fd = open("/dev/buttons", 0);
if (buttons_fd < 0) {
perror("open device buttons");
exit(1);
}
for (;;) {
char current_buttons[6];
int count_of_changed_key;
int i;
if (read(buttons_fd, current_buttons, sizeof current_buttons) != sizeof current_buttons) {
perror("read buttons:");
exit(1);
}
for (i = 0, count_of_changed_key = 0; i < sizeof buttons / sizeof buttons[0]; i++) {
if (buttons[i] != current_buttons[i]) {
buttons[i] = current_buttons[i];
printf("%skey %d is %s", count_of_changed_key? ", ": "", i+1, buttons[i] ==
'0' ? "up" : "down");
count_of_changed_key++;
}
}
if (count_of_changed_key) {
printf("\n");
}
}
close(buttons_fd);
return 0;
}
1、代码中红色部分的printf语句,我没看懂为什么这么写,为什么不写成:printf("key %d is %s\n",i+1,buttons[i]=='0'?"up":"down");
2、下载到开发板运行,发现有时候按下一个按键会出来好几个UP和DOWN,应该是例程中没考虑按键防抖的原因;
3、前一篇学习了LED,所以我想写一个程序,实现按下键对应灯亮,松开灯灭的这样一个程序,同时加上按键防抖。
*******************************************************************************************************************************************************************************************************************
以下是我改进后的代码:
/********filename:test_buttons_leds.c**********/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/ioctl.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/select.h>
#include<sys/time.h>
#include<errno.h>
int main(void)
{
int buttons_fd,leds_fd;
char buttons[6]={'0','0','0','0','0','0'}; //save state of buttons
buttons_fd=open("dev/buttons",0);
leds_fd=open("dev/leds",0);
if(buttons_fd<0||leds_fd<0){
perror("open device buttons and leds");
exit(1);
}
for(;;){
char current_buttons[6]; //save current state of buttons
int i,led_stat;
if(read(buttons_fd,current_buttons,sizeof(current_buttons))!=sizeof(current_buttons)){
perror("read buttons:");
exit(1);
}
for(i=0;i<sizeof(buttons)/sizeof(buttons[0]);i++){
if(buttons[i]!=current_buttons[i])
usleep(10000); //延时10ms防抖
if(buttons[i]!=current_buttons[i]){
buttons[i]=current_buttons[i];
printf("key %d is %s\n",i+1,buttons[i]=='0'?"up":"down");
led_stat=buttons[i]-0x30; //将字符转换成数字
ioctl(leds_fd,led_stat,i);
}
}
}
close(leds_fd);
close(buttons_fd);
return 0;
}
下载到开发板运行,防抖效果很好,同时实现了按键点灯的功能。
过程中遇到的问题:
因为后面点灯用到函数ioctl(),需要向它传递buttons[i],但例程中定义的是char型,所以我想改成int型不是更方便么,然后对程序了做了相应的调整,改完之后,再下载运行,出现:read buttons::success,然后程序终止。不知道为什么会有这个现象,由输出中有"read buttons:"所以我怀疑是read()函数那地方的原因,未解决。。。
欢迎大家扫描下方二维码关注我的个人微信公众号,一起交流学习,谢谢。