SIN210学习笔记__Key

作者: liunian__92
上传时间为: 2015-03-04 04:50 PM
2015-03-04
阅读:

       记得以前学习单片机,首先是流水灯然后是按键、中断、定时器…… 最近几年键盘手机也是渐渐的被触摸屏幕的手机所取代。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,  
}

(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文件。

用到了一个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;  
}  

按键S1来点亮LED1,按键S2来熄灭LED1;按键S3来点亮LED2……

通过屏幕来显示那个按键被按下,具体显示如下:

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

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

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

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



                               最后非常感谢 SINLINX 公司提供的sin210开发板


相关经验
全部评论 ()
条评论
写评论

创建讨论帖子

登录 后参与评论
系统提示