嵌入式Linux串口操作实例

嵌入式培训机构四个月实训课程笔记(完整版)-Linux系统编程第二天-Linux开发板外设开发(物联技术666) 价值2万的培训机构上课笔记,满满干货精华,记录四个月学习全过程,超值资料。 阅读详情

简介

嵌入式Linux下串口编程与Linux系统下的编程没有什么区别,系统API都是一样的。嵌入式设备中串口编程是很常用的,比如会对接一些传感器模块,这些模块大多是RS232或者RS485接口,对于软件层面上来说,RS232与RS48区别不大。RS232与RS485在使用上的区别,RS232是全双工的,只能对接一个设备串口设备。RS485是半双工的总线协议,一般可以挂多个传感器设备,半双工的意思是同时只能有一个设备向串口发数据。

用到的API函数

函数说明
open打开设备,用于打开串口设备
fcntl修改设备描述符属性参数
isatty检测打开的描述符是否指向一个终端
tcgetattr用来获取串口终端参数
cfmakeraw将终端设置为原始模式,该模式下所有的输入数据以字节为单位被处理
tcflush用于清空输入、输出缓冲区
tcsetattr设置串口终端参数
read读取数据
write写数据
close关闭串口设备

代码

#include<termios.h>
#include "uart.h"

/***************************************
*name    : open_port
*功能描述: 打开串口
*入口参数: 串口号
*返 回 值: 成功返回文件描述符,失败返回负值
*作    者: 
*修改时间:
***************************************/
int open_port(const char * com_port)
{
    int fd;

	if( com_port == NULL ){
        printf("the port name is null\n");
        return -1;
    }
    /*open port*/
    fd = open(com_port, O_RDWR | O_NOCTTY | O_NDELAY);
    if(fd < 0){
        fd = open(com_port, O_RDWR | O_NOCTTY | O_NDELAY);
        if(fd < 0){
            perror("open serial port");
            return -1;
        }
    }
    printf("open %s OK!\n", com_port);
    if(fcntl(fd, F_SETFL,0) < 0){
        perror("fcntl F_SETFL");
    }

    if(isatty(fd) == 0){
        perror("isatty is not a terminal device");
    }
    return fd;
}

/******************************
*name    : set_port
*功能描述: 设置串口参数
*入口参数: fd 文件描述符, baud_rate 波特率, data_bits 数据位,
*          parity 奇偶校验, stop_bits 停止位
*			调用示例: set_port(fd, 115200, 8, 'N',1);
*返 回 值: 成功返回0,失败返回-1
*作    者: 
*修改: 
******************************/
int set_port(int fd, int baud_rate,
             int data_bits, char parity, int stop_bits)
{
    struct termios new_cfg, old_cfg;
    int speed_arry[]= {B2400, B4800, B9600, B19200, B38400,B57600, B115200};
    int speed[]={2400,4800,9600,19200,38400,57600,115200};
    int i = 0;

    /*save and test the serial port*/
    if(tcgetattr(fd, &old_cfg) < 0){
        perror("tcgetattr");
        return -1;
    }
	
	if(fcntl(fd,F_SETFL,0) < 0)//恢复为阻塞模式
	{
		perror("fcntl(CzjFd,F_SETFL,0)!");
	}

    new_cfg = old_cfg;
    cfmakeraw(&new_cfg);     //配置为原来配置
    new_cfg.c_cflag &= ~ CSIZE;     //用数据位掩码清空数据位的设置

    /*set baud_rate*/
    for(i = sizeof(speed_arry) / sizeof(speed_arry[0]); i > 0; i--)
    {
        if(baud_rate == speed[i]){
            cfsetispeed(&new_cfg,speed_arry[i]);
            cfsetospeed(&new_cfg,speed_arry[i]);
        }
    }

    switch(data_bits)    /*设置数据位*/
    {
        case 7:
                new_cfg.c_cflag |= CS7;
                break;

        default:
        case 8:
                new_cfg.c_cflag |= CS8;
                break;
    }

    switch(parity)
    {
        default:
        case 'N':
        case 'n':
        {
            new_cfg.c_cflag &= ~PARENB;     //清除校验位
            new_cfg.c_iflag &= ~(ICRNL|INPCK|IXON|IXOFF);      //关闭奇偶校验  关闭软件流控
            
			break;
        }

        case 'o':
        case 'O':
        {
            new_cfg.c_cflag |= (PARODD | PARENB); //使用奇校验不是用偶校验
            new_cfg.c_iflag |= INPCK;
			break;
        }

        case 'e':
        case 'E':
        {
            new_cfg.c_cflag |= PARENB;
            new_cfg.c_cflag &= ~PARODD;     //使用偶校验
			new_cfg.c_iflag |= INPCK;
			break;
        }

        case 's':
        case 'S':
        {
            new_cfg.c_cflag &= ~PARENB;
            new_cfg.c_cflag &= ~CSTOPB;
			break;
        }
    }
	
    new_cfg.c_iflag &= ~(ICRNL| IXON | IXOFF  );      //关闭奇偶校验  关闭软件流控
	new_cfg.c_oflag &= ~OPOST;

    switch(stop_bits)
    {
        default:
        case 1:
        {
            new_cfg.c_cflag &= ~CSTOPB;
            new_cfg.c_cflag &= ~CRTSCTS;   //禁用硬件流控
            //new_cfg.c_cflag |= CRTSCTS;    //启用硬件流控
			break;
        }
        case 2:
        {
            new_cfg.c_cflag |= CSTOPB;
			break;
		}
    }

    /*set wait time*/
    new_cfg.c_cc[VTIME] = 0;
    new_cfg.c_cc[VMIN]  = 1;

    tcflush(fd, TCIFLUSH);   //处理未接收字符
	if((tcsetattr(fd, TCSANOW, &new_cfg)) < 0)
    {
        perror("tcsetattr");
        return -1;
    }

    return 0;
}


调用测试代码:

#include "uart.h"
#include <stdio.h>
#include <unistd.h>


int main()
{
	int fd = open_port("/dev/ttyS1");
	if ( fd < 0 )
	{
		perror("open port");
		return -1;
	}
	
	set_port(fd, 115200, 8, 'N',1);
	
	char readBuf[32] ={0};
	const char *pstr="hello world";
	write(fd, pstr, strlen(pstr)+1);
	
	read(fd, readBuf, sizeof(readBuf));
	
	close(fd);
}

微信公众号:
微信公众号

Linux C语言实现UART串口通信应用层代码详解 通用异步收发传输器(UART)是一种广泛使用的串行通信协议,它允许微控制器(MCU)和其它设备通过两根线(接收和发送)进行全双工通信。UART是硬件通信协议中最基础的一种,由于其简单性、易用性,在多种应用场景中都能见到它的身影。调试和分析工具对于确保UART通信正确无误至关重要。它们不仅帮助开发者理解数据传输过程中的信号,还助于诊断和解决通信问题。本节将介绍几种常用的调试工具,讨论它们的种类、特点、选择依据以及如何进行安装与配置。假设在一个嵌入式系统中,存在大量数据需要通过UART发送到主机。 阅读详情

相关推荐

基于Linux用户态的UART串口数据收发应用开发实战

尽管USB、Wi-Fi、蓝牙层出不穷,UART依然牢牢占据嵌入式世界的一席之地。原因很简单:✅ 极简电路:仅需两根线✅ 超低功耗:MCU休眠时仍可监听✅ 强抗干扰:差分电平支持千米传输✅ 协议透明:没有封装开销据IEEE统计,2023年仍有68%的嵌入式开发板保留至少一路调试串口。它就像计算机世界的“脐带”,源源不断地输送着最原始也最重要的信息。所以,下次当你看到那个小小的DB9接口时,请记住:它不仅仅是一个老旧的通信端口,而是无数系统生命的见证者。👀✨。

weixin_30838971的博客 1233

嵌入式Linux开发---UART串口通信驱动硬件编程

串口参数的配置,一般包括波特率起始位比特数数据位比特数停止位比特数和流控模式。在此,可以将其配置为波特率 115200、起始位 1b、数据位 8b、停止位 1b 和无流控模式。

weixin_49337111的博客 2651

嵌入式linux串口操作接口及测试代码

嵌入式Linux的串口操作接口及测试代码

嵌入式Linux入门-彻底理解UART串口,手把手教你写程序

UART串口这个东西,是嵌入式学习上避不开的,不仅在调试中经常用到,还有很多模块通过串口与SOC相连。这篇文章让你彻彻底底,搞明白串口程序的编写。

闪耀大叔的博客 4182

基于SpringBoot+Vue的公司考勤管理系统

为什么选择我博主是优快云毕设辅导博客第一人兼开派祖师爷、博主本身从事开发软件开发、有丰富的编程能力和水平。专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流和合作。

m0_71849512的博客 1162

【PLIO学习总结】laserMapping中的时间戳与状态更新逻辑

本文仅用于个人学习总结记录。如有错误,请批评指正。

larrydong的博客 1648

嵌入式linux入门3-2-串口

个人博客上本篇文章地址:嵌入式linux入门3-2-串口 tty体系 tty是teletype的缩写,在上世纪计算机还很昂贵的时候,多人可以通过这种终端来连接并共用一台计算机,发展到今日,tty已经成为了字符类设备的统称,这类设备包括:控制台、UART等物理串行接口以及伪终端。也就是说,开发板物理串口一般对应linux中/dev目录下的tty*设备文件,访问这些文件,就访问硬件串口了。 tips:以下内容为阅读 Serial Programming Guide for POSIX Operating Sy

Codinglover 5034

SECS/GEM协议学习教程

摘要:SECS/GEM是半导体制造设备通信的国际标准,定义了主机系统与设备间的通信规范,包括设备控制、状态监控、数据采集等功能。协议采用分层架构(应用层、消息层、传输层、物理层),支持关键消息类型如S1F13(建立通信)、S2F13(数据采集)等。通信流程涵盖建立连接、数据交换和终止会话,并通过状态变量(SVID)、事件(CEID)等实现实时交互。典型应用包括设备初始化、报警处理及配方管理,需处理数据类型(如U2、A、L)和通信调试问题。

GitHub个人仓库地址:https://github.com/feiyuluoye ; 个人塔罗牌占卜平台:http://118.126.82.12:8080/ ; 欢迎广大Coding友共同交流讨论。 2062

嵌入式Linux(十)串口

111

qq_41075961的博客 844

基于docker进行安装部署seata,解决Seata的版本与Nacos的版本不匹配

本文分享了在Docker环境下部署Seata时遇到Nacos 3.x API不兼容问题的解决方案。由于Seata 2.0.0内置的nacos-client 1.4.2无法调用Nacos 3.x重构后的接口,导致注册失败。通过下载Seata 2.6.0源码自行构建Docker镜像,并调整启动方式(直接执行Java命令绕过Shell脚本),最终成功实现与Nacos 3.x的集成。关键步骤包括:创建自定义Dockerfile、配置application.yml、处理启动脚本兼容性问题,最终采用java直接运行方案

Dd52698的博客 409

从Chimera到ChimeraX:科研绘图升级指南,让你的论文配图更专业

本文详细介绍了从UCSF Chimera升级到ChimeraX的科研绘图指南,帮助研究者提升论文配图质量。ChimeraX在渲染引擎、大分子处理能力和动画功能上具有显著优势,特别适合生命科学和结构生物学领域。文章涵盖材质设置、专业配色、工作流程和期刊适配等核心技巧,助力产出出版级分子可视化图像。

weixin_33670786的博客 934

嵌入式Linux——8 串口

*** 设置串口参数* @param fd 串口文件描述符* @param nSpeed 波特率(2400/4800/9600/115200)* @param nBits 数据位(7或8)* @param nEvent 校验方式(N:无校验,O:奇校验,E:偶校验)* @param nStop 停止位(1或2)* @return 成功返回0,失败返回-1*//* 1. 获取当前串口配置 */= 0) {return -1;/* 2. 初始化新配置结构体 */

m0_74375685的博客 1263

ESP32 LVGL开发板例程使用记录:自制常用汉字字库(二)

1、将下载的文件移入工程文件中 ,路径为项目文件中 ”......\lib\lvgl\src\font“文件夹下。3、修改字库配置文件,文件名为lv_conf.h中的内容,向其中加入下面内容(位置可搜索注释块来找到地方)修改完成可以编译试试,看是否成功,如字库较大时编译出错,请使能:LV_FONT_FMT_TXT_LARGE。2、打开此文件,修改包含头文件的路径,不然会报错,修改方法可对照自己库中其他字库文件中的包含路径。导入完成后在VSCode工程中可以查看到此文件。上次说完了如何制作 字库.c 文件。

qq_43279097的博客 1959

Linux串口调试详解

测试平台 宿主机平台:Ubuntu 16.04.6 目标机:iMX6ULL 目标机内核:Linux 4.1.15 目标机添加串口设备 一般嵌入式主板的默认镜像可能只配置了调试串口,并用于 console 控制台打印; 接下来对怎么样通过设备树来分配引脚用于用户串口通信 进行描述; 前提: 目标机以及正常烧录 uboot、内核、文件系统、dtb等;本文仅更新设备树dtb文件...

weixin_30367873的博客 1304

《Android系统开发中高级定制专栏导读》

欢迎来到【Android 中高级系统定制】专栏!在这里,将深入探讨Android系统开发与定制的方方面面,涵盖从权限管理、驱动开发到系统应用配置等多个领域。

我其实什么都不会 1579

RK+linux教程:RK3588 RGA硬件加速在YOLOv5图像预处理中的深度应用教程

摘要: 本教程深入解析了RK3588芯片的RGA硬件加速器在YOLOv5图像预处理中的应用。通过专用硬件设计,RGA支持图像缩放、边界填充等核心操作,结合零拷贝技术显著提升处理效率。重点分析了LetterBox算法的RGA实现,包括参数计算、边界填充和性能优化,并与传统CPU处理对比,展示了RGA在高分辨率图像处理中的优势。教程还提供了统一的预处理接口设计,便于在OpenCV与RGA方案间灵活切换,为RK3588平台的深度学习部署提供实用优化方案。

LXY_LOVE36的博客 977

Linux串口编程(中断方式和select方式)

转载:http://blog.chinaunix.net/uid-20788636-id-1841319.html Linux下的串口编程,在嵌入式开发中占据着重要的地位,因为很多的嵌入式设备都是通过串口交换数据的。在没有操作系统的我们可以使用UART的中断来出来数据的接受和发送,而在Linux操作系统下,我们也可以使用软中断的方式来处理数据的接受和发送,这里主要使用的是信号SIGIO,也就是异步...

qq_41579616的博客 526

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Linux串口

可以参考http://www.cnblogs.com/lovemo1314/archive/2010/10/29/1864327.html 《从实践中学嵌入式linux应用程序开发》(华清远见嵌入式学院)第2章、嵌入式文件和I/O编程   设置串口属性的基本流程: 保存原先串口配置 使用tcgetattr(fd,&old_cfg)函数,该函数得到有fd指向的终

萌萌的It人 www.itmmd.com 1166

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

linux 串口 字符 间隔,嵌入式linux编程过成中模块从串口读数需要特定的字符段并且需要每两位字符数组元素转换成一个16进制数(提取特定字符串+字符串转16进制)...

嵌入式linux编程过成中用到zigbee模块zigbee从串口读数需要特定的字符段并且需要每两位字符数组元素转换成一个16进制数(提取特定字符串+字符串转16进制)#include#include#include#includeint serchzig(char *rdbuf,unsigned char *wtbuf){char *beginbuf = NULL;char *endbuf = N...

weixin_42130786的博客 131

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

嵌入式Linux系统uart串口编程详解及实例分析

近来在一个项目开发中,在一个新的硬件平台下的linux系统,使用uart串口进行通讯,结果通讯不畅。代码是以前在其他硬件平台下验证完全没问题的代码,为什么会出问题呢?经过各方面查资料,最终定位为uart串口初始化的问题。在linux系统下,串口的初始化比较复杂,需要设置的东西比较多,如果有一些默认的配置与硬件和应用程序不匹配,而又没有重新配置,就会导致通讯失败的情况。经过对linux系统下串口初始化的进行了整理梳理,最终解决了问题。记录这批位置可以为其他小伙伴提供参考。 一、termios...

bigmarshal的博客 3901

嵌入式Linux串口操作接口

鉴于串口在嵌入式系统中广泛应用于操作GPRS模块、读卡器模块和GPS北斗模块等,串口操作成为嵌入式系统开发中必备工作,但是目前web中并没有提供一个封装良好的串口初始化和读写接口函数,因此本文基于工程实践提供了操作串口的接口函数和测试程序,为嵌入式Linux的串口操作提供了较大的便利。

程序人生 1545

嵌入式linux操作串口简单示例

嵌入式linux操作串口简单示例 这里以MT7688 openwrt系列为例 main.c #include <fcntl.h> #include <sys/stat.h> #include <unistd.h> #include <termios.h> #include <stdio.h> #include <stdlib.h> #include <string.h> //打开串口文件 static int open_u

锅锅的博客 707

Linux下串口操作-嵌入式-C语言实现

嵌入式开发板到手后一般都会开放串口,对串口的操作可以说是最基本的操作,那么拿到开发板后怎样操作串口呢?怎样利用串口向外发送数据呢?我做的是一个通过串口来发送一串字符,实现NBIot的传输,系统是linux系统下的,发送的数据需要是16进制的数据。以下是c语言开发串口的相关代码记录。1.找到串口的设备号在linux系统下,所有的设备都是文件,所以要先找到串口这个设备文件,之后就可以对这个串口进行操作...

kingkill315的博客 5108

嵌入式Linux操作UART实例

1引言串口是我们实际工作中经常使用的一个接口,比如我们在Linux下使用的debug串口,它用来登录Linux系统,输出log。另外我们也会使用串口和外部的一些模块通信,比如GPS模块、...

嵌入式Linux 2322

zynq操作系统: Linux驱动开发串口篇

一.简介   串口( UART)是一种非常常见的外设, 串口在嵌入式开发领域当中一般作为一种调试手段,通过串口将调试信息打印出来,或者通过串口发送指令给主机端进行处理;当然除了作为基本的调试手段之外,还可以通过串口与其他设备或传感器进行通信, 譬如有些 sensor 就使用了串口通信的方式与主机端进行数据交互。 根据电平标准的不同,串口可以分为 TTL, RS232,RS485, RS422等这些,虽然它们的电平标准不同,但是却都遵循相同的通信时序协议,所以呢,不管它是什么样的电平标准,对于我们软件而言其驱

同步更新https://blog.must-xin.com/,内容转载请联系作者本人 8289
上一篇: 代码托管码云地址
下一篇: 嵌入式C语言终端界面输出颜色
fensnote
博客等级 码龄7年 11粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值