当前位置: 首页 > news >正文

串口通信初始化过程是怎样的???

一、简介

本文简单介绍一下 Linux嵌入式开发中,串口通信的初始化过程。

二、串口通信的初始化过程

串口通信初始化过程涉及配置串行端口的参数,以确保设备间能够正确地进行数据传输。这通常包括设置波特率、数据位、停止位、校验位等。以下是一个详细的步骤指南,以及如何在 Linux 环境下通过 C 语言完成串口通信的初始化。

1. 初始化串口的基本步骤:

打开串口设备:

使用 open() 函数打开串口设备文件(例如 /dev/ttyS0 或 /dev/ttyUSB0),并指定适当的访问模式(读写权限)和标志。

获取当前串口属性:

使用 tcgetattr() 函数获取串口当前的配置信息到一个 termios 结构体中,以便后续修改。

修改串口属性:

设置波特率:cfsetspeed()设置波特率。

配置数据位。

配置停止位;

配置校验类型,也可以配置无校验(是否有奇偶校验)。

根据需要启用或禁用硬件流控(CRTSCTS)、或者软件流控(IXON, IXOFF, IXANY)等。

设置超时和最小读取字符数(目的是控制read()函数从串口读取数据的阻塞行为,这样非常重要,防止读取阻塞);

设置本地模式并启用接收。

禁用回显等等其他配置;

应用新的串口属性:

使用 tcsetattr() 函数将修改后的串口设置应用于串口设备。

2. 初始化过程中,控制从串口读取数据的阻塞行为

串口通信初始化过程中,设置超时和最小读取字符数配置是很重要的,这两个配置是为了控制read()函数从串口读取数据的阻塞行为!!!

在串口通信中,设置超时和最小读取字符数是非常重要的,这可以帮助你控制数据读取的行为,避免程序无限期等待数据或过早读取不完整的数据。这些设置是通过 termios 结构体中的 c_cc 成员来配置的,具体来说是使用 VMINVTIME 控制字符。

一、参数定义与作用
这两个参数位于 termios 结构体的 c_cc 数组中,用于配置串口的读取规则:

VMIN:最小读取字符数(c_cc[VMIN])
定义 read() 函数返回前需要接收到的最小字符数量。
VTIME:超时时间(c_cc[VTIME])
单位为 0.1 秒,定义等待数据的最长时间(与 VMIN 配合使用)。


二、常见配置组合及效果
VMIN 和 VTIME 的不同组合会产生完全不同的读取行为,需根据实际场景选择:

三、Linux应用层串口通信示例代码

下面是Linux应用层串口通信示例代码:

int initComm(char *ttyDir, unsigned speed)
{int retry = 60;  // 设备锁定重试次数(60秒超时)// 以读写方式打开串口设备,不设为控制终端int mfd = open(ttyDir, O_RDWR | O_NOCTTY);if (mfd < 0){perror(ttyDir);  return -1;}// 尝试获取设备锁,防止多进程同时访问while (lockf(mfd, F_TLOCK, 0) < 0){sleep(1);    retry--;     if (retry <= 0){printf("Device %s locked.\n", ttyDir);  close(mfd); return -1;}}// 将数值波特率转换为系统定义的波特率常量switch (speed){case 4800:speed = B4800;break;case 9600:speed = B9600;break;case 19200:speed = B19200;break;case 38400:speed = B38400;break;case 57600:speed = B57600;break;case 115200:speed = B115200;break;case 230400:speed = B230400;break;case 460800:speed = B460800;break;default:printf("speed error");  return -1;}// 获取当前串口属性struct termios Opt;tcgetattr(mfd, &Opt);// 设置波特率cfsetispeed(&Opt, speed);  // 输入速度cfsetospeed(&Opt, speed);  // 输出速度tcsetattr(mfd, TCSANOW, &Opt);  //立即应用设置tcflush(mfd, TCIOFLUSH);  // 清空输入输出缓冲区// 重新获取属性以确保设置生效tcgetattr(mfd, &Opt);// 配置串口参数Opt.c_cflag &= ~CSIZE;  // 清除数据位掩码Opt.c_cflag |= CS8;     // 设置8位数据位// 启用软件流控(XON/XOFF)Opt.c_cflag |= IXON | IXOFF | IXANY;  Opt.c_cflag &= ~PARENB;  // 禁用奇偶校验Opt.c_cflag &= ~CSTOPB;  // 设置1位停止位(清除2位停止位标志)// 设置本地模式标志// 原始模式(非规范模式),禁用回显和信号 Opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);    // 设置输入模式标志// 禁用特殊输入处理 Opt.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);    // 设置输出模式标志// 原始输出(禁用输出处理)Opt.c_oflag &= ~OPOST;  // 设置超时和最小读取字符数// 读取超时(单位:0.1秒,这里15秒)// 最小读取字符数(0表示非阻塞)Opt.c_cc[VTIME] = 150;  Opt.c_cc[VMIN] = 0;    // 应用新的串口属性设置if (tcsetattr(mfd, TCSANOW, &Opt) < 0){perror(ttyDir);  close(mfd);      return -1;}tcflush(mfd, TCIOFLUSH);  //再次清空输入输出缓冲区return mfd;  // 返回配置好的串口文件描述符
}

Linux嵌入式开发

http://www.dtcms.com/a/324481.html

相关文章:

  • IDEA 快捷编辑指南
  • Java开源代码源码研究:我的成长之路与实战心得分享
  • IDEA 安装插件的两种方式
  • 【面试场景题】异地多活改造方案
  • AI大模型--提示词工程
  • CVPR医学图像三套创新方案:通用分割+3D高效解码+SSM肿瘤定位(附链接)
  • 如何解决网站长期不连接数据库后首次连接缓慢的问题?
  • JS--判断是对象还是数组
  • Spring之【详解AOP】
  • 使用 Docker-Compose 部署 Redis 三主三从集群(含 Exporter 监控)
  • SQL Server从入门到项目实践(超值版)读书笔记 23
  • Windows 11 安装 JDK 11
  • ThreadLocal的原理是什么,使用场景有哪些?
  • 【自动化运维神器Ansible】playbook案例解析:Handlers与Notify机制深度解析
  • Vue3入门到精通:2.4 Vue3动态组件与异步组件深度解析
  • leetcode经典题目——单调栈
  • 【Python 工具人快餐 · 第 7 份 · 完结】
  • Redis 监控与优化方案(C++项目)
  • [激光原理与应用-221]:设计 - 皮秒紫外激光器 - 常见技术难题、原因与解决方案
  • 北京天津廊坊唐山打捞失物日记
  • Docker-04:CGroups资源控制组
  • Go语言--语法基础8--函数定义与调用--错误处理
  • Java学习第一百二十三部分——HTTP/HTTPS
  • 基于VuePress2开发文档自部署及嵌入VUE项目
  • 【RH134知识点问答题】第 4 章 归档和传输文件
  • 【浮点数存储】结构、精度说明
  • 联邦学习之------VT合谋
  • Pico+unity VR入门开发超详细笔记2025
  • 人形机器人强化学习入门实践1part
  • stm32没有CMSIS文件