记得以前学习单片机,首先是流水灯然后是按键、中断、定时器…… 最近几年键盘手机也是渐渐的被触摸屏幕的手机所取代。SIN210开发板上有一块FT液晶屏,并配有一个电阻触摸屏,所以一直没鼓捣按键,今天参考了下SINLINX公司提供的教程,来鼓捣一下按键。。。
SIN210开发板上具有8个按键,电路图如下:
图9-1:User Key
EINT0~7 就是对应的和CPU的GPH0_0 ~ GH0_7 如下图所示:
图9-1-1:User Key
开发板上的按键,是借助linux的input子系统进行的修改。
一、驱动
(1)编辑/kernel/drivers/input/keyboard/s3c-gpio_keys.c 文件
(2)修改 s3c_gpio_keys 结构体
struct s3c_gpio_key s3c_gpio_keys[]=
{
{
.pin = S5PV210_GPH0(0),
.eintcfg = 0X0f<<0,
.inputcfg = 0<<0,
.eint = IRQ_EINT0,
},
/*剩下的7个,与这个类似,在这里就不重复了*/ };
}
(3)编辑kernel/arch/arm/mach-s5pv210/mach-smdkv210.c文件
(4)编辑 gpio_buttons 结构体,定义按键的键值
static struct gpio_keys_button gpio_buttons[] = {
{
.gpio
= S5PV210_GPH0(0),
.code
= 231,
.desc
= "CALL",
.active_low = 1,
.wakeup
= 1,
},
/*剩下的7个,与这个类似,在这里就不重复了*/
};
(5)查询键值请参看文件/kernel_smdkv210/include/linux/input.h
(6)编辑完成后,重新编译内核即可.
二、应用(主要就是写个简单的程序来通过Qt来显示哪个键被按下)
(1)新建一个Qt工程
(2)新建key.c key.h led.c文件如下
//key.c
#include "key.h"
#include
#include
#include
#include
#include
#define NOKEY 0
int key_fd=0;
struct input_event t;
int key_open(const char*devname)
{
key_fd=open(devname,O_RDWR);
printf("KEY driver is ok\n");
if(key_fd<0)
{
printf("open device %s failed.\n",devname);
return -1;
}
return 0;
}
int key_read()
{
if(read(key_fd,&t,sizeof(t))==sizeof(t))
{
if(t.type==EV_KEY)
if(t.value==0 || t.value==1)
{
switch(t.code)
{
case 231:
printf("S1 %s\n",(t.value)?"Pressed":"Released");
return ((t.value)?0x11:0x10);
break;
case 139:
printf("S2 %s\n",(t.value)?"Pressed":"Released");
return ((t.value)?0x21:0x20);
break;
case 158:
printf("S3 %s\n",(t.value)?"Pressed":"Released");
return ((t.value)?0x31:0x30);
break;
case 107:
printf("S4 %s\n",(t.value)?"Pressed":"Released");
return ((t.value)?0x41:0x40);
break;
case 102:
printf("S5 %s\n",(t.value)?"Pressed":"Released");
return ((t.value)?0x51:0x50);
break;
case 30:
printf("S6 %s\n",(t.value)?"Pressed":"Released");
return ((t.value)?0x61:0x60);
break;
case 48:
printf("S7 %s\n",(t.value)?"Pressed":"Released");
return ((t.value)?0x71:0x70);
break;
case 46:
printf("S8 %s\n",(t.value)?"Pressed":"Released");
return ((t.value)?0x81:0x80);
break;
default:
break;
}
}
}
}
int key_close(void){
if(key_fd)
close(key_fd);
}
/************************************/
//led.c
#include "key.h"
#include
#include
#include
#include
#include
#define IOCTL_LED_ON 0
#define IOCTL_LED_OFF 1
int led_fd=0;
int led_open(const char*devname){
led_fd=open(devname,O_RDWR);
printf("LED driver is ok\n");
if(led_fd<0){
printf("open device %s failed.\n",devname);
return -1;
}
return 0;
}
int led_ioctl(const int no,const int sw){
//led_fd=open("/dev/led",O_RDWR);
int num=no;
ioctl(led_fd,sw,num);
printf("LED%dis open\n",num);
return 0;
}
int led_close(void){
if(led_fd)
close(led_fd);
}
/*********************************/
//key.h
#ifndef KEY_H
#define KEY_H
#ifdef __cplusplus
extern "C" {
#endif
extern int key_open(const char *devname);
extern int key_read();
extern int key_close(void);
extern int key_fd;
extern int led_open(const char *devname);
extern int led_ioctl(const int no,const int sw);
extern int led_close(void);
extern int led_fd;
#ifdef __cplusplus
}
#endif
#endif
用到了一个Qt的QSocketNotifier。
QSocketNotifier 用来监听系统文件操作,将操作转换为Qt事件进入系统的消息循环队列。并调用预先设置的事件接受函数,处理事件。一共存在3类事件:read,write,exception.
QSocketNotifier::Read 0 There is data to be read.
QSocketNotifier::Write 1 Data can be written.
QSocketNotifier::Exception 2 An exception has occurred. We recommend against using this.
通过QSocketNotifier来监听是否有按键按下的事件,通过槽和按键处理函数buttonOnclik()连接。
代码如下:
/*mainwindow.h*/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include#include
namespace Ui {
class MainWindow;
//class QSocketNotifier;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
protected:
void paintEvent(QPaintEvent* e);
private slots:
void buttonClicked();
private:
int k_fd;
int led_fd;
QSocketNotifier* m_notifier;
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include#include
#include "key.h"
#define LED1 0
#define LED2 1
#define LED3 2
#define LED4 3
#define LED_ON 0
#define LED_OFF 1
//int led_fd;
int mm_key=0,last_key=0;
//int m_notifier;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
k_fd=key_open("/dev/input/event0");
if(led_fd==-1)
QMessageBox::warning(this, tr("Error"), tr("Not Found /dev/led !"));
led_fd=led_open("/dev/led");
if(k_fd==-1)
QMessageBox::warning(this, tr("Error"), tr("Not Found /dev/input/event0 !"));
m_notifier = new QSocketNotifier(k_fd, QSocketNotifier::Read, this);
connect (m_notifier, SIGNAL(activated(int)), this, SLOT(buttonClicked()));
}
void MainWindow::buttonClicked()
{
mm_key=key_read();
if(mm_key!=last_key)
{
last_key=mm_key;update();
}
}
void MainWindow::paintEvent(QPaintEvent*)
{
switch(last_key)
{
case 0x11: ui->KeyDis->setText("S1 is Pressed0!"); led_ioctl(LED1,LED_ON); break;
case 0x21: ui->KeyDis->setText("S2 is Pressed!"); led_ioctl(LED1,LED_OFF); break;
case 0x31: ui->KeyDis->setText("S3 is Pressed!"); led_ioctl(LED2,LED_ON); break;
case 0x41: ui->KeyDis->setText("S4 is Pressed!"); led_ioctl(LED2,LED_OFF); break;
case 0x51: ui->KeyDis->setText("S5 is Pressed!"); led_ioctl(LED3,LED_ON); break;
case 0x61: ui->KeyDis->setText("S6 is Pressed!"); led_ioctl(LED3,LED_OFF); break;
case 0x71: ui->KeyDis->setText("S7 is Pressed!"); led_ioctl(LED4,LED_ON); break;
case 0x81: ui->KeyDis->setText("S8 is Pressed!"); led_ioctl(LED4,LED_OFF); break;
}
}
MainWindow::~MainWindow()
{
led_close();
key_close();
delete ui;
}
通过屏幕来显示那个按键被按下,具体显示如下:
图9-2-1:Qt-key显示

图9-2-2:Qt-key显示

图9-2-3:Qt-key显示

图9-2-4:Qt-key显示
我要赚赏金
