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

Linux驱动应用编程(三)UART串口

本文目录

  • 前述
  • 一、手册查看
  • 二、命令行调试串口
    • 1. 查看设备节点
    • 2. 使用stty命令设置串口
    • 3. 查看串口配置信息
    • 4. 调试串口
  • 三、代码编写
    • 1. 常用API
    • 2. 例程
      • 线程优化

  

前述

   在开始实验前,请一定要检查测试好所需硬件是否使用正常,不然调试过程中出现的问题,会让你很烦恼。因为我在测试的时候发现一直接收不到消息,后面才知道ttl转usb的tx引脚坏了。所以确保硬件良好是我们后续测试的基本保障。

一、手册查看

   我们前面讲到在Linux中一切皆是文件!无论是上一章节的GPIO,还是串口这边都同样如此。首先,我们就先来使用命令行基本调试一下我们的串口,来确保串口的可用性。无论是什么开发板,我们都需要先查看手册来确定开发板的串口io。这里以香橙派AIPro为例,手册中提醒我们串口0已经被系统使用,不能当作普通串口给用户使用。 所以用户可用串口只有两个。分别是UART7和UART2。

在这里插入图片描述

查看设备节点,如下所示。
在这里插入图片描述

二、命令行调试串口

1. 查看设备节点

设备节点都在 /dev目录下。
在这里插入图片描述

2. 使用stty命令设置串口

常用配置:stty -F /dev/ttyAMA2 115200 cs8 -parenb -cstopb iutf8

在这里插入图片描述

3. 查看串口配置信息

命令:stty -F /dev/ttyAMA2 -a
在这里插入图片描述

4. 调试串口

我们使用TTL转USB接口连接香橙派与电脑,使用串口调试助手测试。注意:在串口助手中要设置为UTF8显示。
坑:在使用TTL连接时,一定要接地线!以保证电气基准电位!不要只接TX和RX!!

(1)香橙派发送数据
在这里插入图片描述

(2)香橙派接收数据
在这里插入图片描述

三、代码编写

   终端设备属性结构体,我们在操作一些设备文件时,常常会用到下面这个结构体。在Unix系统中常用于控制终端的输入输出参数,比如波特率、字符大小、控制字符等。通过操作这个结构体,可以对终端的各种属性进行设置和获取。
头文件:#include<termios.h>

struct termios {unsigned short c_iflag;//控制终端的输入方式,如是否启用回车、换行等unsigned short c_oflag; //控制终端的输出方式,如是否启用回车、换行等。unsigned short c_cflag; //控制终端的控制模式,如波特率、数据位数等。unsigned short c_lflag;//控制终端的本地模式,如是否启用回显、是否启用信号等。unsigned char c_line;//行(线)规程,指定终端的行规程,比如终端是终端设备还是伪终端设备。unsigned char c_cc[NCC]; //控制字符数组,用于定义特殊控制字符的行为,比如终端中的删除、结束、停止等功能键的行为。
};

   这些成员里都有很多配置参数的宏定义,我们只需要将成员与要配置参数的宏定义进行|=(置1)或&=~(置0)操作即可配置相应功能。我这里只先列举出来几个常用的功能。这里我将不再展示参数的宏定义,因为太多了,很多也用不到,有需要的自己去查看其他博客来学习。

●配置举例如下:

struct termios termios_p; //初始化结构体
termios_p.c_cflag |=CS8; //设置八位数据位。
termios_p.c_cflag &=~CSTOPB; //设置一位停止位。
termios_p.c_cflag &=~PARENB; //无奇偶校验位。
termios_p.c_lflag &=~ECHO ; //不回显

1. 常用API

(1)设置波特率。
   波特率,常用 B2400,B4800,B9600,B115200,B460800。

int cfsetispeed(struct termios *termios_p,speed_t speed)  //设置接收波特率
int cfsetospeed(struct termios *termios_p,speed_t speed)  //设置发送波特率
//

(2)清空缓冲区数据。
   主要用于清除输入和输出缓冲区中的数据。这个命令在处理串口通信时非常有用,特别是在初始化或重置通信通道时,以确保没有残留的数据干扰通信。

int tcflush(int fd,int queue_selector)
//int fd :文件描述符
//int queue_selector: 
/*	        TCIFLUSH:清空正读的数据,且不会读出TCOFLUSH:清空正写入的数据,且不会发送到终端TCIOFLUSH:清空所有正在发生的 I/O 数据.*/

(3)获取终端设备参数。
   函数的作用是获取指定文件描述符(fd)所关联的终端设备的当前属性,并将这些属性存储到指定的 termios 结构体(termios_p)中。

int tcgetattr(int fd,struct termios *termios_p)
//int fd :文件描述符。
//struct termios *termios_p: 设备终端结构体。

(4)设置终端设备参数,激活配置。

int tcsetattr(int fd,int optional_actions,cons struct termios *termios_p)
//int fd :文件描述符。
//int optional_actions :
/*			TCSANOW:不等数据传输完毕,立即改变属性TCSADRAIN:等所有数据传输完毕,再改变属性TCSAFLUSH:清空输入输出缓冲区才改变属性
*/		
//cons struct termios *termios_p :终端设备属性的结构体。

2. 例程

uart.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <string.h>
#include "uart.h"
#include <termios.h>void UART_Close(int fd)
{close(fd);
}int UART_Send(int fd, char *data)
{int num;num=write(fd, data, strlen(data));return num;
}int UART_Receive(int fd, char *receive)
{int num;num=read(fd, receive, sizeof(receive)-1);return num;
}int UART_Init(char *device, int baud)
{int fd;int ret;struct termios termios_p; 
//1.打开串口设备。不当作控制台。fd = open(device, O_NOCTTY | O_RDWR);if (fd < 0) {perror("open error");return -1;}
//2. 填充设备结构体memset(&termios_p, 0 ,sizeof(termios_p));termios_p.c_cflag |= CREAD;     //使能接收器的接收功能!必须配置的。termios_p.c_cflag |= CLOCAL;    //忽略调制解调器线路状态。termios_p.c_cflag |=CS8;        //设置八位数据位。//这里为了方便观看,所以写出来下面的配置,这里其实可以不写,因为我们已经先前清空结构体了。termios_p.c_cflag &=~CSTOPB; //设置一位停止位。termios_p.c_cflag &=~PARENB; //无奇偶校验位。termios_p.c_lflag &=~ECHO ; //不回显// 设置超时和最小读取字符数。必须配置!!termios_p.c_cc[VTIME] = 1;termios_p.c_cc[VMIN] = 128;switch (baud){  //设置波特率case 9600:cfsetispeed(&termios_p,B9600);  //设置接收波特率cfsetospeed(&termios_p,B9600);  //设置发送波特率break;case 115200:cfsetispeed(&termios_p,B115200);  //设置接收波特率cfsetospeed(&termios_p,B115200);  //设置发送波特率break;default:printf("不支持此波特率\n");break;}//3. 清空接收/发送缓冲,准备发送和接收数据 tcflush(fd, TCIOFLUSH);//4. 将配置好的设备结构体设置上(绑定),激活设置的配置。ret =tcsetattr( fd,TCSAFLUSH,&termios_p);if (ret < 0) {perror("tcsetattr error");return -3;}return fd; //返回文件描述符
}

uart.h

#ifndef __UART_H
#define __UART_Hvoid UART_Close(int fd);
int UART_Init(char *device, int baud);
int UART_Receive(int fd, char *receive);
int UART_Send(int fd, char *data);
#endif

main.c

#include <stdio.h>
#include <stdlib.h>
#include "uart.h" 
#include <unistd.h>
#include <termios.h>
#include <string.h>
int main()
{char buff[100];int fd;fd=UART_Init("/dev/ttyAMA2",115200);if(fd<0){perror("UART_Init error");return -1;}while(1){fgets(buff,sizeof(buff),stdin);UART_Send(fd, buff);}UART_Close(fd);return 0;
}

在这里插入图片描述

线程优化

功能:添加线程实现可收可发!
main.c

#include <stdio.h>
#include <stdlib.h>
#include "uart.h" 
#include <unistd.h>
#include <termios.h>
#include <string.h>
#include <pthread.h>
#include <signal.h>pthread_attr_t attr; //线程属性
int fd;  //文件描述符void signal_task(int arg)
{printf("销毁相关属性\n");pthread_attr_destroy(&attr); //销毁线程属性UART_Close(fd);exit(0);
}// 线程任务函数
void *task(void *arg) {int fd = *(int *)arg;int ret;char buff[64];while (1) {memset(buff, 0, sizeof(buff));ret = UART_Receive(fd, buff); // 读取数据到buff中if (ret > 0) {buff[ret] = '\0'; // 确保字符串以NULL结尾printf("Receive: %s\n", buff);} else break;}pthread_exit(NULL);
}int main()
{char buff[100];int ret;pthread_t thread;fd=UART_Init("/dev/ttyAMA2",115200);if(fd<0){perror("UART_Init error");return -1;}signal(2, signal_task);pthread_attr_init(&attr);  //初始化线程属性pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); //设置子线程分离属性,子线程推出后自动销毁。ret=pthread_create(&thread,NULL,task,(void *)&fd); //只有一个子线程,可以取地址操作。if(ret<0){perror("pthread_create error");return -1;}while(1){memset(buff,0,sizeof(buff));fgets(buff,sizeof(buff),stdin);UART_Send(fd, buff);}return 0;
}

在这里插入图片描述

相关文章:

Linux驱动应用编程(三)UART串口

本文目录 前述一、手册查看二、命令行调试串口1. 查看设备节点2. 使用stty命令设置串口3. 查看串口配置信息4. 调试串口 三、代码编写1. 常用API2. 例程线程优化 前述 在开始实验前&#xff0c;请一定要检查测试好所需硬件是否使用正常&#xff0c;不然调试过程中出现的问题&am…...

【设计模式深度剖析】【4】【行为型】【策略模式】

文章目录 策略模式定义英文原话直译 角色类图策略接口Strategy&#xff1a;具体策略类上下文类Context测试类 策略模式的应用策略模式的优点策略模式的缺点策略模式的使用场景 策略模式 策略模式&#xff08;Strategy Pattern&#xff09; Strategy策略也称作Policy政策。 想…...

opencv dnn模块 示例(26) 目标检测 object_detection 之 yolov10

文章目录 1、yolov10简要介绍1.1、双标签分配策略1.2、架构改进1.3、性能1.4、预训练模型1.5、网络有关层说明 2、测试2.1、官方测试2.2、opencv dnn2.2.1、仅运行到内部"NMS"步骤之前的层2.2.2、完整代码2.2.2、完整实现所有层 2.3、onnxruntime测试2.4、tensorrt 1…...

【python进阶】python图形化编程之美--tkinter模块初探

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…...

discuz点微同城源码34.7+全套插件+小程序前端

discuz点微同城源码34.7全套插件小程序前后端 模板挺好看的 带全套插件 自己耐心点配置一下插件 可以H5可以小程序...

ActiveMQ 介绍、下载、安装和控制台

ActiveMQ 介绍 Apache ActiveMQ 是一款非常成熟且功能全面的开源消息中间件&#xff0c;由Apache软件基金会维护。它遵循 Java Message Service (JMS) 规范&#xff0c;这意味着它提供了一组标准的 API&#xff0c;允许 Java 应用程序以一种标准化的方式发送和接收消息。 以下…...

MacOS M系列芯片一键配置多个不同版本的JDK

第一步&#xff1a;下载JDK。 官网下载地址&#xff1a;Java Archive | Oracle 选择自己想要下载的版本&#xff0c;一般来说下载一个jdk8和一个jdk11就够用了。 M系列芯片选择这两个&#xff0c;第一个是压缩包&#xff0c;第二个是dmg可以安装的。 第二步&#xff1a;编辑…...

源码文章上传无忧,论坛小程序支持

前言 在数字化时代&#xff0c;知识的分享与传播显得愈发重要。为了满足广大创作者和求知者的需求&#xff0c;我们推出了全新的论坛小程序&#xff0c;不仅支持文章、源码、链接等多样化内容的上传&#xff0c;还实现了付费观看功能&#xff0c;为创作者们提供了一个展示才华…...

Docker面试整理-如何优化Docker容器的性能?

优化Docker容器的性能可以从多个方面入手,以下是一些建议: 选择合适的基础镜像:使用轻量级的基础镜像,如基于Alpine Linux的镜像,可以减少镜像的大小和启动时间。避免使用过于庞大的操作系统镜像。优化Dockerfile:减少Dockerfile中的不必要指令和层,以最小化镜像的大小。…...

list(二)和_stack_queue

嗨喽大家好&#xff0c;时隔许久阿鑫又给大家带来了新的博客&#xff0c;list的模拟实现&#xff08;二&#xff09;以及_stack_queue&#xff0c;下面让我们开始今天的学习吧&#xff01; list(二)和_stack_queue 1.list的构造函数 2.设计模式之适配器和迭代器 3.新容器de…...

查询SQL02:寻找用户推荐人

问题描述 找出那些 没有被 id 2 的客户 推荐 的客户的姓名。 以 任意顺序 返回结果表。 结果格式如下所示。 题目分析&#xff1a; 这题主要是要看这null值会不会用&#xff0c;如果说Java玩多了&#xff0c;你去写SQL时就会有问题。在SQL中判断是不是null值用的是is null或…...

2、Tomcat 线程模型详解

2、Tomcat 线程模型详解 Tomcat I/O模型详解Linux I/O模型详解I/O要解决什么问题Linux的I/O模型分类 Tomcat支持的 I/O 模型Tomcat I/O 模型如何选型 网络编程模型Reactor线程模型单 Reactor 单线程单 Reactor 多线程主从 Reactor 多线程 Tomcat NIO实现Tomcat 异步IO实现 Tomc…...

对硬盘的设想:纸存、执行存

固态硬盘出现后&#xff0c;发现它的擦写次数受限&#xff0c;越是便宜的固态硬盘&#xff0c;擦写次数越少。于是&#xff0c;有了“纸存”的设想&#xff0c;即硬盘上的单元只能改写一次&#xff0c;就像拿钢笔在纸上写字一样。这时&#xff0c;文件系统、数据库该怎么设计&a…...

最新付会进群多群同时变现社群系统V3.5.3版本 详细教程+源码下载

市面1888最新付费进群多群同时变现系统V3.5.3版本 详细教程源码下载介绍&#xff1a; 续男粉变现&#xff0c;相亲群变现后 演化出来的最新多群同时变现系统 可同时进行40个群同时变现 可设置地域群&#xff0c;相亲&#xff0c;男粉变现等多种群 购买后包括详细的 域名服…...

python tk实现标签切换页面

import tkinter as tk from tkinter import ttk# 初始化主窗口 root tk.Tk() root.title("标签页示例")# 设置窗口大小 root.geometry("400x300")# 创建 Notebook 小部件 notebook ttk.Notebook(root) notebook.pack(expandTrue, fill"both")#…...

引擎:UI

一、控件介绍 Button 按钮 创建一个按钮 按钮禁用 精灵模式 颜色模式 缩放模式 绑定点击事件 EditBox 输入框 Layout 布局 支持水平排列、垂直排列、背包排列 PageView 页面视图 ProgressBar 进度条 RichText 富文本 绑定点击事件 事件可以被其它标签包裹 图文混排 Scroll…...

Redis常见异常及优化方案

Redis常见异常及优化方案 Redis集群&#xff08;redis-cluster&#xff09;中的三主三从或者哨兵&#xff08;sentinel&#xff09;模式配置是一种常见的高可用架构&#xff0c;用于解决单点故障和提高数据可靠性。然而&#xff0c;即使在这样的配置下&#xff0c;仍然可能会遇…...

YOLOV5 图像分割:利用yolov5进行图像分割

1、介绍 本章将介绍yolov5的分割部分,其他的yolov5分类、检测项目参考之前的博文 分类:YOLOV5 分类:利用yolov5进行图像分类_yolov5 图像分类-CSDN博客 检测:YOLOV5 初体验:简单猫和老鼠数据集模型训练-CSDN博客 yolov5的分割和常规的分割项目有所区别,这里分割的结果…...

如何在Linux中使用Screen管理后台进程

如何在Linux中使用Screen管理后台进程 在Linux系统中&#xff0c;screen是一个非常有用的工具&#xff0c;它允许用户在一个终端窗口中创建多个虚拟终端&#xff0c;并且可以在这些终端之间切换&#xff0c;甚至可以在断开连接后重新连接到这些会话。这对于需要在后台运行长时…...

互联网轻量级框架整合之SpringMVC初始化及各组件工作原理

Spring MVC的初始化和流程 MVC理念的发展 SpringMVC是Spring提供给Web应用领域的框架设计&#xff0c;MVC分别是Model-View-Controller的缩写&#xff0c;它是一个设计理念&#xff0c;不仅仅存在于Java中&#xff0c;各类语言及开发均可用&#xff0c;其运转流程和各组件的应…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

day36-多路IO复用

一、基本概念 &#xff08;服务器多客户端模型&#xff09; 定义&#xff1a;单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用&#xff1a;应用程序通常需要处理来自多条事件流中的事件&#xff0c;比如我现在用的电脑&#xff0c;需要同时处理键盘鼠标…...

【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权

摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题&#xff1a;安全。文章将详细阐述认证&#xff08;Authentication) 与授权&#xff08;Authorization的核心概念&#xff0c;对比传统 Session-Cookie 与现代 JWT&#xff08;JS…...

相关类相关的可视化图像总结

目录 一、散点图 二、气泡图 三、相关图 四、热力图 五、二维密度图 六、多模态二维密度图 七、雷达图 八、桑基图 九、总结 一、散点图 特点 通过点的位置展示两个连续变量之间的关系&#xff0c;可直观判断线性相关、非线性相关或无相关关系&#xff0c;点的分布密…...

海云安高敏捷信创白盒SCAP入选《中国网络安全细分领域产品名录》

近日&#xff0c;嘶吼安全产业研究院发布《中国网络安全细分领域产品名录》&#xff0c;海云安高敏捷信创白盒&#xff08;SCAP&#xff09;成功入选软件供应链安全领域产品名录。 在数字化转型加速的今天&#xff0c;网络安全已成为企业生存与发展的核心基石&#xff0c;为了解…...