代码拉取完成,页面将自动刷新
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<unistd.h>
#include<assert.h>
#include<termios.h>
#include<string.h>
#include<sys/time.h>
#include<sys/types.h>
#include<errno.h>
static int ret;
static int fd;
/*
* 安全读写函数
*/
ssize_t safe_write(int fd, const void *vptr, size_t n)
{
size_t nleft;
ssize_t nwritten;
const char *ptr;
ptr = vptr;
nleft = n;
// printf("write:%s,len:%d\n",vptr,n );
while(nleft > 0)
{
if((nwritten = write(fd, ptr, nleft)) <= 0)
{
if(nwritten < 0&&errno == EINTR)
nwritten = 0;
else
return -1;
}
nleft -= nwritten;
ptr += nwritten;
}
return(n);
}
ssize_t safe_read(int fd,void *vptr,size_t n)
{
size_t nleft;
ssize_t nread;
char *ptr;
ptr=vptr;
nleft=n;
while(nleft > 0)
{
if((nread = read(fd,ptr,nleft)) < 0)
{
if(errno == EINTR)//被信号中断
nread = 0;
else
return -1;
}
else
if(nread == 0)
break;
nleft -= nread;
ptr += nread;
}
return (n-nleft);
}
int uart_open(int fd,const char *pathname)
{
assert(pathname);
/*打开串口*/
fd = open(pathname,O_RDWR|O_NOCTTY);
if(fd <0)
{
perror("Open UART failed!");
return -1;
}
/*清除串口非阻塞标志*/
// if(fcntl(fd,F_SETFL,0) < 0)
// {
// fprintf(stderr,"fcntl failed!\n");
// return -1;
// }
return fd;
}
int uart_set(int fd,int baude,int c_flow,int bits,char parity,int stop)
{
struct termios options;
bzero(&options, sizeof(options)); //clear options
/*获取终端属性*/
if(tcgetattr(fd,&options) < 0)
{
perror("tcgetattr error");
return -1;
}
//printf("btnset:%d\n",baude );
/*设置输入输出波特率,两者保持一致*/
switch(baude)
{
case 4800:
cfsetispeed(&options,B4800);
cfsetospeed(&options,B4800);
break;
case 9600:
cfsetispeed(&options,B9600);
cfsetospeed(&options,B9600);
break;
case 19200:
cfsetispeed(&options,B19200);
cfsetospeed(&options,B19200);
break;
case 38400:
cfsetispeed(&options,B38400);
cfsetospeed(&options,B38400);
break;
case 57600:
cfsetispeed(&options,B57600);
cfsetospeed(&options,B57600);
break;
case 115200:
cfsetispeed(&options,B115200);
cfsetospeed(&options,B115200);
break;
default:
fprintf(stderr,"Unkown baude!\n");
return -1;
}
// options.c_cflag |= (CS8 | CLOCAL | CREAD );
// options.c_cflag &= ~CRTSCTS;//¹Ø±ÕÓ²¼þÁ÷¿Ø 0
// options.c_iflag = IGNPAR;
// options.c_oflag &= ~OPOST; //启用输出处理
// tcflush(fd, TCIFLUSH); //clear data not read
// int err;
// err =tcsetattr(fd, TCSANOW, &options); //chang to use now
/*设置控制模式*/
options.c_cflag |= CLOCAL;//保证程序不占用串口
options.c_cflag |= CREAD;//保证程序可以从串口中读取数据
/*设置数据流控制*/
switch(c_flow)
{
case 0://不进行流控制
options.c_cflag &= ~CRTSCTS;
break;
case 1://进行硬件流控制
options.c_cflag |= CRTSCTS;
break;
case 2://进行软件流控制
options.c_cflag |= IXON|IXOFF|IXANY;
break;
default:
fprintf(stderr,"Unkown c_flow!\n");
return -1;
}
/*设置数据位*/
switch(bits)
{
case 5:
options.c_cflag &= ~CSIZE;//屏蔽其它标志位
options.c_cflag |= CS5;
break;
case 6:
options.c_cflag &= ~CSIZE;//屏蔽其它标志位
options.c_cflag |= CS6;
break;
case 7:
options.c_cflag &= ~CSIZE;//屏蔽其它标志位
options.c_cflag |= CS7;
break;
case 8:
options.c_cflag &= ~CSIZE;//屏蔽其它标志位
options.c_cflag |= CS8;
break;
default:
fprintf(stderr,"Unkown bits!\n");
return -1;
}
/*设置校验位*/
switch(parity)
{
/*无奇偶校验位*/
case 'n':
case 'N':
// options.c_cflag &= ~PARENB;//PARENB:产生奇偶位,执行奇偶校验
// options.c_cflag &= ~INPCK;//INPCK:使奇偶校验起作用
break;
/*设为空格,即停止位为2位*/
case 's':
case 'S':
options.c_cflag &= ~PARENB;//PARENB:产生奇偶位,执行奇偶校验
options.c_cflag &= ~CSTOPB;//CSTOPB:使用两位停止位
break;
/*设置奇校验*/
case 'o':
case 'O':
options.c_cflag |= PARENB;//PARENB:产生奇偶位,执行奇偶校验
options.c_cflag |= PARODD;//PARODD:若设置则为奇校验,否则为偶校验
options.c_cflag |= INPCK;//INPCK:使奇偶校验起作用
options.c_cflag |= ISTRIP;//ISTRIP:若设置则有效输入数字被剥离7个字节,否则保留全部8位
break;
/*设置偶校验*/
case 'e':
case 'E':
options.c_cflag |= PARENB;//PARENB:产生奇偶位,执行奇偶校验
options.c_cflag &= ~PARODD;//PARODD:若设置则为奇校验,否则为偶校验
options.c_cflag |= INPCK;//INPCK:使奇偶校验起作用
options.c_cflag |= ISTRIP;//ISTRIP:若设置则有效输入数字被剥离7个字节,否则保留全部8位
break;
default:
fprintf(stderr,"Unkown parity!\n");
return -1;
}
/*设置停止位*/
switch(stop)
{
case 1:
options.c_cflag &= ~CSTOPB;//CSTOPB:使用两位停止位
break;
case 2:
options.c_cflag |= CSTOPB;//CSTOPB:使用两位停止位
break;
default:
fprintf(stderr,"Unkown stop!\n");
return -1;
}
/*设置输出模式为原始输出*/
options.c_oflag &= ~OPOST;//OPOST:若设置则按定义的输出处理,否则所有c_oflag失效
/*设置本地模式为原始模式*/
options.c_lflag &= IGNPAR;//~(ICANON | ECHO | ECHOE | ISIG);
/*
*ICANON:允许规范模式进行输入处理
*ECHO:允许输入字符的本地回显
*ECHOE:在接收EPASE时执行Backspace,Space,Backspace组合
*ISIG:允许信号
*/
/*设置等待时间和最小接受字符*/
options.c_cc[VTIME] = 150;//可以在select中设置
options.c_cc[VMIN] = 0;//最少读取一个字符
/*如果发生数据溢出,只接受数据,但是不进行读操作*/
tcflush(fd,TCIFLUSH);
/*激活配置*/
if(tcsetattr(fd,TCSANOW,&options) < 0)
{
perror("tcsetattr failed");
return -1;
}
return 0;
}
int uart_read(int fd,char *r_buf,size_t len)
{
ssize_t cnt = 0;
fd_set rfds;
struct timeval time;
/*将文件描述符加入读描述符集合*/
FD_ZERO(&rfds);
FD_SET(fd,&rfds);
/*设置超时为15s*/
time.tv_sec = 15;
time.tv_usec = 0;
/*实现串口的多路I/O*/
ret = select(fd+1,&rfds,NULL,NULL,&time);
switch(ret)
{
case -1:
fprintf(stderr,"select error!\n");
return -1;
case 0:
fprintf(stderr,"time over!\n");
return -1;
default:
cnt = safe_read(fd,r_buf,len);
if(cnt == -1)
{
fprintf(stderr,"read error!\n");
return -1;
}
return cnt;
}
}
int uart_write(int fd,const char *w_buf,size_t len)
{
ssize_t cnt = 0;
cnt = safe_write(fd,w_buf,len);
if(cnt == -1)
{
fprintf(stderr,"write error!\n");
return -1;
}
return cnt;
}
int uart_close(int fd)
{
assert(fd);
close(fd);
/*可以在这里做些清理工作*/
return 0;
}
void init_ttySerial(int fd,int btn)
{
struct termios options;
bzero(&options, sizeof(options)); //clear options
cfsetispeed(&options,btn ); //set baudrate
cfsetospeed(&options, btn);
options.c_cflag |= (CS8 | CLOCAL | CREAD );
options.c_cflag &= ~CRTSCTS;//¹Ø±ÕÓ²¼þÁ÷¿Ø
options.c_iflag = IGNPAR;
options.c_oflag &= ~OPOST; //启用输出处理
tcflush(fd, TCIFLUSH); //clear data not read
int err;
err =tcsetattr(fd, TCSANOW, &options); //chang to use now
fprintf(stderr, "init tvsetattr:%d\n",err );
}
int serial_init(char *ttySx,int btn)
{
fd = uart_open(fd,ttySx);/*串口号/dev/ttySn,USB口号/dev/ttyUSBn*/
//init_ttySerial(fd,btn);
// if(fd == -1)
// {
// fprintf(stderr,"uart_open error\n");
// exit(EXIT_FAILURE);
// }
// //int uart_set(int fd,int baude,int c_flow,int bits,char parity,int stop)
if(uart_set(fd,btn,0,8,'N',1) == -1)
{
fprintf(stderr,"uart set failed!\n");
exit(EXIT_FAILURE);
}
printf("com:%s,btn:%d\n",ttySx,btn );
}
int uart_sendstr(char *str)
{
int len=0;
len =strlen(str);
char strcp[len+4];
memset(strcp,0,len+4);
strcpy(strcp,str);
len =strlen(strcp);
if(strcp[len-2]!= '\r')
{
if(strcp[len-1]=='\n')
{
strcp[len-1]='\0';
strcat(strcp,"\r\n");
}
else
{
if(strcp[len-1]!='\r')
strcat(strcp,"\r\n");
else
{
strcp[len-1]='\0';
strcat(strcp,"\r\n");
}
}
}
len = strlen(strcp);
ret = uart_write(fd,strcp,len);
if(ret == -1)
{
//fprintf(stderr,"uart write failed!\n");
exit(EXIT_FAILURE);
}
fprintf(stderr,"serial send:%s\n",str );
}
// char * right(char *dst,char *src, int n)
// {
// char *p = src;
// char *q = dst;
// int len = strlen(src);
// if(n>len) n = len;
// p += (len-n); /*从右边第n个字符开始,到0结束,很巧啊*/
// while(*(q++) = *(p++));
// return dst;
// }
int uart_readline(char *str)
{
char c[]="00000";
int len;
memset(str,0,sizeof(str));
while(1)
{
memset(c,0,4);
len=read(fd,c,1);
if(len > 0)
{
strcat(str,c);
}
else
{
usleep(2000);
continue;
}
if(c[0]=='\n')
{
if(str[strlen(str)-1]!='\r')
{
strcat(str,"\r\n");
}
else
{
strcat(str,c);
}
break;
}
if(strlen(str)>1000)
{
strcat(str,"\r\n");
break;
}
}
fprintf(stderr,"rev:%s\n",str );
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。