Linux串口通信中一种接收不到数据的问题的解决
这个奇怪的问题当时之所以没有被发现出来,是因为在这之前,曾经打开过一次minicom。后来实验表明,如果打开过一次minicom,哪怕打开又关闭的话,再次运行上文中的串口读写程序就没有问题了。但是重启机器之后,错误又出现了:只要不运行minicom一下,程序读取总是会有问题。
为了查找错误究竟是在什么地方,分别在刚刚开机、运行过一次自己编写的串口程序、运行过一次minicom这三种情况下使用命令stty -a < /dev/ttyS0查看了COM1的相关参数。然后主要根据自己的读取程序和minicom对串口的设置差异进行了相应的修改,现将读取程序的全部贴在下面。经过修改后,该程序运行之后的/dev/ttyS0的环境参数与直接运行minicom后/dev/ttyS0的环境参数完全相同。
注:程序中红色部分是与 文中的程序相比加入的主要内容。
/*********************************** read_serial ************************************/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <time.h>
#include <stdlib.h>
#define FALSE -1
#define TRUE 0
void set_speed(int, int);
int set_Parity(int,int,int,int);
int main()
{
int fd,flag,rd_num=0;
struct termios term;
struct timeval timeout;
speed_t baud_rate_i,baud_rate_o;
char recv_buf[20];
fd=open("/dev/ttyS0",O_RDWR|O_NONBLOCK);
if(fd==-1)
printf("can not open the COM1!\n");
else
printf("open COM1 ok!\n");
flag=tcgetattr(fd,&term);
baud_rate_i=cfgetispeed(&term);
baud_rate_o=cfgetospeed(&term);
printf("设置之前的输入波特率是%d,输出波特率是%d\n",baud_rate_i,baud_rate_o);
set_speed(fd,1200);
flag=tcgetattr(fd,&term);
baud_rate_i=cfgetispeed(&term);
baud_rate_o=cfgetospeed(&term);
printf("设置之后的输入波特率是%d,输出波特率是%d\n",baud_rate_i,baud_rate_o);
if (set_Parity(fd,8,1,'N')== FALSE)
{
printf("Set Parity Error\n");
exit(1);
}
int transfer_started=0;
int i=0;
while(1)
{
rd_num=read(fd,recv_buf,sizeof(recv_buf));
timeout.tv_sec=0;
timeout.tv_usec=200000;
if(rd_num>0)
{
printf("%d(间隔%4.3fs):we can read \"%s\" from the COM1,total:%d characters.\n",++i,timeout.tv_sec+timeout.tv_usec*0.000001,recv_buf,rd_num);
transfer_started=1;
}
else
printf("%d(间隔%4.3fs):read fail! rd_num=%d。本次数据传输%s\n",++i,timeout.tv_sec+timeout.tv_usec*0.000001,rd_num,transfer_started==1?"已经结束":"尚未开始");
// sleep(1); 粗糙定时
select(0,NULL,NULL,NULL,&timeout);/*精确定时*/
}
}
int speed_arr[] = {B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300};
int name_arr[] = {115200, 38400, 19200, 9600, 4800, 2400, 1200, 300};
void set_speed(int fd, int speed){
unsigned int i;
int status;
struct termios Opt;
tcgetattr(fd, &Opt);
for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++) {
if (speed == name_arr[i]) {
tcflush(fd, TCIOFLUSH);
cfsetispeed(&Opt, speed_arr[i]);
cfsetospeed(&Opt, speed_arr[i]);
status = tcsetattr(fd, TCSANOW, &Opt);
if (status != 0) {
perror("tcsetattr fd1");
return;
}
tcflush(fd,TCIOFLUSH);
}
}
}
/**
*@brief 设置串口数据位,停止位和效验位
*@param fd 类型 int 打开的串口文件句柄*
*@param databits 类型 int 数据位 取值 为 7 或者8*
*@param stopbits 类型 int 停止位 取值为 1 或者2*
*@param parity 类型 int 效验类型 取值为N,E,O,,S
*/
int set_Parity(int fd,int databits,int stopbits,int parity)
{
struct termios options;
if ( tcgetattr( fd,&options) != 0)
{
perror("SetupSerial 1");
return(FALSE);
}
options.c_cflag &= ~CSIZE;
switch (databits) /*设置数据位数*/
{
case 7:
options.c_cflag |= CS7;
break;
case 8:
options.c_cflag |= CS8;
break;
default:
fprintf(stderr,"Unsupported data size\n");
return (FALSE);
}
switch (parity)
{
case 'n':
case 'N':
// options.c_cflag &= ~PARENB; /* Clear parity enable */
// options.c_iflag &= ~INPCK; /* Enable parity checking */
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/
options.c_oflag &= ~OPOST; /*Output*/
break;
case 'o':
case 'O':
options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/
options.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 'e':
case 'E':
options.c_cflag |= PARENB; /* Enable parity */
options.c_cflag &= ~PARODD; /* 转换为偶效验*/
options.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 'S':
case 's': /*as no parity*/
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
break;
default:
fprintf(stderr,"Unsupported parity\n");
return (FALSE);
}
/* 设置停止位*/
switch (stopbits)
{
case 1:
options.c_cflag &= ~CSTOPB;
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default:
fprintf(stderr,"Unsupported stop bits\n");
return (FALSE);
}
/* Set input parity option */
if ((parity != 'n')&&(parity != 'N'))
options.c_iflag |= INPCK;
options.c_cc[VTIME] = 5; // 0.5 seconds
options.c_cc[VMIN] = 1;
options.c_cflag &= ~HUPCL;
options.c_iflag &= ~INPCK;
options.c_iflag |= IGNBRK;
options.c_iflag &= ~ICRNL;
options.c_iflag &= ~IXON;
options.c_lflag &= ~IEXTEN;
options.c_lflag &= ~ECHOK;
options.c_lflag &= ~ECHOCTL;
options.c_lflag &= ~ECHOKE;
options.c_oflag &= ~ONLCR;
tcflush(fd,TCIFLUSH); /* Update the options and do it NOW */
if (tcsetattr(fd,TCSANOW,&options) != 0)
{
perror("SetupSerial 3");
return (FALSE);
}
return (TRUE);
}
这样的话,读程序就可以直接接收到串口过来的数据,而不需要先运行一次minicom了。
Linux串口通信中一种接收不到数据的问题的解决的更多相关文章
- 解决Postman发送post数据但是Node.js中req.body接收不到数据的问题[已解决]
之前编写后台接口,测试数据都是使用的Postman,相当的方便,之前也一直使用get方法,编写Node.js一直没有问题,但是由于要编写一个注册/登陆的功能,所以发送的post数据,后台的逻辑已经编写 ...
- c#中实现串口通信的几种方法
c#中实现串口通信的几种方法 通常,在C#中实现串口通信,我们有四种方法: 第一:通过MSCOMM控件这是最简单的,最方便的方法.可功能上很难做到控制自如,同时这个控件并不是系统本身所带,所以还得注册 ...
- 串口通信中ReadFile和WriteFile的超时详解!
源:串口通信中ReadFile和WriteFile的超时详解! 在用ReadFile和WriteFile读写串行口时,需要考虑超时问题.如果在指定的时间内没有读出或写入指定数量的字符,那么ReadFi ...
- Qt 串口通信之使用16进制发送数据的转换方式
Qt 串口通信之使用16进制发送数据的转换方式 一 概述 有时候在做上位机串口通讯时,经常需要将字符串转成16进制的形式作为发送,借此分析记录一下. 二 需求分析 //假设需要转换的字符:如下 QSt ...
- Java实现RS485串口通信,发送和接收数据进行解析
最近项目有一个空气检测仪,需要得到空气检测仪的实时数据,保存到数据库当中.根据了解得到,硬件是通过rs485进行串口通讯的,需要发送16进制命令给仪器,然后通过轮询来得到数据. 需要先要下载RXTX的 ...
- 串口通信中,QString 、QByteArray 转化需要注意的问题
在做串口通信的时候,其中犯了一个错误.在此记录一下:QT中串口通信接到收据和发送数据的接口如下: QByteArray QIODevice::readAll()//接受数据 qint64 QIODev ...
- 嵌入式linux串口通信自发自收测试程序
/*串口自收自发程序主函数*/#include"uart_api.h"int main(){ int fd; char buff[BUFFER_SIZE]; char buff2 ...
- linux串口通信 接收信息不完整 读取不全
类似这种 ready.o是我用来读取串口信息的一个程序 执行结果如下: [root@localhost testPlc]# ./ready.o 0 02 1 30 2 30 3 46 4 46 5 3 ...
- Linux进程通信的几种方式总结
进程通信的目的 数据传输 一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几M字节之间 共享数据 多个进程想要操作共享数据,一个进程对共享数据 通知事 一个进程需要向另一个或一组进程发 ...
随机推荐
- UNIX&Linux发展图谱
来自为知笔记(Wiz)
- 【Nginx】事件驱动框架和异步处理
Nginx对请求的处理是通过事件触发的,模块作为事件消费者,仅仅能被事件收集.分发器调用.这与传统的Webserver是不同的. 传统的Webserver下,一个请求由一个进程消费.请求在建立连接后将 ...
- USACO 1.2 Milking Cows (枚举)
标记数组(哈希) 1e6的范围,开一个char数组全然能够,有人为1,无人为0,注意边界就可以.最后线性扫描就可以. 时间复杂度,应该是O(n),n为最后结束的时间. 缺点就是--比較慢 /* ID: ...
- C++11 并发指南一(C++11 多线程初探)(转)
引言 C++11 自2011年发布以来已经快两年了,之前一直没怎么关注,直到最近几个月才看了一些 C++11 的新特性,今后几篇博客我都会写一些关于 C++11 的特性,算是记录一下自己学到的东西吧, ...
- 浅谈PropertyChanged是如何被初始化的?
http://www.cnblogs.com/wpcockroach/p/3909081.html
- 【Sprint3冲刺之前】项目完成时间表
Sprint2冲刺成果——项目完成时间表 项目完成时间表 经过Sprint2小组总结会议的探讨,我们决定一起约定项目alpha版本,beta版本,release版本的发布时间,发布形式及预计完成效果 ...
- 【每日Scrum】第四天(4.14) TD学生助手Sprint1站立会议
TD学生助手Sprint1站立会议(4.14) 任务看板 站立会议内容 组员 昨天 今天 困难 签到 刘铸辉 (组长) 今天早晨静姐调整了下界面和配色,下午和宝月兄一起做了GPS功能显示,暂时只能显示 ...
- Android中Environment与StatFs获取系统/SDCard存储空间大小
近期想起Android开发的知识.好久没有使用了,都忘得几乎相同了,今天查看了一会资料往回捡捡,顺便写下来帮助一下须要的同学. 首先讲述一下Environment与StatFs这两个类,然后介绍它们的 ...
- 看完此文,妈妈还会担心你docker入不了门?
本文在个人技术博客不同步发布,详情可猛戳 亦可扫描屏幕右侧二维码关注个人公众号,公众号内有个人联系方式,等你来撩... 上周对象突然心血来潮说想养个小宠物,我问想养啥她又说随便,你看着办!!!这我 ...
- RESTful API 设计原则
http://www.ruanyifeng.com/blog/2014/05/restful_api.html http://www.ruanyifeng.com/blog/2011/09/restf ...