分类: 嵌入式
2012-10-15 22:44:32
int open_port(const char* dev_path)
{
int fd;
//open uart
fd = open(dev_path, O_RDWR|O_NOCTTY|O_NDELAY);
if(fd < 0)
{
perror("open serial port");
return -1;
}
if(fcntl(fd, F_SETFL, 0) < 0)//设置为阻塞模式,后面启动的线程会阻塞,串口有数据才读
perror("fcntl F_SETFL\n");
/*if(isatty(STDIN_FILENO) == 0)//再次验证是否为终端设备,我用的刷卡器,屏蔽了这个,不然会失败
{
perror("standard inpput is not a terminal device");
}*/
return fd;
}
int set_com_config(int fd, int baud_rate, int data_bits, char parity, int stop_bits)
{
struct termios new_cfg, old_cfg;
int speed;
int returnvalue;
returnvalue = tcgetattr(fd, &old_cfg);//save current uart configure
if(returnvalue < 0)
{
perror("tcgetattr:tcsetattr()1");
return -1;
}
new_cfg = old_cfg;//直接获取串口的所有数据到新配置,省去了一些参数的手动设置
cfmakeraw(&new_cfg);//config as orignal mode: recevice byte one by one
new_cfg.c_cflag &= ~CSIZE;//clear c_cflag
switch(baud_rate)
{
case 2400:
speed = B2400;break;
case 4800:
speed = B4800;break;
case 9600:
speed = B9600;break;
case 19200:
speed = B19200;break;
case 38400:
speed = B38400;break;
default:
case 115200:
speed = B115200;break;
}
cfsetispeed(&new_cfg, speed);//set in baud_rate
cfsetospeed(&new_cfg, speed);//set out baud_rate;
switch(data_bits)//set data bits
{
case 7:
new_cfg.c_cflag |= CS7;break;
default:
case 8:
new_cfg.c_cflag |= CS8;break;
}
switch(parity)//set parity
{
default:
case 's':
case 'S':
{
new_cfg.c_cflag &= ~PARENB;
new_cfg.c_cflag &= ~INPCK;
}break;
case 'o':
case 'O':
{
new_cfg.c_cflag |= (PARODD | PARENB);
new_cfg.c_cflag |= INPCK;
}break;
case 'e':
case 'E':
{
new_cfg.c_cflag |= PARENB;
new_cfg.c_cflag &= ~PARODD;
new_cfg.c_cflag |= INPCK;
}break;
case 'n':
case 'N':
{
new_cfg.c_cflag &= ~PARENB;
new_cfg.c_cflag &= ~CSTOPB;
}break;
}
switch(stop_bits)//set stop bits
{
default:
case 1:
new_cfg.c_cflag &= ~CSTOPB;break;
case 2:
new_cfg.c_cflag |= CSTOPB;break;
}
//set wait time and min recevice byte
new_cfg.c_cc[VTIME] = 0;
new_cfg.c_cc[VMIN] = 1;
tcflush(fd, TCIFLUSH);//清除数据
returnvalue = tcsetattr(fd, TCSANOW, &new_cfg);//激活配置
if(returnvalue < 0)
{
perror("tcsetattr:tcsetattr()2");
return -1;
}
return 0;
}
write(fd_com, buff, strlen(buff));//发送
#ifndef RECEIVETHREAD_H
#define RECEIVETHREAD_H
#include <QThread>
class ReceiveThread : public QThread
{
Q_OBJECT
public:
explicit ReceiveThread(QObject *parent = 0);
void run();
void enStopFlag();
void enBaudChanged_flag();
int fd;
int stop_flag;
char buff[100];
int baudChanged_flag;
signals:
void sendbuff(QString );
public slots:
};
#endif // RECEIVETHREAD_H
void ReceiveThread::run()
{
qDebug()<<"Receive thread started";
int count_receive=0, c=0;
QString data;
memset(buff, 0, 100);
data.clear();
while(stop_flag)
{
c = read(fd, buff, 100);
if(baudChanged_flag)
{
data.clear();
memset(buff, 0, 100);
count_receive = 0;
baudChanged_flag = 0;
continue ;
}
if(c >= 0)
data += buff;
else continue;
memset(buff, 0, 100);
count_receive += c;
if(count_receive < 14)
continue;
data = data.mid(1, 10);
emit sendbuff(data);
data.clear();
count_receive = 0;
memset(buff, 0, 100);
}
qDebug()<<"Receive thread exited";
}
以下内容引用自参考资料:(begin到end)
以上代码简单,没有必要做过多的讲解,但是其中的“thread->terminate(); ”有必要讲解下,terminate()函数的调用便不会立刻终止线程,因为线程的何时终止取决于系统的调度策略,所在在之后又调用了wait()函数是线程阻塞等待直到退出或者超时。
最后加以一点就是在.pro文件中加入一行代码才能成功运行:
CONFIG+=thread
转自:http://avny.blog.163.com/blog/static/2101802782012991126278/