linux 串口 控制 鼠标,linux下串口控制

  • Post author:
  • Post category:linux


/*  本程序符合GPL条约

*  Beneboy 2003-5-16

*/

#include               // printf

#include               // open

#include              // bzero

#include              // exit

#include           // times

#include           // pid_t

#include   //termios, tcgetattr(), tcsetattr()

#include

#include           // ioctl

#include “MyCom.h”

#define TTY_DEV “/dev/ttyS” //端口路径

//接收超时

#define TIMEOUT_SEC(buflen,baud) (buflen*20/baud+2)

#define TIMEOUT_USEC 0

/*******************************************

* 获得端口名称

********************************************/

char *get_ptty(pportinfo_t pportinfo)

{

char *ptty;

switch(pportinfo->tty){

case ‘0’:{

ptty = TTY_DEV”0″;

}break;

case ‘1’:{

ptty = TTY_DEV”1″;

}break;

case ‘2’:{

ptty = TTY_DEV”2″;

}break;

}

return(ptty);

}

/*******************************************

* 波特率转化转换函数

********************************************/

int convbaud(unsigned long int baudrate)

{

switch(baudrate){

case 2400:

return B2400;

case 4800:

return B4800;

case 9600:

return B9600;

case 19200:

return B19200;

case 38400:

return B38400;

case 57600:

return B57600;

case 115200:

return B115200;

default:

return B9600;

}

}

/*******************************************

* Setup comm attr

* fdcom: 串口文件描述符, pportinfo: 待设置的端口信息s

*

********************************************/

int PortSet(int fdcom, const pportinfo_t pportinfo)

{

struct termios termios_old, termios_new;

int  baudrate, tmp;

char databit, stopbit, parity, fctl;

bzero(&termios_old, sizeof(termios_old));

bzero(&termios_new, sizeof(termios_new));

cfmakeraw(&termios_new);

tcgetattr(fdcom, &termios_old);   //get the serial port attributions

/*————设置端口属性—————-*/

//baudrates

baudrate = convbaud(pportinfo -> baudrate);

cfsetispeed(&termios_new, baudrate);  //填入串口输入端波特率

cfsetospeed(&termios_new, baudrate);  //填入串口输出端波特率

termios_new.c_cflag |= CLOCAL;   //控制模式, 保证程序不会成为端口的占有者

termios_new.c_cflag |= CREAD;   //控制模式, 使能端口读取输入的数据

// 控制模式, flow control

fctl = pportinfo-> fctl;

switch(fctl){

case ‘0’:{

termios_new.c_cflag &= ~CRTSCTS;  //no flow control

}break;

case ‘1’:{

termios_new.c_cflag |= CRTSCTS;   //hardware flow control

}break;

case ‘2’:{

termios_new.c_iflag |= IXON | IXOFF |IXANY; //software flow control

}break;

}

//控制模式, data bits

termios_new.c_cflag &= ~CSIZE;  //控制模式, 屏蔽字符大小位

databit = pportinfo -> databit;

switch(databit){

case ‘5’:

termios_new.c_cflag |= CS5;

case ‘6’:

termios_new.c_cflag |= CS6;

case ‘7’:

termios_new.c_cflag |= CS7;

default:

termios_new.c_cflag |= CS8;

}

//控制模式 parity check

parity = pportinfo -> parity;

switch(parity){

case ‘0’:{

termios_new.c_cflag &= ~PARENB;  //no parity check

}break;

case ‘1’:{

termios_new.c_cflag |= PARENB;  //odd check

termios_new.c_cflag &= ~PARODD;

}break;

case ‘2’:{

termios_new.c_cflag |= PARENB;  //even check

termios_new.c_cflag |= PARODD;

}break;

}

//控制模式, stop bits

stopbit = pportinfo -> stopbit;

if(stopbit == ‘2’){

termios_new.c_cflag |= CSTOPB; //2 stop bits

}

else{

termios_new.c_cflag &= ~CSTOPB; //1 stop bits

}

//other attributions default

termios_new.c_oflag &= ~OPOST;   //输出模式, 原始数据输出

termios_new.c_cc[VMIN]  = 1;   //控制字符, 所要读取字符的最小数量

termios_new.c_cc[VTIME] = 1;   //控制字符, 读取第一个字符的等待时间,  unit: (1/10)second

tcflush(fdcom, TCIFLUSH);   //溢出的数据可以接收,但不读

tmp = tcsetattr(fdcom, TCSANOW, &termios_new); //设置新属性, TCSANOW: 所由改变立即生效

tcgetattr(fdcom, &termios_old);

return(tmp);

}

/*******************************************

* Open serial port

* tty: 端口号 ttyS0, ttyS1, ….

* 返回值为串口文件描述符

********************************************/

int PortOpen(pportinfo_t pportinfo)

{

int fdcom; //串口文件描述符

char *ptty;

ptty = get_ptty(pportinfo);

//fdcom = open(ptty, O_RDWR | O_NOCTTY | O_NONBLOCK | O_NDELAY);

fdcom = open(ptty, O_RDWR | O_NOCTTY | O_NONBLOCK);

return (fdcom);

}

/*******************************************

* Close serial port

********************************************/

void PortClose(int fdcom)

{

close(fdcom);

}

/********************************************

* send data

* fdcom: 串口描述符, data: 待发送数据, datalen: 数据长度

* 返回实际发送长度

*********************************************/

int PortSend(int fdcom, char *data, int datalen)

{

int len = 0;

len = write(fdcom, data, datalen); //实际写入的长度

if(len == datalen){

return (len);

}

else{

tcflush(fdcom, TCOFLUSH);

return -1;

}

}

/*******************************************

* receive data

* 返回实际读入的字节数

*

********************************************/

int PortRecv(int fdcom, char *data, int datalen, int baudrate)

{

int readlen, fs_sel;

fd_set fs_read;

struct timeval tv_timeout;

FD_ZERO(&fs_read);

FD_SET(fdcom, &fs_read);

tv_timeout.tv_sec = TIMEOUT_SEC(datalen, baudrate);

tv_timeout.tv_usec = TIMEOUT_USEC;

fs_sel = select(fdcom+1, &fs_read, NULL, NULL, &tv_timeout);

if(fs_sel){

readlen = read(fdcom, data, datalen);

return(readlen);

}

else{

return(-1);

}

return (readlen);

}

//*************************Test*********************************

int main(int argc, char *argv[])

{

int fdcom, i, SendLen, RecvLen;

struct termios termios_cur;

char RecvBuf[256];

char writeBuf[256];

portinfo_t portinfo ={

‘0’,                          // print prompt after receiving

9600,                       // baudrate: 9600

‘8’,                          // databit: 8

‘0’,                          // debug: off

‘0’,                          // echo: off

‘2’,                          // flow control: software

‘0’,                          // default tty: COM1

‘0’,                          // parity: none

‘1’,                          // stopbit: 1

0                           // reserved

};

if(argc != 2){

printf(“Usage: \n”);

printf(”   eg:”);

printf(”        MyPort 0″);

exit(-1);

}

fdcom = PortOpen(&portinfo);

if(fdcom<0){

printf(“Error: open serial port error.\n”);

exit(1);

}

PortSet(fdcom, &portinfo);

while(1)

if(atoi(argv[1]) == 0)

{

//send data

//for(i=0; i<1000; i++)

{

//fgets(writeBuf,256,stdin);

scanf(“%s”,writeBuf);

SendLen = PortSend(fdcom, writeBuf, strlen(writeBuf));

if(SendLen>0)

{

//printf(“send data %s”, writeBuf);

}

else

{

printf(“Error: send failed.\n”);

}

if(strncmp(writeBuf,”exit”,4)==0)

break;

sleep(1);

}

//PortClose(fdcom);

}

else

{

//for(;;)

{

RecvLen = PortRecv(fdcom, RecvBuf, 256, portinfo.baudrate);

if(RecvLen>0)

{

/*for(i=0; i

{

printf(“Receive data No %d is %x.\n”, i, RecvBuf[i]);

}//*/

RecvBuf[RecvLen] = ‘\0’;

printf(“read data %s\n”,RecvBuf);

if(strncmp(RecvBuf,”exit”,4)==0)

break;

}

else

{

//printf(“Error: receive error.\n”);

}

sleep(1);

}

}

PortClose(fdcom);

return 0;

}