我是靠谱客的博主 微笑钢笔,最近开发中收集的这篇文章主要介绍Linux 串口读取,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

#include <stdlib.h>
#include
<fcntl.h>
#include
"stdio.h"
#include
"termios.h"
#include
"unistd.h"
#include
"limits.h"
#include
<stdint.h>
#include
"time.h"
//===================
#include <sys/select.h>
#include <sys/time.h>
//===================
#define
UART_DEV
"/dev/ttyUSB0" //根据电脑插入的串口号定义
void main()
{
int fd =0;
int RxLen=0;
uint8_t RxBuff[1024]={0};
//==========串口打开============//
fd = open(UART_DEV ,O_RDWR|O_NOCTTY);
if(fd<0){
printf("COM (%s) Open Fail ! n",UART_DEV); //必须要权限.
return;
}
printf("COM (%s) Open Success ! Watting recv...nn",UART_DEV);
//==========配置串口============//
struct
termios opt;
//配置串口的属性定义在结构体struct termios中
tcgetattr(fd, & opt);
//获取终端控制属性
cfsetispeed(& opt, B115200);
//指定输入波特率(若不设置系统默认9600bps)
cfsetospeed(& opt, B115200);
//指定输出波特率(若不设置系统默认9600bps)
/* c_lflag 本地模式 */
opt.c_cflag &= ~ INPCK;
//不启用输入奇偶检测
opt.c_cflag |= (CLOCAL |
CREAD); //CLOCAL忽略 modem 控制线,CREAD打开接受者
/* c_lflag 本地模式 */
opt.c_lflag &= ~(ICANON | ECHO | ECHOE |
ISIG); //ICANON启用标准模式;ECHO回显输入字符;ECHOE如果同时设置了 ICANON,字符 ERASE 擦除前一个输入字符,WERASE 擦除前一个词;ISIG当接受到字符 INTR, QUIT, SUSP, 或 DSUSP 时,产生相应的信号
/* c_oflag 输出模式 */
opt.c_oflag &= ~ OPOST;
//OPOST启用具体实现自行定义的输出处理
opt.c_oflag &= ~(ONLCR | OCRNL);
//ONLCR将输出中的新行符映射为回车-换行,OCRNL将输出中的回车映射为新行符
/* c_iflag 输入模式 */
opt.c_iflag &= ~(ICRNL |
INLCR);
//ICRNL将输入中的回车翻译为新行 (除非设置了 IGNCR),INLCR将输入中的 NL 翻译为 CR
opt.c_iflag &= ~(IXON | IXOFF | IXANY);
//IXON启用输出的 XON/XOFF流控制,IXOFF启用输入的 XON/XOFF流控制,IXANY(不属于 POSIX.1;XSI) 允许任何字符来重新开始输出
/* c_cflag 控制模式 */
opt.c_cflag &= ~ CSIZE;
//字符长度掩码,取值为 CS5, CS6, CS7, 或 CS8,加~就是无
opt.c_cflag |=
CS8;
//数据宽度是8bit
opt.c_cflag &= ~ CSTOPB;
//CSTOPB设置两个停止位,而不是一个,加~就是设置一个停止位
opt.c_cflag &= ~ PARENB;
//PARENB允许输出产生奇偶信息以及输入的奇偶校验,加~就是无校验
/* c_cc[NCCS] 控制字符 */
opt.c_cc[VTIME] = 0 ;
//等待数据时间(10秒的倍数),每个单位是0.1秒
若20就是2秒
opt.c_cc[VMIN] = 0 ;
//最少可读数据,非规范模式读取时的最小字符数,设为0则为非阻塞,如果设为其它值则阻塞,直到读到到对应的数据,就像一个阀值一样,比如设为8,如果只接收到3个数据,那么它是不会返回的,只有凑齐8个数据后一齐才READ返回,阻塞在那儿
/* new_cfg.c_cc[VMIN]
=
8;//DATA_LEN;
new_cfg.c_cc[VTIME]
=
20;//每个单位是0.1秒
20就是2秒
如果这样设置,就完全阻塞了,只有串口收到至少8个数据才会对READ立即返回,或才少于8个数据时,超时2秒也会有返回
另外特别注意的是当设置VTIME后,如果read第三个参数小于VMIN ,将会将VMIN 修改为read的第三个参数*/
/*TCIFLUSH
刷清输入队列
TCOFLUSH
刷清输出队列
TCIOFLUSH 刷清输入、输出队列*/
tcflush(fd, TCIOFLUSH);
//刷串口清缓存
tcsetattr(fd, TCSANOW, &opt);
//设置终端控制属性,TCSANOW:不等数据传输完毕就立即改变属性
while(1)
{
//==========串口接收(字符串)============//
while( ((RxLen = read(fd, RxBuff,sizeof(RxBuff))) > 0)
)
{
RxBuff[RxLen] = 0;
printf( "%s",RxBuff);
}
}
}

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
/**
* @brief set_baudrate
设置波特率
* @param opt
* @param baudrate
*/
static void set_baudrate (struct termios *opt, unsigned int baudrate)
{
cfsetispeed(opt, baudrate);
cfsetospeed(opt, baudrate);
}
/**
* @brief set_data_bit
设置数据位
* @param opt
* @param databit
*/
static void set_data_bit (struct termios *opt, unsigned int databit)
{
opt->c_cflag &= ~CSIZE;
switch (databit) {
case 8:
opt->c_cflag |= CS8;
break;
case 7:
opt->c_cflag |= CS7;
break;
case 6:
opt->c_cflag |= CS6;
break;
case 5:
opt->c_cflag |= CS5;
break;
default:
opt->c_cflag |= CS8;
break;
}
}
/**
* @brief set_parity
设置奇偶校验位
* @param opt
* @param parity
*/
static void set_parity (struct termios *opt, char parity)
{
switch (parity) {
case 'N':
/* no parity check */
opt->c_cflag &= ~PARENB;
break;
case 'E':
/* even */
opt->c_cflag |= PARENB;
opt->c_cflag &= ~PARODD;
break;
case 'O':
/* odd */
opt->c_cflag |= PARENB;
opt->c_cflag |= ~PARODD;
break;
default:
/* no parity check */
opt->c_cflag &= ~PARENB;
break;
}
}
/**
* @brief set_stopbit
设置停止位
* @param opt
* @param stopbit
*/
static void set_stopbit (struct termios *opt, const char *stopbit)
{
if (0 == strcmp (stopbit, "1")) {
opt->c_cflag &= ~CSTOPB; /* 1 stop bit */
}	else if (0 == strcmp (stopbit, "1")) {
opt->c_cflag &= ~CSTOPB; /* 1.5 stop bit */
}
else if (0 == strcmp (stopbit, "2")) {
opt->c_cflag |= CSTOPB;
/* 2 stop bits */
} else {
opt->c_cflag &= ~CSTOPB; /* 1 stop bit */
}
}
int
set_port_attr (
int fd,
int
baudrate,
// B1200 B2400 B4800 B9600 .. B115200
int
databit,
// 5, 6, 7, 8
const char *stopbit,
//
"1", "1.5", "2"
char parity,
// N(o), O(dd), E(ven)
int vtime,
int vmin )
{
struct termios opt;
tcgetattr(fd, &opt);
//设置波特率
set_baudrate(&opt, baudrate);
opt.c_cflag
|= CLOCAL | CREAD;
/* | CRTSCTS */
//设置数据位
set_data_bit(&opt, databit);
//设置校验位
set_parity(&opt, parity);
//设置停止位
set_stopbit(&opt, stopbit);
//其它设置
opt.c_oflag
= 0;
opt.c_lflag
|= 0;
opt.c_oflag
&= ~OPOST;
opt.c_cc[VTIME]
= vtime;
opt.c_cc[VMIN]
= vmin;
tcflush (fd, TCIFLUSH);
return (tcsetattr (fd, TCSANOW, &opt));
}
int main(int argc, char **argv)
{
printf("=========BuildTime:[%s %s]============n",__DATE__,__TIME__ );
//通过指令 ls /dev/* 查看电脑硬件设备
//一般 ttyS0 等价于Windows的COM1 ,以此类推
//可用MobaXterm软件在Windows下运行linux程序
char *devPath = "/dev/ttyS25";
int fd = open(devPath ,O_RDWR);
long baud = 115200;
if(fd < 0){
printf("[ERROR] uart [%s] open file failed .", devPath );
return -1;
}
set_port_attr(fd,baud,8,"N",'1',0,0);
printf("uart [%s] open sucess,baud=%d bps.n",devPath , baud );
char buf[1024*5] = {0};
int max_size = sizeof(buf);
int len = 0;
while(1) //Ctrl+C 结束终端
{
memset(buf,0,max_size);
len = read(fd, buf,max_size);
if(len<=0)
{
usleep(1000);
continue;
}
printf("Length:%d,Text:%srn",len,buf);
//printf("%s",buf);
}
close( fd );
printf("Quit main program.n");
}

最后

以上就是微笑钢笔为你收集整理的Linux 串口读取的全部内容,希望文章能够帮你解决Linux 串口读取所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(70)

评论列表共有 0 条评论

立即
投稿
返回
顶部