IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> Linux下串口非标准波特率——使用termios2结构体修改波特率 -> 正文阅读

[C++知识库]Linux下串口非标准波特率——使用termios2结构体修改波特率

注意事项

  1. linux的x86和arm64架构下均测试通过。
  2. 程序包含的两个头文件<termios.h> 和<asm/termbits.h>都定义了struct termios,需要将<asm/termbits.h>中的注释掉
  3. 先以标准波特率打开串口,再通过termios2 配合ioctrl修改自定义波特率。
  4. 确保打开串口权限 sudo chmod 777 /dev/ttyUSB0

c++代码

使用SerialInit(int &fd, const char* devname, int baude)完成串口打开与波特率自定义。

  1. uart.hpp
#ifndef UART_HPP_
#define UART_HPP_
//sys include
#include <termios.h> /*PPSIX 终端控制定义*/
#include <linux/serial.h>
class Uart{
public:
    Uart(){}
    ~Uart(){}
    int SerialInit(int &fd, const char* devname, int baude);
private:
    struct termios uart;
    int baude_changed(int &fd,int speed);
     int serial_set_speci_baud(int &fd,int baude);
     int setCustomBaudRate(int&fd,int baude);
};
#endif
  1. uart.cpp
#include <iostream>
#include <errno.h> /*错误号定义*/
#include <fcntl.h>   /*文件控制定义*/
#include <sys/ioctl.h>
#include <asm/termbits.h>//以修改源码
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include "uart.hpp"

int Uart::SerialInit(int &fd, const char* devname, int baude){
    fd = open(devname, O_RDWR | O_NOCTTY | O_NDELAY);//以只读形式、不将此终端作为此进程的终端控制器、非阻塞的形式打开串口
    if (-1 == fd)
    {
        printf("Open %s Error!\n",devname);
        perror("\n");
        return -1;
    }
    if ((fcntl(fd, F_SETFL, 0)) < 0)//设置串口非阻塞,因为这里是以非阻塞形式打开的,所以第三个参数为0,
    {
        perror("Fcntl F_SETFL Error!\n");
        return -1;
    }
    if (tcgetattr(fd, &uart) != 0)
    {
        perror("tcgetattr error!\n");
        return -1;
    }
    cfmakeraw(&uart); //将终端设置为原始模式,该模式下全部的输入数据以字节为单位被处理
    //set speed
/***********************普通设置波特率****************************/
    cfsetispeed(&uart, B115200);
    cfsetospeed(&uart, B115200);
    uart.c_cflag |= CLOCAL | CREAD;//本地连接和接受使能
    uart.c_iflag &= ~ICRNL;    //禁止将输入中的回车翻译为新行 (除非设置了 IGNCR)
    uart.c_iflag &= ~ISTRIP;   //禁止将所有接收的字符裁减为7比特
    uart.c_cflag &= ~PARENB;   //禁止奇偶校验码的生成和检测功能
    uart.c_cflag &= ~CSTOPB;   //设置1停止位
    uart.c_cflag &= ~CSIZE;    //清除数据位设置
    uart.c_cflag |=  CS8;      //设置为8数据位
    uart.c_cflag &= ~CRTSCTS;  //禁止硬件流控
    uart.c_cc[VTIME] = 0;      //指定所要读取字符的最小数量
    uart.c_cc[VMIN] = 1;       //指定读取第一个字符的等待时间,时间的单位为n*100ms
                                //假设设置VTIME=0,则无字符输入时read()操作无限期的堵塞
    tcflush(fd, TCIFLUSH);     //清空终端未完毕的输入/输出请求及数据。

    if (tcsetattr(fd, TCSANOW, &uart) != 0) //激活配置
    {
        perror("tcsetattr Error!\n");
        return -1;
    }
    baude_changed(fd,baude);
    return 1;
}

int Uart::setCustomBaudRate(int &fd,int baude){
    // struct serial_struct currentSerialInfo;
    // if (ioctl(fd, TIOCGSERIAL, &currentSerialInfo) == -1)
    //     perror("\n");
    // printf("baud_base :%d\n",currentSerialInfo.baud_base);
    // if (currentSerialInfo.baud_base % baude != 0)
    //     // perror("\n");

    // currentSerialInfo.flags &= ~ASYNC_SPD_MASK;
    // currentSerialInfo.flags |= (ASYNC_SPD_CUST /* | ASYNC_LOW_LATENCY*/);
    // currentSerialInfo.custom_divisor = currentSerialInfo.baud_base / baude;
    // if (currentSerialInfo.custom_divisor == 0)
    //     // perror("\n");
    // if (ioctl(fd, TIOCSSERIAL, &currentSerialInfo) == -1)
    //     perror("\n");
    // cfsetispeed(&uart, B38400);
    // cfsetispeed(&uart, B38400);
}

int Uart::serial_set_speci_baud(int &fd,int baude){
    // struct serial_struct ss, ss_set;
    // tcgetattr(fd, &uart);
    // cfsetispeed(&uart, B38400);
    // cfsetospeed(&uart, B38400);
    // tcflush(fd, TCIFLUSH);/*handle unrecevie char*/
    // tcsetattr(fd, TCSANOW, &uart);
    // if((ioctl(fd, TIOCGSERIAL, &ss)) < 0)
    // {
    //     printf("BAUD: error to get the serial_struct info:%s\n", strerror(errno));
    //     return -1;
    // }
    // ss.flags |= ASYNC_SPD_CUST| ASYNC_LOW_LATENCY;
    // ss.flags &= ~ASYNC_SPD_MASK;
    // ss.custom_divisor = ss.baud_base / baude;
    // if((ioctl(fd, TIOCSSERIAL, &ss)) < 0)
    // {
    //     printf("BAUD: error to set serial_struct:%s\n", strerror(errno));
    //     return -2;
    // }
    // ioctl(fd, TIOCGSERIAL, &ss_set);
    // printf("BAUD: success set baud to %d,custom_divisor=%d,baud_base=%d\n",
    //     baude, ss_set.custom_divisor, ss_set.baud_base);
    // return 0;
}

/*先使用标准波特率打开串口,再使用该接口修该波特率*/
int Uart::baude_changed(int &fd,int speed)
{
	struct termios2 tio = {0};
	tio.c_cflag = BOTHER | CS8 | CLOCAL | CREAD;
	tio.c_iflag = IGNPAR;
	tio.c_oflag = 0;
	tio.c_ispeed = speed;
	tio.c_ospeed = speed;
	return ioctl(fd, TCSETS2, &tio);
}

linux实现100k波特率的SBUS协议10通道解析

在这里插入图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-07 11:49:05  更:2021-08-07 11:51:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/9 5:29:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码