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 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> linux应用程序串口操作及配置 -> 正文阅读

[系统运维]linux应用程序串口操作及配置

linux的设计思想是一切皆文件,对于串口的访问,通过/dev/ttyxx实现对串口设备的访问.

1.串口基本操作

串口最基本的操作是open/read/write. 如下所示是最基本的串口操作程序, open函数打开设备节点,read函数读取串口数据,write函数向串口写入数据.实现终端接收到串口数据,再原封不动的发送给对端.在我们的实际应用中,串口一般外接各类串口模块,比如GPS等.会涉及到配置串口波特率、数据位、停止位等参数.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <asm/termios.h>

#define DEV_UART    "/dev/ttySAC0"
int main (int argc, char *argv[])
{
    int fd;
    int len, i,ret;
    char buf[100] = {0};

    fd = open(DEV_UART, O_RDWR | O_NOCTTY);
    if(fd < 0) {
        perror(DEV_UART);
        return -1;
    }

    while(1){
        len = read(fd, buf, sizeof(buf));
        if (len > 0){
            write(fd, buf, len);
        }
    }
    return 0;
}

2.串口参数设置

串口参数涉及串口波特率、数据位、停止位、奇偶检验位.linux下使用struct termios 结构体来描述这些属性.设置串口参数的流程为,tcgetattr()获取终端属性参数,然后设置串口参数,最后调用tcsetattr()设置终端属性.

struct termios {
    tcflag_t c_iflag;       /* input mode flags */
    tcflag_t c_oflag;       /* output mode flags */
    tcflag_t c_cflag;       /* control mode flags */
    tcflag_t c_lflag;       /* local mode flags */
    cc_t c_line;            /* line discipline */
    cc_t c_cc[NCCS];        /* control characters */
};

2.1. 波特率设置
cfgetispeed和cfgetospeed获取串口的输入输出波特率. cfsetispeed和cfsetospeed设置串口的输入输出波特率.
一般情况下,串口的输入输出波特率都设置为相同的值.

// 设置串口波特率
static void set_baudrate (struct termios *opt, unsigned int baudrate)
{
    cfsetispeed(opt, baudrate);
    cfsetospeed(opt, baudrate);
}

2.2. 数据位设置
数据位置是每个字节中的实际数据所占据的bit数.数据位通过修改struct termios结构体中的c_cflag成员变量实现.CS5、CS6、CS7和CS8分别表示数据位为5、6、7和8.设置数据位之前,先使用CSIZE做位屏蔽.

// 设置数据位.
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;
    }
}

2.3. 奇偶校验位
奇偶检验可以选择奇校验、偶检验或者不校验.

// 设置奇偶校验.
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;
    }
}

2.4.停止位设置

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 */
    }
}

3.测试函数

int main (int argc, char *argv[])
{
    int fd;
    int len;
    char buf[1024] = {0};
    struct termios opt;

    fd = open(DEV_UART, O_RDWR | O_NOCTTY);
    if(fd < 0) {
        perror(DEV_UART);
        return -1;
    }
        tcgetattr(fd, &opt);
        //设置波特率
    set_baudrate(&opt, B115200);
    opt.c_cflag          |= CLOCAL | CREAD;      /* | CRTSCTS */
    //设置数据位
    set_data_bit(&opt, 8);
    //设置校验位
    set_parity(&opt, 'N');
    //设置停止位
    set_stopbit(&opt, "1");
    tcsetattr (fd, TCSANOW, &opt);

    while(1){
        len = read(fd, buf, sizeof(buf));
        if (len > 0){
            write(fd, buf, len);
        }
    }
    return 0;
}
  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-01-16 13:31:42  更:2022-01-16 13:33:51 
 
开发: 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年11日历 -2024/11/16 6:38:00-

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