一個串口操作的C++代碼

下面給出一個關於串口操作的C++代碼,本代碼運行環境爲linux

#ifndef _SERIALCOM_H_
#define _SERIALCOM_H_


typedef struct _serialconfig_{
long baud;/*波特率:如38400,115200等*/
unsigned char databits;/*數據位0-8位;1-7位;2-6位;3-5位;*/
unsigned char parity;/*奇偶校驗位:0-無奇偶校驗;1-設置爲奇效驗;2-轉換爲偶效驗*/
unsigned char stopbits;/*停止位:0--1位停止位;1--2位停止位*/
}serialconfig_t;

class Serialcom
{
public:
	Serialcom();
	Serialcom(serialconfig_t serialconf,int delay,int choice);
	~Serialcom();
	int SerialcomOpen();
	int SerialcomClose();
	int CheckSerialcomData();
	int SerialcomRead(char* pbuffer,int dataLen);
	int SerialcomWrite(char* pbuffer,int dataLen);
	
protected:
	int ComFd;	/*串口描述符*/
	int stat;
	long baud;/*波特率:如38400,115200等*/
	unsigned char databits;/*數據位0-8位;1-7位;2-6位;3-5位;*/
	unsigned char parity;/*奇偶校驗位:0-無奇偶校驗;1-設置爲奇效驗;2-轉換爲偶效驗*/
	unsigned char stopbits;/*停止位:0--1位停止位;1--2位停止位*/
	int usec;
	int port;	/*0,1,2;only 3 choice*/
#endif

#include "serialcom.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <termios.h>
#include <errno.h>
#include <iostream>
using namespace std;

Serialcom::Serialcom()
{
	long baud = 19200;
	unsigned char databits = '8';
	unsigned char parity = 'N';
	unsigned char stopbits = '1';
	usec = 1;
	port = 2;
	stat = 0;
	ComFd = -1;
    std::cout<<baud<<"\t"<<databits<<"\t"<<parity<<"\t"<<stopbits<<std::endl;
}

Serialcom::Serialcom(serialconfig_t serialconf,int delay,int choice)
{
	long baud = serialconf.baud;
	unsigned char databits = serialconf.databits;
	unsigned char parity = serialconf.parity;
	unsigned char stopbits = serialconf.stopbits;
	usec = delay;
	port = choice;
	stat = 0;
	ComFd = -1;
}

Serialcom::~Serialcom()
{

}
int Serialcom::SerialcomOpen()
{
    char dev[][13] = {"/dev/tty0", "/dev/tty1", "/dev/ttyS0"};//此處對應port,選擇你要打開的串口
    if((port < 0) || (port > 2) ){
        printf("the port is out range");
        return -1;
    }
    /*open port*/
    ComFd = open(dev[port], O_RDWR | O_NOCTTY | O_NDELAY);
    if(ComFd < 0){
        ComFd = open(dev[port], O_RDWR | O_NOCTTY | O_NDELAY);
        if(ComFd < 0){ 
            perror("open serial port");
            return -1;
        }
    }
    
    if(fcntl(ComFd, F_SETFL,0) < 0){
        perror("fcntl F_SETFL");
    }

    if(isatty(ComFd) == 0){
        perror("isatty is not a terminal device");
    }
	stat = 1;
	
	
	    struct termios new_cfg, old_cfg;
    int speed_arry[]= {B2400, B4800, B9600, B19200, B38400, B115200};
    int speed[]={2400,4800,9600,19200,38400,115200};
    int i = 0; 
    
    /*save and test the serial port*/
    if(tcgetattr(ComFd, &old_cfg) < 0){
        perror("tcgetattr");
        return -1;
    }

    new_cfg = old_cfg;
    cfmakeraw(&new_cfg);    
    new_cfg.c_cflag &= ~ CSIZE;    
    
    
    for(i = sizeof(speed_arry) / sizeof(speed_arry[0]); i > 0; i--)
    {
        if(baud == speed[i]){
            cfsetispeed(&new_cfg,speed_arry[i]);
            cfsetospeed(&new_cfg,speed_arry[i]);
        }
    }


    switch(databits)   
    {
        case '7':
                new_cfg.c_cflag |= CS7;
                break;
                
        default:
        case '8':
                new_cfg.c_cflag |= CS8;
                break;
    }
    
    switch(parity)
    {
        default:
        case 'N':
        case 'n':
        {
            new_cfg.c_cflag &= ~PARENB;    
            new_cfg.c_iflag &= ~INPCK;     
        }
        break;

        case 'o':
        case 'O':
        {
            new_cfg.c_cflag |= (PARODD | PARENB); 
            new_cfg.c_iflag |= INPCK;     
        }
        break;

        case 'e':
        case 'E':
        {
            new_cfg.c_cflag |= PARENB;
            new_cfg.c_cflag &= ~PARODD;    
            new_cfg.c_iflag |= INPCK;
        }
        break;

        case 's':
        case 'S':
        {
            new_cfg.c_cflag &= ~PARENB;
            new_cfg.c_cflag &= ~CSTOPB;
        }
        break;
    }

    switch(stopbits)
    {
        default:
        case '1':
        {
            new_cfg.c_cflag &= ~CSTOPB;
        }
        break;

        case '2':
        {
            new_cfg.c_cflag |= CSTOPB;
        }
        break;
    }

    /*set wait time*/
    new_cfg.c_cc[VTIME] = 0;
    new_cfg.c_cc[VMIN]  = 1;

    tcflush(ComFd, TCIFLUSH);  
    if((tcsetattr(ComFd, TCSANOW, &new_cfg)) < 0)
    {
        perror("tcsetattr");
        return -1;
    }
    printf("Open and Set serial ok,%d\n",ComFd);
    return ComFd;	
}

int Serialcom::SerialcomClose()
{
	close(ComFd);
	stat = 0;
	return stat;
}	
	
/*> 0 有文件描述符可讀, =0 超時 < 0 無描述符可讀*/
int Serialcom::CheckSerialcomData()
{
	fd_set rset;
	struct timeval	tv;
	int ret;

	FD_ZERO(&rset);
	FD_SET(ComFd, &rset);

	tv.tv_sec= usec;
	tv.tv_usec = 0;

	ret = select(ComFd+1, &rset, NULL, NULL, &tv);
	if (ret>0)
		printf("Check have data\n");
	return ret;
}

int Serialcom::SerialcomRead(char* pbuffer,int dataLen)
{
	int ret;
	ret = read(ComFd,pbuffer,dataLen);
	
	return ret;
}	

int Serialcom::SerialcomWrite(char* pbuffer,int dataLen)
{
	int ret;
	ret = write(ComFd,pbuffer,dataLen);
	if(ret > 0)	
		printf("SerialcomWrite pbuffer = %s\n",pbuffer);
	return ret;	
}

};#endif


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章