串口键盘在Qt上的移植
来源:互联网 发布:kali linux 性能 编辑:程序博客网 时间:2024/04/28 16:53
项目中用到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;;
}
void 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
- 串口键盘在Qt上的移植
- mini2440的串口在Qt上实现
- mini2440的串口在Qt上实现
- QT+QTOPIA在linux上的移植
- QT在arm上的移植
- qt在嵌入式板子上的移植
- 在OMAP3530上移植QT
- mini2440的串口在Qt上实现(原创)
- 在s3c6410上移植lm8333键盘驱动
- QT+QTOPIA在linux上的移植 转
- qt-extended-4.4.3在S3C6410上的移植
- Qt/E4.7 在s3c6410上的移植
- qt程序在arm-tiny6410上的运行以及移植
- qt-extended-4.4.3在S3C6410上的移植
- Qt 4.7.2 在DM365触摸屏上的移植
- Qt-5.2.1在S5PV210上的移植
- Linux Qt+opencv2.3.1在tiny6410上的移植
- qt-4.8.4在ARM平台上的移植
- memset函数详解
- 失业一个月
- 实际项目中的常见算法
- 关于android的activity被回收,导致的变量数据丢失的问题
- 关于java的传值和传引用
- 串口键盘在Qt上的移植
- 2011年12月 六级听力短对话八个
- 运行junit test 出现Unrooted Tests initializationError
- eclipse中使用link方式安装插件
- JSP表单中的form传值
- Android 4.0 事件输入(Event Input)系统
- VS编译器快捷键大全
- 从一条select语句看Oracle数据库查询工作原理
- OpenCart之会员等级教程