您的位置:首页 > 编程语言 > Qt开发

串口键盘在Qt上的移植

2013-12-02 17:45 267 查看
项目中用到Qt进行开发,其中键盘部分电路自己设计,所以qt自带的键盘驱动无法直接使用,需要进行一些简单的移植才可以。

键盘电路是用单片机扫描方式,通过串口与系统的连接。为了修改方便,直接拿qkbdtty_qws.cpp进行修改,同时修改的还有qkbdtty_qws.h和qkbddriverfactory_qws.cpp,这几个文件都在src/gui/embedded下面。

为了串口传送的数据具有一定的完整性,我在串口发送键值时,采用的是一次发送2字节,即键值和键值的反码,接收后方便校验。

编译方法:代码修改完成后,只编译gui的库即可,即到gui目录下make,所作的改动都在qt的libQtGui.so里面,编译完成后拷贝该库到目标板即可。当然,Qt的系统配置里面键盘要配置为tty,一般在profile里面配置。

下面是源码:

qkbddriverfactory_qws.cpp文件修改部分如下:

# ifndef QT_NO_QWS_KBD_TTY

    if (driver == QLatin1String("tty") || driver.isEmpty())

        return new QWSMyKeyboardHandler(device);

# endif

qkbdtty_qws.cpp源码:

#include "qkbdtty_qws.h"

#if !defined(QT_NO_QWS_KEYBOARD) && !defined(QT_NO_QWS_KBD_TTY)

#include <sys/types.h>

#include <sys/stat.h>

#include <sys/ioctl.h>

#include <fcntl.h>

#include <termios.h>

#include <unistd.h>

#include <errno.h>

#include <private/qcore_unix_p.h>

#include <qsocketnotifier.h>

#include<stdio.h>      

#include<stdlib.h>     

#include<string.h>

int UART_Open(int fd,char* port)

{

  fd = open( port, O_RDWR|O_NOCTTY|O_NDELAY);

//fd = open( port, O_RDWR);

  if (FALSE == fd){

perror("Can't Open Serial Port");

  return(FALSE);

  }

  if(fcntl(fd, F_SETFL, 0) < 0){

printf("fcntl failed!\n");

    return(FALSE);

  } else {

           //    printf("fcntl=%d\n",fcntl(fd, F_SETFL,0));

  }

  if(0 == isatty(STDIN_FILENO)){

  printf("standard input is not a terminal device\n");

        return(FALSE);

  }

  return fd;

}

void UART_Close(int fd)

{

close(fd);

}

int UART_Set(int fd,int speed,int flow_ctrl,int databits,int stopbits,int parity)

{

    

    int   i;

      int   status;

  int   speed_arr[] = { B115200,B57600,B38400, B19200, B9600, B4800, B2400, B1200, B300,

                        B115200,B57600,B38400, B19200, B9600, B4800, B2400, B1200, B300

                      };

    int   name_arr[] = {

       115200,57600,38400,  19200,  9600,  4800,  2400,  1200,  300,

       115200,57600,38400,  19200,  9600, 4800, 2400, 1200,  300

  };  

struct termios options;

if(tcgetattr( fd,&options)  !=  0){  

   perror("SetupSerial 1");     

   return(FALSE);  

    }

for(i= 0;i < sizeof(speed_arr) / sizeof(int);i++) {

if  (speed == name_arr[i]) {        

      cfsetispeed(&options, speed_arr[i]);  

      cfsetospeed(&options, speed_arr[i]);   

}

    }    

//options.c_cflag |= CLOCAL;

//options.c_cflag |= CREAD;

switch(flow_ctrl){

case 0 :

options.c_cflag &= ~CRTSCTS;

break;    

    case 1 :

    options.c_cflag |= CRTSCTS;

    break;

    case 2 :

    options.c_cflag |= IXON | IXOFF | IXANY;

    break;

}

    

options.c_cflag &= ~CSIZE;

switch (databits){   

case 5 :

    options.c_cflag |= CS5;

    break;

    case 6    :

    options.c_cflag |= CS6;

    break;

    case 7    :     

        options.c_cflag |= CS7;

        break;

    case 8:     

        options.c_cflag |= CS8;

        break;   

           default:    

        fprintf(stderr,"Unsupported data size\n");

        return (FALSE);

}

switch (parity) {   

    case 'n':

    case 'N':

        options.c_cflag &= ~PARENB;  

        options.c_iflag &= ~INPCK;     

        break;  

    case 'o':   

    case 'O':    

        options.c_cflag |= (PARODD | PARENB);  

        options.c_iflag |= INPCK;              

        break;  

    case 'e':  

    case 'E':   

        options.c_cflag |= PARENB;        

        options.c_cflag &= ~PARODD;        

        options.c_iflag |= INPCK;       

        break;

    case 's':

    case 'S':

        options.c_cflag &= ~PARENB;

        options.c_cflag &= ~CSTOPB;

        break;  

        default:   

        fprintf(stderr,"Unsupported parity\n");    

        return (FALSE);

}  

switch (stopbits){   

    case 1:    

        options.c_cflag &= ~CSTOPB;  

        break;  

    case 2:    

        options.c_cflag |= CSTOPB;  

           break;

    default:    

             fprintf(stderr,"Unsupported stop bits\n");  

             return (FALSE);

}

    

   // options.c_oflag &= ~OPOST;

/*RAW mode*//*Input*/

    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); //Ñ¡ÔñÔ­ÊŒÊäÈë·š

    options.c_iflag &= ~(ICRNL | INLCR | IGNCR);

 

    /*Output*/

    options.c_oflag &= ~OPOST; //Ñ¡ÔñÔ­ÊŒÊýŸÝÊä³ö   

    options.c_oflag &= ~(INLCR | IGNCR | ICRNL);

    options.c_oflag &= ~(ONLCR | OCRNL);

    options.c_cc[VTIME] = 0;  //阻塞

    options.c_cc[VMIN] = 2;   //最少接收2个字符

    tcflush(fd,TCIFLUSH);

    if(tcsetattr(fd,TCSANOW,&options) != 0){

    perror("kbd com set error!\n");   

    return (FALSE);  

    }

    ioctl(fd, TIOCMGET, &status);

 

    //ĬÈÏDTR, DSR ÓÐЧ

    status |= TIOCM_DTR;

    status |= TIOCM_DSR;

 

    ioctl(fd, TIOCMSET, status);

return (TRUE);  

}

int UART_Init(int fd, int speed,int flow_ctrlint ,int databits,int stopbits,char parity)

{

if (FALSE == UART_Set(fd,speed,flow_ctrlint,databits,stopbits,parity)) {        

return FALSE;

    } else {

       return  TRUE;

       }

}

int UART_Send(int fd, char *send_buf,int data_len)

{

    int ret;

    

    ret = write(fd,send_buf,data_len);

    if (data_len == ret ){    

   return ret;

    } else {    

   tcflush(fd,TCOFLUSH);    

   return FALSE;

        

    }

    

}

//////////////////////////////////////////////////////

class QWSMyKbPrivate : public QObject

{

Q_OBJECT

public:

QWSMyKbPrivate(QWSMyKeyboardHandler *handler, const QString &device);

~QWSMyKbPrivate();

bool isOpen() { return buttonFD > 0; }

private Q_SLOTS:

void readKeyboardData();

private:

QWSMyKeyboardHandler *m_handler;

QString terminalName;

int buttonFD;

int kbdIdx;

int kbdBufferLen;

unsigned char *kbdBuffer;

QSocketNotifier *notifier;

};

QWSMyKeyboardHandler::QWSMyKeyboardHandler(const QString &device)

: QWSKeyboardHandler(device)

{

d = new QWSMyKbPrivate(this, device);

}

QWSMyKeyboardHandler::~QWSMyKeyboardHandler()

{

delete d;

}

QWSMyKbPrivate::QWSMyKbPrivate(QWSMyKeyboardHandler *h, const QString &device)

: m_handler(h)

{

terminalName = device.isEmpty()?"/dev/ttyS1":device.toLatin1();

buttonFD = -1;

notifier = 0;

if ((buttonFD = QT_OPEN(terminalName.toLatin1().constData(), O_RDWR|O_NOCTTY|O_NDELAY)) < 0) //O_RDONLY| O_NDELAY

{

qWarning("Cannot open %s\n", terminalName.toLatin1());

}

qWarning("open /dev/ttyS1 OK!buttonFD=%d\n",buttonFD);

if ( buttonFD >= 0 )

{

UART_Init(buttonFD,9600,0,8,1,'N');

notifier = new QSocketNotifier( buttonFD, QSocketNotifier::Read, this );

connect( notifier, SIGNAL(activated(int)),this,SLOT(readKeyboardData()) );

}

kbdBufferLen = 80;

kbdBuffer = new unsigned char [kbdBufferLen];

kbdIdx = 0;

}

QWSMyKbPrivate::~ QWSMyKbPrivate()

{

if ( buttonFD > 0 )

{

::close( buttonFD );

buttonFD = -1;

}

delete notifier;

notifier = 0;

delete [] kbdBuffer;;

}

voi
b72a
d QWSMyKbPrivate::readKeyboardData()

{

int n = 0;

int idx = 0;

n = read(buttonFD, kbdBuffer+kbdIdx, 2);

unsigned char *next = kbdBuffer + idx;

int *code = (int *)next;

int keycode = Qt::Key_unknown;

int unicode = 0;

qDebug("Receive num= %d\n", n);

qDebug("Receive key code %d-%d\n", *next ,*(next+1));

if(*next+(*(next+1))!=0xff)

{

    qDebug("key check error!\n");

    return;

}

switch ( (*code) & 0xff )

{

case 0x30:

    keycode = Qt::Key_0;

    unicode='0';

    break;

case 0x31:

    keycode = Qt::Key_1;

    unicode='1';

    break;

case 0x32:

    keycode = Qt::Key_2;

    unicode='2';

    break;

case 0x33:

    keycode = Qt::Key_3;

    unicode='3';

    break;

case 0x34:

    keycode = Qt::Key_4;

    unicode='4';

    break;

case 0x35:

    keycode = Qt::Key_5;

    unicode='5';

    break;

case 0x36:

    keycode = Qt::Key_6;

    unicode='6';

    break;

case 0x37:

    keycode = Qt::Key_7;

    unicode='7';

    break;

case 0x38:

    keycode = Qt::Key_8;

    unicode='8';

    break;

case 0x39:

    keycode = Qt::Key_9;

    unicode='9';

    break;

    

case 0x0d:

    keycode = Qt::Key_Enter;

    break;

case 0x1b:

    keycode = Qt::Key_Escape;

    break;

case 0x09:

    keycode = Qt::Key_Tab;

    break;

case 0x08:

    keycode = Qt::Key_Backspace;

    break;

case 0x27:

    keycode = Qt::Key_Right;

    break;

case 0x25:

    keycode = Qt::Key_Left;

    break;

case 0x26:

    keycode = Qt::Key_Up;

    break;

case 0x28:

    keycode = Qt::Key_Down;

    break;

default:

    qDebug("Unrecognised key code %d", *next );

}

m_handler->processKeyEvent( unicode, keycode, 0, TRUE, FALSE );

m_handler->processKeyEvent( unicode, keycode, 0, FALSE, FALSE);

}

qkbdtty_qws.h源码:

#include "qkbdtty_qws.moc"

#endif // QT_NO_QWS_KEYBOARD || QT_NO_QWS_KBD_TTY

#ifndef QKBDTTY_QWS_H

#define QKBDTTY_QWS_H

#include <QtGui/qkbd_qws.h>

#ifndef QT_NO_QWS_KEYBOARD

#ifndef QT_NO_QWS_KBD_TTY

class QWSMyKbPrivate;

class QWSMyKeyboardHandler : public QWSKeyboardHandler

{

public:

QWSMyKeyboardHandler(const QString &);

virtual ~QWSMyKeyboardHandler();

private:

QWSMyKbPrivate *d;

};

#endif // QT_NO_QWS_KBD_TTY

#endif // QT_NO_QWS_KEYBOARD

#endif // QKBDTTY_QWS_H
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: