linux 串口 拼帧处理
串口每次read数据可能不是完整的数据,参照网上的代码,写了拼帧的代码#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <strings.h>
#include <sys/time.h>
#include <sys/types.h> int speed_arr[] = { B115200, B57600, B38400, B19200, B9600, B4800, B2400, B1200, B300};
int name_arr[] = { , , , , , , , , }; /**
*@brief Set Serial Port BitRate
*@param fd Type : int The File Description of Serial Port
*@param speed Type : int Serial Speed
*@return void
*/
void set_speed(int fd, int speed)
{
int i;
int status;
struct termios Opt;
tcgetattr(fd, &Opt);
for( i=; 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 != )
{
perror("tcsetattr fd");
return;
}
tcflush(fd,TCIOFLUSH);
}
}
} /**
*@brief Set Serial Port Databits, Stopbits and Parity.
*@param fd Type: int The File Description of Serial Port
*@param databits Type: int Databits 7 or 8
*@param stopbits Type: int Stopbits 1 or 2
*@param parity Type: int Parity Type: n,N,e,E,o,O,s,S
*/
int set_Parity(int fd, int databits, int parity, int stopbits)
{
struct termios options;
if ( tcgetattr( fd,&options) != )
{
perror("SetupSerial 1");
return(-);
}
options.c_cflag &= ~CSIZE;
switch (databits) /*Set Datebits*/
{
case :
options.c_cflag |= CS7;
break;
case :
options.c_cflag |= CS8;
break;
default:
fprintf(stderr,"Unsupported data size\n");
return(-);
} switch (parity) /*Set Parity*/
{
case 'n':
case 'N':
options.c_cflag &= ~PARENB; /* Clear parity enable */
options.c_iflag &= ~INPCK; /* Enable parity checking */
break;
case 'o':
case 'O':
options.c_cflag |= (PARODD | PARENB); /* Odd Checking*/
options.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 'e':
case 'E':
options.c_cflag |= PARENB; /* Enable parity */
options.c_cflag &= ~PARODD; /* Even Checking*/
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(-);
} switch (stopbits) /*Set Stobits*/
{
case :
options.c_cflag &= ~CSTOPB;
break;
case :
options.c_cflag |= CSTOPB;
break;
default:
fprintf(stderr,"Unsupported stop bits\n");
return(-);
}
/* Set input parity option */
if (parity != 'n')
options.c_iflag |= INPCK; /*以下两句添加后发送方可以不加回车换行,但是read读取不完整*/
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/
options.c_oflag &= ~OPOST; /*Output*/ //屏蔽功能: NL(换行)->CR(回车)、CR->NL、忽略输入回车
options.c_iflag &= ~(INLCR | ICRNL | IGNCR);
options.c_oflag &= ~(ONLCR | OCRNL); tcflush(fd,TCIFLUSH);
//未设置O_NONBLOCK或O_NDELAY
options.c_cc[VTIME] = ; /* Timeout in 15 seconds*/
options.c_cc[VMIN] = ; /* Update the options and do it NOW */
if (tcsetattr(fd,TCSANOW,&options) != )
{
perror("SetupSerial 3");
return(-);
}
return();
} void print_frame(unsigned char *buf,int size)
{
int i;
for(i = ; i < size; i++)
{
printf("0x%x ", buf[i]);
}
printf("\n");
} void getCompleteFrame(unsigned char *inBuf,int inCnt,unsigned char *outBuf,int *destCnt,int *readStatus)
{
int i;
for(i = ; i < inCnt; i++)
{
if(inBuf[i] == 0x01 && inBuf[i+] == 0x03)//header
{
outBuf[(*destCnt)++] = inBuf[i];
*readStatus = ;
continue;
}
if(*readStatus == )//body
{
outBuf[(*destCnt)++] = inBuf[i];
}
if(*destCnt == outBuf[] && *readStatus == )//tail
{
print_frame(outBuf,*destCnt);
*readStatus = ;
*destCnt = ;
memset(outBuf, -, sizeof(outBuf));
// memset(inBuf,0,sizeof(inBuf));
continue;
}
}
} int main(void)
{
unsigned char battery_msg[];
int fd;
unsigned char read_buf[] = {};
int nread = ;
fd = open("/dev/ttyS0", O_RDWR|O_NOCTTY);
if (fd > )
{
printf("Open Port Success!\n");
}
else
{
printf("Can't Open port\n");
return(-);
} set_speed(fd, );
if(set_Parity(fd, , 'N', ) == -)
{
close(fd);
return(-);
}
int i = , rc = ;
int flag = ;
fd_set rset;
struct timeval tv;
int read_status = ;
int dest_cnt = ; while () //循环读取数据
{
FD_ZERO(&rset);
FD_SET(fd, &rset); tv.tv_sec = ;
tv.tv_usec = ; rc = select(fd+, &rset, NULL, NULL, &tv); if(rc > )
{
if(FD_ISSET(fd_485C2, &rset))
{
memset(read_buf, , sizeof(read_buf));
usleep();
nread = read(fd, read_buf, sizeof(read_buf));
// printf("read %d data\n", nread);
if(nread > )
{
getCompleteFrame(read_buf, nread, battery_msg,&dest_cnt,&read_status);
}
}
}
}
close(fd);
return ;
}
linux 串口 拼帧处理的更多相关文章
- linux串口驱动分析
linux串口驱动分析 硬件资源及描写叙述 s3c2440A 通用异步接收器和发送器(UART)提供了三个独立的异步串行 I/O(SIO)port,每一个port都能够在中断模式或 DMA 模式下操作 ...
- storysnail的Linux串口编程笔记
storysnail的Linux串口编程笔记 作者 He YiJun – storysnail<at>gmail.com 团队 ls 版权 转载请保留本声明! 本文档包含的原创代码根据Ge ...
- linux -- 串口调试总结
linux 串口输出调试 在某些情况下,需要同时对两台或多台Linux主机进行管理和操作.如果手头缺少足够多的键盘和显示器,那么通过一台机器的串口对其余主机进行控制不失为一种快捷.有效的方法. 下面就 ...
- Linux串口c_cc[VTIME]和c_cc[VMIN]属性设置的作用
Linux串口c_cc[VTIME]和c_cc[VMIN]属性设置的作用 在串口编程模式下,open未设置O_NONBLOCK或O_NDELAY的情况下. c_cc[VTIME]和c_cc[VMIN] ...
- linux串口驱动分析——发送数据
一.应用程序中write函数到底层驱动历程 和前文提到的一样,首先先注册串口,使用uart_register_driver函数,依次分别为tty_register_driver,cdev_init函数 ...
- linux串口驱动分析——打开设备
串口驱动是由tty_driver架构实现的.一个应用程序中的函数要操作硬件,首先会经过tty,级级调用之后才会到达驱动之中.本文先介绍应用程序中打开设备的open函数的整个历程. 首先在串口初始化中会 ...
- Linux串口编程详解(转)
串口本身,标准和硬件 † 串口是计算机上的串行通讯的物理接口.计算机历史上,串口曾经被广泛用于连接计算机和终端设备和各种外部设备.虽然以太网接口和USB接口也是以一个串行流进行数据传送的,但是串口连接 ...
- linux串口编程总结
串口本身.标准和硬件 † 串口是计算机上的串行通讯的物理接口.计算机历史上,串口以前被广泛用于连接计算机和终端设备和各种外部设备.尽管以太网接口和USB接口也是以一个串行流进行数据传送的.可是串口连接 ...
- Chain TDNN/LSTM的拼帧索引、延时
TDNN模型示例 TDNN拼帧: 层:(0,3) 层:(-9,0) 层:(0,3) 层:(-6,0) 层:(0,3) 层:(-3,0) 层:(0,3) 层:(-3,0) 输出依赖 帧,各层需要 ...
随机推荐
- LeetCode练题——88. Merge Sorted Array
1.题目 88. Merge Sorted Array——Easy Given two sorted integer arrays nums1 and nums2, merge nums2 into ...
- iOS 与 js交互的其一方法 WebViewJavascriptBridge的使用
#import <WebViewJavascriptBridge.h> /// @interface ZWBridgeViewController ()<WKNavigationDe ...
- Spring Boot 学习前你应该知道的 Maven 知识
Maven 是什么? 回答这个问题,我们先来了解下没有Maven,我们是怎么使用开发者工具IDE去开发Java程序的.我之前开发Java程序不多,但是我还是记得,我是从网上下载或从合作方拷贝 jar ...
- Deepin-linux下的linux的终端下软件安装和卸载方法
1.方法一: sudo apt update #最好第一步是它 sudo apt install <package_name> --no-upgrade #安装该package但是不升级. ...
- N3K异常重启(案例)
在实际的情况下,有时候会遇到设备无故重启的问题,这个时候,我们需要判断一下重启的根本原因是什么,是否有规避的方法等. 这里记录了几个N3K异常重启的问题. 案例1: 设备型号:N3K-C3048TP- ...
- 关于Android发送邮件
Google 在发表 Android 手机平台时,强调的是超强大的网络支持能力,因此,无论通过 GPRS.3G的电信网络或者是Wifi的无线WLAN网络,都能够发EMAIL. 发送邮件中使用的Inte ...
- PSP第二次总结
项目计划总结: 姓名:李志强 日期:2017/12/06 听课 编程 阅读课本 准备考试 日总计 周日11.26 周一 100 100 周二 ...
- swiper插件遇到的坑
1.网速卡的情况下轮播图会出现塌陷 解决方法: 在swiper外层固定高度,用填充百分比方法: html代码:在swiper-container加一层外层,外层用padding-top:50%(看图片 ...
- GSS系列题解——最大子段和系列
开坑啦! 2019 3/28 以前一直不知道怎么搞最大子段和,如今终于可以学习,其实真的很简单啊. 2019 3/29 树链剖分上最大子段和也OK啦 前置技能:线段树 题目大意:询问区间[l,r]的最 ...
- unique() 函数详解
简介 顾名思义,unique,独一无二的.这个函数可以对容器中的元素进行"去重". 但是需要注意,这里的"去重",并没有把重复的元素删除,只是不重复的元素放到了 ...