linux下c的串口收发

news/2024/12/20 2:21:41/

linux下c的串口收发录

转自: https://blog.csdn.net/weixin_41471318/article/details/116230465

文章目录

  • linux下c的串口收发录
    • 转自: https://blog.csdn.net/weixin_41471318/article/details/116230465
  • 前言
  • 一、直接打开串口
  • 二、使用步骤
    • 1.引入库
    • 2.源码
  • 三、使用步骤
    • 1.termios详解及其赋值
  • 总结


前言

因为在另外一篇文章说到了单片机的收发,所以想着在linux下也写一篇
而他们不同的是单片机是裸机,而Linux是一个系统,至于linux下皆文件,知道就行了,这里以ubuntu讲解,linux你大可分为驱动–内核–应用,而对于初始化串口都是内核跟驱动的事情,他们写好后会生成一个设备号,至于设备号在啥地方,驱动工程师会告诉你,一般来说串口的在 ”/dev/ttyx“,我们输入 ls /dev/tty 后按下Tab,他会自动补齐,然后会看到很多设备,可以理解成设备操作符

ls /dev/tty  (+Tab)

在这里插入图片描述


提示:以下是本篇文章正文内容,下面案例可供参考

一、直接打开串口

    fd= open("/dev/ttyUSB0",O_RDWR );//不成为控制终端程序,不受其他程序输出输出影响

这种也可以,后续也可以进行读写。就是read write,但是这样会使得波特率只能是9600,所以很多时候对于一些外设不是很友好,所以要对其进行设置

//试用的头文件有以下
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <error.h>
#include <termios.h>///串口使用到了这个
#include <malloc.h>
#include <sys/types.h>
#include <sys/stat.h>

二、使用步骤

1.引入库

代码如下(示例):

typedef struct termios termios_t;//串口类型结构体
typedef struct serial_data{char databuf[100];//发送/接受数据int serfd;//串口文件描述符
}ser_Data;void *sersend(void *arg);
void *serrecv(void *arg);

其termios 结构体是这个,后面会对这几个结构体进行解释

//而比较重要的是termios这个结构体struct termios{unsigned short c_iflag; /* 输入模式标志*/unsigned short c_oflag; /* 输出模式标志*/unsigned short c_cflag; /* 控制模式标志*/unsigned short c_lflag; /*区域模式标志或本地模式标志或局部模式*/unsigned char c_line; /*行控制line discipline */unsigned char c_cc[NCC]; /* 控制字符特性*/speed_tc_isspeed;      //输入波特率speed_tc_ospedd;       //输出波特率};

对此结构体进行设置

    bzero(ter_s,sizeof(*ter_s)); ter_s->c_cflag |= CLOCAL | CREAD; //激活本地连接与接受使能 ter_s->c_cflag &= ~CSIZE;//失能数据位屏蔽ter_s->c_cflag |= CS8;//8位数据位 ter_s->c_cflag &= ~CSTOPB;//1位停止位 ter_s->c_cflag &= ~PARENB;//无校验位 ter_s->c_cc[VTIME] = 0;ter_s->c_cc[VMIN] = 0;

改变波特率,如果没有,那就是默认的115200

    cfsetispeed(ter_s,B115200);//设置输入波特率cfsetospeed(ter_s,B115200);//设置输出波特率 tcflush(serport1fd,TCIFLUSH);//刷清未处理的输入和/或输出 if(tcsetattr(serport1fd,TCSANOW,ter_s) != 0){printf("com set error!\r\n");} 

2.源码

代码如下(示例):

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <error.h>
#include <termios.h>
#include <malloc.h>
#include <sys/types.h>
#include <sys/stat.h>
typedef struct termios termios_t;typedef struct serial_data{char databuf[100];//发送/接受数据int serfd;//串口文件描述符}ser_Data;void *sersend(void *arg);
void *serrecv(void *arg);int main(int argc,char *argv[])
{pthread_t pid1,pid2;pthread_attr_t *pthread_arr1,*pthread_arr2;pthread_arr1 = NULL;pthread_arr2 = NULL;int serport1fd;/*   进行串口参数设置  */termios_t *ter_s = malloc(sizeof(*ter_s));serport1fd = open(argv[1],O_RDWR | O_NOCTTY | O_NDELAY);//不成为控制终端程序,不受其他程序输出输出影响if(serport1fd < 0){printf("%s open faild\r\n",argv[1]);return -1;}bzero(ter_s,sizeof(*ter_s));ter_s->c_cflag |= CLOCAL | CREAD; //激活本地连接与接受使能ter_s->c_cflag &= ~CSIZE;//失能数据位屏蔽ter_s->c_cflag |= CS8;//8位数据位ter_s->c_cflag &= ~CSTOPB;//1位停止位ter_s->c_cflag &= ~PARENB;//无校验位ter_s->c_cc[VTIME] = 0;ter_s->c_cc[VMIN] = 0;/*1 VMIN> 0 && VTIME> 0VMIN为最少读取的字符数,当读取到一个字符后,会启动一个定时器,在定时器超时事前,如果已经读取到了VMIN个字符,则read返回VMIN个字符。如果在接收到VMIN个字符之前,定时器已经超时,则read返回已读取到的字符,注意这个定时器会在每次读取到一个字符后重新启用,即重新开始计时,而且是读取到第一个字节后才启用,也就是说超时的情况下,至少读取到一个字节数据。2 VMIN > 0 && VTIME== 0在只有读取到VMIN个字符时,read才返回,可能造成read被永久阻塞。3 VMIN == 0 && VTIME> 0和第一种情况稍有不同,在接收到一个字节时或者定时器超时时,read返回。如果是超时这种情况,read返回值是0。4 VMIN == 0 && VTIME== 0这种情况下read总是立即就返回,即不会被阻塞。----by 解释粘贴自博客园*/cfsetispeed(ter_s,B115200);//设置输入波特率cfsetospeed(ter_s,B115200);//设置输出波特率tcflush(serport1fd,TCIFLUSH);//刷清未处理的输入和/或输出if(tcsetattr(serport1fd,TCSANOW,ter_s) != 0){printf("com set error!\r\n");}char buffer[] = {"hello my world!\r\n"};char recvbuf[100] = {};ser_Data snd_data;ser_Data rec_data;snd_data.serfd = serport1fd;rec_data.serfd = serport1fd;memcpy(snd_data.databuf,buffer,strlen(buffer));//拷贝发送数据pthread_create(&pid1,pthread_arr1,sersend,(void *)&snd_data);pthread_create(&pid2,pthread_arr2,serrecv,(void *)&rec_data);ssize_t sizec;while(1){usleep(100000);}pthread_join(pid1,NULL);pthread_join(pid2,NULL);free(ter_s);return 0;
}void *sersend(void *arg)//串口发送线程函数
{ser_Data *snd = (ser_Data *)arg ;int ret;while(0){ret = write(snd->serfd,snd->databuf,strlen(snd->databuf));if(ret > 0){printf("send success, data is  %s\r\n",snd->databuf);}else{printf("send error!\r\n");}usleep(300000);/*if(发生中断)break;//退出*/}
}void *serrecv(void *arg)//串口发送线程函数
{ser_Data *rec= (ser_Data *)arg ;int ret;while(1){ret = read(rec->serfd,rec->databuf,1024);if(ret > 0){printf("recv success,recv size is %d \r\n",ret );if(rec->databuf[0]==1){printf("\n many color");}else{printf("\n black color");}printf("\n num :%d",rec->databuf[1]);if(rec->databuf[3]==1){printf("\n one by one open");}else{printf("\n one by one close");}if(rec->databuf[4]==1){printf("\n single single");}else{printf("\n  double  single");}if(rec->databuf[5]==1){printf("\n  auto");}else if(rec->databuf[5]==2){printf("\n  text");}else if(rec->databuf[5]==3){printf("\n  text  pict");}else if(rec->databuf[5]==4){printf("\n  pict");}printf("\n mingandu :%d",rec->databuf[6]);if(rec->databuf[6]==1){printf("\n a4");}else{printf("\n  a3");}if(rec->databuf[7]==1){printf("\n jinzhiqi");}else{printf("\n  gaotai");}}else{/*什么也不做*/}usleep(1000);/*if(发生中断)break;//退出*/}
}

该处使用的url网络请求的数据。


三、使用步骤

1.termios详解及其赋值

//而比较重要的是termios这个结构体struct termios{unsigned short c_iflag; /* 输入模式标志*/unsigned short c_oflag; /* 输出模式标志*/unsigned short c_cflag; /* 控制模式标志*/unsigned short c_lflag; /*区域模式标志或本地模式标志或局部模式*/unsigned char c_line; /*行控制line discipline */unsigned char c_cc[NCC]; /* 控制字符特性*/};

c_iflag参数表

键值Value
IGNBRK忽略BREAK键输入
BRKINT如果设置了IGNBRK,BREAK键输入将被忽略
IGNPAR忽略奇偶校验错误
PARMRK标识奇偶校验错误
INPCK允许输入奇偶校验
ISTRIP去除字符的第8个比特
INLCR将输入的NL(换行)转换成CR(回车)
IGNCR忽略输入的回车
ICRNL将输入的回车转化成换行(如果IGNCR未设置的情况下)
IUCLC将输入的大写字符转换成小写字符(非POSIX)
IXON允许输出时对XON/XOFF流进行控制
IXANY输入任何字符将重启停止的输出
IXOFF允许输入时对XON/XOFF流进行控制
IMAXBEL当输入队列满的时候开始响铃

c_oflag参数表

键值Value
OPOST处理后输出
OLCUC将输入的小写字符转换成大写字符(非POSIX)
ONLCR将输入的NL(换行)转换成CR(回车)及NL(换行)
OCRNL将输入的CR(回车)转换成NL(换行)
ONOCR第一行不输出回车符
ONLRET不输出回车符
OFILL发送填充字符以延迟终端输出
OFDEL以ASCII码的DEL作为填充字符,如果未设置该参数,填充字符为NUL
NLDLY换行输出延时,可以取NL0(不延迟)或NL1(延迟0.1s)
CRDLY回车延迟,取值范围为:CR0、CR1、CR2和 CR3
TABDLY水平制表符输出延迟,取值范围为:TAB0、TAB1、TAB2和TAB3
BSDLY空格输出延迟,可以取BS0或BS1
VTDLY垂直制表符输出延迟,可以取VT0或VT1
FFDLY换页延迟,可以取FF0或FF1

c_cflag:

键值Value
CBAUD波特率(4+1位)(非POSIX)
CBAUDEX附加波特率(1位)(非POSIX)
CSIZE字符长度,取值范围为CS5、CS6、CS7或CS8
CSTOPB设置两个停止位
CREAD使用接收器
PARENB使用奇偶校验
PARODD对输入使用奇偶校验,对输出使用偶校验
HUPCL关闭设备时挂起
CLOCAL忽略调制解调器线路状态
CRTSCTS使用RTS/CTS流控制

c_lflag:

键 值说 明
ISIG当输入INTR、QUIT、SUSP或DSUSP时,产生相应的信号
ICANON使用标准输入模式
XCASE在ICANON和XCASE同时设置的情况下,终端只使用大写。如果只设置了XCASE,则输入字符将被转换为小写字符,除非字符使用了转义字符(非POSIX,且Linux不支持该参数)
ECHO显示输入字符
ECHOE如果ICANON同时设置,ERASE将删除输入的字符,WERASE将删除输入的单词
ECHOK如果ICANON同时设置,KILL将删除当前行
ECHONL如果ICANON同时设置,即使ECHO没有设置依然显示换行符
ECHOPRT如果ECHO和ICANON同时设置,将删除打印出的字符(非POSIX)
TOSTOP向后台输出发送SIGTTOU信号

总结

提示:这里对文章进行总结:

先搞懂那几个结构体,就好办事了
链接: link


http://www.ppmy.cn/news/560930.html

相关文章

C#编写串口助手

C#编写串口助手 借鉴了很大部分下面文章的内容&#xff0c;我也修改了很多&#xff0c;最后完善成了一个完整的串口助手。 C#编写串口助手 1.UI设置 ①创建Windows窗口应用程序。 文件—新建—项目&#xff0c;选择Visual C#&#xff0c;选择Windows窗体应用程序&#xff0…

Debian系列-USB转串口(CH340)调试及cutecom串口调试工具安装

Debian系列-USB转串口(CH340)调试及cutecom串口调试工具安装 文章目录 Debian系列-USB转串口(CH340)调试及cutecom串口调试工具安装摘要1 CH340驱动测试2 cutecom 串口调试助手安装3 测试 关键字&#xff1a; CH340、 USB、 cutocom、 debian、 linux 摘要 今天要搞的是串…

windows C语言读串口数据

&#xff08;1&#xff09;这种方式真的很奇怪&#xff0c;乍一看咋都不像打开串口的&#xff0c;但是真的可以打开。不过在这段代码里并没有配置串口&#xff0c;所以必须借助串口助手才可以&#xff0c;就是先用串口助手打开串口&#xff0c;然后这段程序才可以正常运行。可能…

华为2288H V5串口重定向修改为iBMC

问题描述&#xff1a; 华为2288Hv5默认的串口都是显示为系统界面(显示器内容)。 显示一般为下面两种情况&#xff08;服务器暂时没有安装操作系统&#xff09;&#xff1a; 问题解决&#xff1a; 如何把串口修改为显示iBMC呢&#xff1f;可以采用如下方式&#xff1a; ①使用…

Linux C/C++串口读写

1.串口简介 串行通信接口(简称“串口”)是计算机一种常用的接口&#xff0c;因其连接线少、通讯简单的特点而得到广泛使用。常用的串口是 RS-232-C接口(又称EIA RS-232-C)&#xff0c;它是在1970年由美国电子工业协会(EIA)联合贝尔系统、调制解调器厂家及计算机终端生产厂家共同…

飞思卡尔MC9S12G64串口发送接收驱动

因为之前刚入职&#xff0c;对串口调试不了解&#xff0c;下面整理一下书上的串口程序。 移植性还比较强 使用说明&#xff1a;MC9S12系列的串口有两种查询方式 1》使用中断方式查询 2》在主函数中使用轮询的方式的方法进行查询 这两种方法在下面函数中都有体现&#xff0c;需…

C#读取RS232串口扫描枪

扫描对于工业商业的主要输入设备很常见&#xff0c;与扫描枪的通讯也非常简单。之前看到网上有很多人问&#xff0c;但大多说人没有给出确切的回答&#xff0c;其实也就是源代码啦。 我刚好做了一个项目用到了这种扫描枪&#xff0c;现在把做的步骤和代码上传上来&#xff0c;…

CH340串口驱动(包含各系统平台)

CH340转串口芯片支持的平台驱动齐全&#xff0c;支持 Windows/Linux/Android/MacOS/WinCE 等操作系统。各平台下驱动官网链接和说明如下&#xff0c;各平台的安装与使用问题可参见其他博文。 Windows驱动 下载链接&#xff1a;CH340/CH341 Windows 驱动链接http://www.wch.cn/…