⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serial.c

📁 这是pxa270的RS485驱动程序
💻 C
字号:
/* * Program:     serial.c * Author:      Paul Dean * Version:     0.0.3 * Date:        2002-02-19 * Description: To provide underlying serial port function, *              for high level applications. **/#include <termios.h>            /* tcgetattr, tcsetattr */#include <stdio.h>              /* perror, printf, puts, fprintf, fputs */#include <unistd.h>             /* read, write, close */#include <fcntl.h>              /* open */#include <sys/signal.h>#include <sys/types.h>#include <string.h>             /* bzero, memcpy */#include <limits.h>             /* CHAR_MAX */#include "serial.h"/*  * Decription for TIMEOUT_SEC(buflen,baud); * baud bits per second, buflen bytes to send. * buflen*20 (20 means sending an octect-bit data by use of the maxim bits 20) * eg. 9600bps baudrate, buflen=1024B, then TIMEOUT_SEC = 1024*20/9600+1 = 3  * don't change the two lines below unless you do know what you are doing.*/#define TIMEOUT_SEC(buflen,baud) (buflen*20/baud+2)#define TIMEOUT_USEC 0#define CH_TO_WAIT 5#define CH_BITS 11#define BUFFER_LEN  1024    /* sendfile() */static INT32    fd;             //File descriptor for the portstatic struct termios termios_old, termios_new;static fd_set   fs_read, fs_write;static struct timeval tv_timeout;// static struct sigaction sigaction_io;   /* definition of signal action */// static int      SetPortSig ();// static void     signal_handler_IO (int status);static void     set_baudrate (INT32);static INT32    get_baudrate ();static void     set_data_bit (INT32 databit);static INT32    baudrate2Bxx (INT32 baudrate);static INT32    Bxx2baudrate (INT32 _baudrate);static INT32    set_port_attr (                             INT32 baudrate, 		//                             INT32 databit,                             const char *stopbit,                              char parity);static void     set_stopbit (const char *stopbit);static void     set_parity (char parity);/* Open serial port ComPort at baudrate baud rate. */INT32 OpenComPort (INT32 ComPort, INT32 baudrate, INT32 databit,                   const char *stopbit, char parity){    char           *pComPort;    INT32           retval;    switch (ComPort) {    case 0:        pComPort = "/dev/ttyS0";        break;    case 1:        pComPort = "/dev/ttyS1";        break;    case 2:        pComPort = "/dev/ttyS2";        break;    case 3:        pComPort = "/dev/ttyS3";        break;    case 4:        pComPort = "/dev/ttyS4";        break;    case 5:        pComPort = "/dev/ttyS5";        break;    case 6:        pComPort = "/dev/ttyS6";        break;    case 7:        pComPort = "/dev/ttyS7";        break;    default:        pComPort = "/dev/ttyS0";        break;    }    fd = open (pComPort, O_RDWR | O_NOCTTY); // | O_NONBLOCK);    if (-1 == fd) {        fprintf (stderr, "cannot open port %s\n", pComPort);        return (-1);    }    printf("comport fd = %d\n", fd);    tcgetattr (fd, &termios_old);       /* save old termios value */    /* 0 on success, -1 on failure */    retval = set_port_attr (baudrate, databit, stopbit, parity);    if (-1 == retval) {        fprintf (stderr, "\nport %s cannot set baudrate at %d\n", pComPort,                 baudrate);    }    return (retval);}/* close serial port by use of file descriptor fd */void CloseComPort (){    /* flush output data before close and restore old attribute */    tcsetattr (fd, TCSADRAIN, &termios_old);    close (fd);}int getPortFd(){    return fd;}INT32 ReadComPort (void *data, INT32 datalength){    INT32           retval = 0;    FD_ZERO (&fs_read);    FD_SET (fd, &fs_read);    tv_timeout.tv_sec = TIMEOUT_SEC (datalength, get_baudrate ());    tv_timeout.tv_usec = TIMEOUT_USEC;    retval = select (fd + 1, &fs_read, NULL, NULL, &tv_timeout);    if (retval > 0) {        retval = read (fd, data, datalength);        return (retval);    }    else {        if (0 == retval ) {            return (0);        }else{            return (-1);        }    }}INT32 ReadComPortA (void *data, INT32 datalength){    INT32           retval = 0;    int bytes_read;    int readlen;    /**     * caculate the time of 5 characters and get the maxim     * with 3ms and 5 ch's time    */    tv_timeout.tv_sec = 0;    tv_timeout.tv_usec = ( (CH_TO_WAIT * CH_BITS) * (1000000/get_baudrate()));    //printf("port read timeout:%dus\n",tv_timeout.tv_usec);    bytes_read = 0;    while(bytes_read<datalength){        tv_timeout.tv_sec = 0;        tv_timeout.tv_usec = ( (CH_TO_WAIT * CH_BITS) * (1000000/get_baudrate()));        FD_ZERO (&fs_read);        FD_SET (fd, &fs_read);        retval = select (fd + 1, &fs_read, NULL, NULL, &tv_timeout);        if ( retval >0 ) {            readlen = read (fd, (data+bytes_read), datalength);            bytes_read += readlen;        } else            return (bytes_read==0?-1:bytes_read);    }    return -1;}/*  * Write datalength bytes in buffer given by UINT8 *data, * return value: bytes written * Nonblock mode*/INT32 WriteComPort (UINT8 * data, INT32 datalength){    INT32           retval, len = 0, total_len = 0;    FD_ZERO (&fs_write);    FD_SET (fd, &fs_write);    tv_timeout.tv_sec = TIMEOUT_SEC (datalength, get_baudrate ());    tv_timeout.tv_usec = TIMEOUT_USEC;    for (total_len = 0, len = 0; total_len < datalength;) {        retval = select (fd + 1, NULL, &fs_write, NULL, &tv_timeout);        if (retval) {            len = write (fd, &data[total_len], datalength - total_len);            if (len > 0) {                total_len += len;            }        }        else {            tcflush (fd, TCOFLUSH);     /* flush all output data */            break;        }    }    return (total_len);}/* get serial port baudrate */static INT32 get_baudrate (){    return (Bxx2baudrate (cfgetospeed (&termios_new)));}/* set serial port baudrate by use of file descriptor fd */static void set_baudrate (INT32 baudrate){    termios_new.c_cflag = baudrate2Bxx (baudrate);  /* set baudrate */}static void set_data_bit (INT32 databit){    termios_new.c_cflag &= ~CSIZE;    switch (databit) {    case 8:        termios_new.c_cflag |= CS8;        break;    case 7:        termios_new.c_cflag |= CS7;        break;    case 6:        termios_new.c_cflag |= CS6;        break;    case 5:        termios_new.c_cflag |= CS5;        break;    default:        termios_new.c_cflag |= CS8;        break;    }}static void set_stopbit (const char *stopbit){    if (0 == strcmp (stopbit, "1")) {        termios_new.c_cflag &= ~CSTOPB; /* 1 stop bit */    }    else if (0 == strcmp (stopbit, "1.5")) {        termios_new.c_cflag &= ~CSTOPB; /* 1.5 stop bits */    }    else if (0 == strcmp (stopbit, "2")) {        termios_new.c_cflag |= CSTOPB;  /* 2 stop bits */    }    else {        termios_new.c_cflag &= ~CSTOPB; /* 1 stop bit */    }}static void set_parity (char parity){    switch (parity) {    case 'N':                  /* no parity check */        termios_new.c_cflag &= ~PARENB;        break;    case 'E':                  /* even */        termios_new.c_cflag |= PARENB;        termios_new.c_cflag &= ~PARODD;        break;    case 'O':                  /* odd */        termios_new.c_cflag |= PARENB;        termios_new.c_cflag |= ~PARODD;        break;    default:                   /* no parity check */        termios_new.c_cflag &= ~PARENB;        break;    }}static INT32 set_port_attr (                          INT32 baudrate,        // 1200 2400 4800 9600 .. 115200                          INT32 databit,           // 5, 6, 7, 8                          const char *stopbit,  //  "1", "1.5", "2"                          char parity)              // N(o), O(dd), E(ven){    bzero(&termios_new, sizeof (termios_new));	cfmakeraw (&termios_new);	set_baudrate (baudrate);    termios_new.c_cflag |= CLOCAL | CREAD;      /* | CRTSCTS */    set_data_bit (databit);    set_parity (parity);    set_stopbit (stopbit);    termios_new.c_oflag 			= 0;    termios_new.c_lflag 			|= 0;    termios_new.c_oflag 			&= ~OPOST;    termios_new.c_cc[VTIME] 	= 1;        /* unit: 1/10 second. */    termios_new.c_cc[VMIN] 		= 255; /* minimal characters for reading */    tcflush (fd, TCIFLUSH);	return (tcsetattr (fd, TCSANOW, &termios_new));}/** * baudrate xxx to Bxxx *  * @@param baudrate xxx *  * @@return  */static INT32 baudrate2Bxx (INT32 baudrate){    switch (baudrate) {    case 0:        return (B0);    case 50:        return (B50);    case 75:        return (B75);    case 110:        return (B110);    case 134:        return (B134);    case 150:        return (B150);    case 200:        return (B200);    case 300:        return (B300);    case 600:        return (B600);    case 1200:        return (B1200);    case 2400:        return (B2400);    case 9600:        return (B9600);    case 19200:        return (B19200);    case 38400:        return (B38400);    case 57600:        return (B57600);    case 115200:        return (B115200);    default:        return (B9600);    }}/** * get boundrate from Bxxx *  * @@param baudrate Bxxx refers to bound rate *  * @@return  */static INT32 Bxx2baudrate (INT32 _baudrate){/* reverse baudrate */    switch (_baudrate) {    case B0:        return (0);    case B50:        return (50);    case B75:        return (75);    case B110:        return (110);    case B134:        return (134);    case B150:        return (150);    case B200:        return (200);    case B300:        return (300);    case B600:        return (600);    case B1200:        return (1200);    case B2400:        return (2400);    case B9600:        return (9600);    case B19200:        return (19200);    case B38400:        return (38400);    case B57600:        return (57600);    case B115200:        return (115200);    default:        return (9600);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -