📄 rs232_fn.c
字号:
#include <stdio.h>#include <string.h>#include <errno.h>#include <termios.h>#include <sys/time.h>#include <sys/types.h>#include <sys/ioctl.h>#include <unistd.h>#include <fcntl.h>#include <stdarg.h>#include "rs232_fn.h"//#define DEBUG 1//#define DEBUG_COUNT 0//#define WITHOUT_CFSETSPEED#ifdef WITHOUT_CFSETSPEEDstruct rs232_speed_struct{ speed_t value; speed_t internal;};static const struct rs232_speed_struct rs232_speeds[] = {#ifdef B0 { 0, B0 },#endif#ifdef B50 { 50, B50 },#endif#ifdef B75 { 75, B75 },#endif#ifdef B110 { 110, B110 },#endif#ifdef B134 { 134, B134 },#endif#ifdef B150 { 150, B150 },#endif#ifdef B200 { 200, B200 },#endif#ifdef B300 { 300, B300 },#endif#ifdef B600 { 600, B600 },#endif#ifdef B1200 { 1200, B1200 },#endif#ifdef B1200 { 1200, B1200 },#endif#ifdef B1800 { 1800, B1800 },#endif#ifdef B2400 { 2400, B2400 },#endif#ifdef B4800 { 4800, B4800 },#endif#ifdef B9600 { 9600, B9600 },#endif#ifdef B19200 { 19200, B19200 },#endif#ifdef B38400 { 38400, B38400 },#endif#ifdef B57600 { 57600, B57600 },#endif#ifdef B76800 { 76800, B76800 },#endif#ifdef B115200 { 115200, B115200 },#endif#ifdef B153600 { 153600, B153600 },#endif#ifdef B230400 { 230400, B230400 },#endif#ifdef B307200 { 307200, B307200 },#endif#ifdef B460800 { 460800, B460800 },#endif };/* Set both the input and output baud rates stored in *TERMIOS_P to SPEED. */intrs232_cfsetspeed (struct termios *termios_p, speed_t speed){ size_t cnt; for (cnt = 0; cnt < sizeof (rs232_speeds) / sizeof (rs232_speeds[0]); ++cnt) if (speed == rs232_speeds[cnt].internal) { cfsetispeed (termios_p, speed); cfsetospeed (termios_p, speed); return 0; } else if (speed == rs232_speeds[cnt].value) { cfsetispeed (termios_p, rs232_speeds[cnt].internal); cfsetospeed (termios_p, rs232_speeds[cnt].internal); return 0; } /*__set_errno (EINVAL);*/ return -1;}#endif /* WITHOUT_CFSETSPEED *//* Set right mode and speed for RS232 interface *//* baud can be either speed in character per second or special Bxxxx constant */int rs232_setmode(int fd, int baud, int mode, int flowc){ struct termios ts; /* Flush input and output queues. */ if (tcflush(fd, TCIOFLUSH) != 0) { fprintf(stderr,"Error in tcflush\n"); return -1; } /* Fetch the current terminal parameters. */ if (tcgetattr(fd, &ts) != 0) { fprintf(stderr,"Error in tcgetattr\n"); return -1; } /* Sets hardware control flags: */ /* 8 data bits */ /* Enable receiver */ /* Ignore CD (local connection) */ ts.c_cflag = CS8 | CREAD | CLOCAL; if(flowc&1){ /* Use RTS/CTS flow control */ ts.c_cflag |= CRTSCTS; /* CCTS_OFLOW | CRTS_IFLOW */ } ts.c_iflag = 0; ts.c_oflag = NL0 | CR0 | TAB0 | BS0 | VT0 | FF0; ts.c_lflag = 0; /* set right ispeed and ospeed */ #ifdef WITHOUT_CFSETSPEED if(rs232_cfsetspeed(&ts,baud)<0){ fprintf(stderr,"Error in rs232_cfsetspeed\n"); return -1; } #else /* WITHOUT_CFSETSPEED */ if(cfsetspeed(&ts,baud)<0){ fprintf(stderr,"Error in cfsetspeed\n"); return -1; } #endif /* WITHOUT_CFSETSPEED */ ts.c_cc[VINTR] = '\0'; ts.c_cc[VQUIT] = '\0'; ts.c_cc[VERASE] = '\0'; ts.c_cc[VKILL] = '\0'; ts.c_cc[VEOF] = '\0'; ts.c_cc[VTIME] = '\0'; ts.c_cc[VMIN] = 1; ts.c_cc[VSWTC] = '\0'; ts.c_cc[VSTART] = '\0'; ts.c_cc[VSTOP] = '\0'; ts.c_cc[VSUSP] = '\0'; ts.c_cc[VEOL] = '\0'; ts.c_cc[VREPRINT] = '\0'; ts.c_cc[VDISCARD] = '\0'; ts.c_cc[VWERASE] = '\0'; ts.c_cc[VLNEXT] = '\0'; ts.c_cc[VEOL2] = '\0'; /* Sets the new terminal parameters. */ if (tcsetattr(fd, TCSANOW, &ts) != 0) { fprintf(stderr,"Error in tcsetattr\n"); return -1; } return 0;}int rs232_sendch(int fd,unsigned char c){ if(write(fd, &c, 1) != 1){ fprintf(stderr,"Error in rs232_sendch\n"); return -1; } #if DEBUG printf("rs232_sendch 0x%02X ",c); #endif return c;}int rs232_recch(int fd){ unsigned char c; if (read(fd, &c, 1) != 1){ fprintf(stderr,"Error in rs232_recch\n"); return -1; } #if DEBUG printf("R:0x%02X '%c' ",c,c>=0x20?c:'?'); #endif return c;}int rs232_test(int fd,int time){ struct timeval tv; fd_set rfds; int x; tv.tv_sec = 0; tv.tv_usec = time; FD_ZERO(&rfds); FD_SET(fd, &rfds); x=select(fd + 1, &rfds, NULL, NULL, &tv); #if DEBUG printf("rs232_test %d ",x); #endif return x;}int rs232_recch_wait(int fd,int time){ int ret; int ch; ret=rs232_test(fd,time); if(ret<=0){ #if DEBUG printf("\nrs232_recch_wait: rs232_test failed\n"); #endif return -1; } ch=rs232_recch(fd); if(ch<0){ #if DEBUG printf("\nrs232_recch_wait: rs232_recch failed\n"); #endif return -1; } return ch;}int rs232_wait_delimit(int fd,char *delimit,int time){ int ret; int ch; do{ ret=rs232_test(fd,time); if(ret<=0){ #if DEBUG printf("\nrs232_wait_delimit: rs232_test failed\n"); #endif return -1; } ch=rs232_recch(fd); if(ch<0){ #if DEBUG printf("\nrs232_wait_delimit: rs232_recch failed\n"); #endif return -1; } }while(!strchr(delimit,ch)); return ch;}#define B_LEN 8int rs232_writem(int fd, int mode, char *data, int len){ char *p, *r, *e; int res; char chk[B_LEN]; int wcnt=0; #if DEBUG printf("\nrs232_writem: write len %d\n",len); #endif r=p=data; e=data+len; while(e!=r){ len=e-p; if(len>(B_LEN-(p-r))) len=B_LEN-(p-r); if(len){ if((res=write(fd,p,len))==-1){ #if DEBUG printf("\nrs232_writem: write failed\n"); #endif return -1; } p+=res; #if DEBUG printf("\nwrm: %d>%d \n",len,res); #endif } if(mode&RS232_SF_ECHO){ rs232_test(fd,10000); len=p-r; if(len>B_LEN) len=B_LEN; chk[0]='Y', res=read(fd,chk,len); if(res<0){ if((errno==EAGAIN)||(errno==EINTR)) if(wcnt<2) { wcnt++; continue; } #if DEBUG printf("\nrs232_writem: read failed %s (%d)\n", strerror(errno),errno); #endif return -2; } if(res){ wcnt = 0; if(memcmp(chk,r,res)){ #if DEBUG int i; printf("\nrs232_writem: compare failed\n"); for(i=0;i<res;i++){ if(chk[i]==r[i]) printf("%02X '%c' ",chk[i],chk[i]>=0x20?chk[i]:'?'); else printf("%02X!%02X '%c'!'%c' ",chk[i],r[i], chk[i]>=0x20?chk[i]:'?',r[i]>=0x20?r[i]:'?'); } printf("\n"); #endif return -3; } r+=res; #if DEBUG printf("res=%d\n",res); #endif } else { if(wcnt++>2) { #if DEBUG printf("\nrs232_writem: read failed %s (%d)\n", strerror(errno),errno); #endif return -4; } } } else r=p; } return r-data;}int rs232_readm(int fd, int time, char *data, int len){ int res; char *p=data; #if DEBUG printf("\nrs232_readm: read len %d\n",len); #endif while(len){ if(rs232_test(fd,time)<0){ #if DEBUG printf("\nrs232_readm: timeout\n"); #endif return -1; } res=read(fd,p,len); if(res<0){ if((errno==EAGAIN)||(errno==EINTR)) continue; #if DEBUG printf("\nrs232_readm: read failed\n"); #endif return -2; } p+=res; len-=res; } #if DEBUG printf("\nrs232_readm: received %d characters\n",p-data); #endif return p-data;}#define S_LEN 88int rs232_sendf(int fd, int mode, char *template, ...){ va_list ap; char s[S_LEN]; int cnt; va_start (ap, template); cnt=vsnprintf (s, S_LEN, template, ap); if(cnt>S_LEN) return -1; va_end (ap); return rs232_writem(fd, mode, s, cnt);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -