嵌入式Linux应用开发笔记:串口

news2024/12/24 3:25:25

文章目录

  • 目的
  • 基础说明
  • 开发准备
    • 设备树
    • 应用程序
  • 应用程序与演示
    • 代码
    • 演示
  • 总结
  • 设备树文件

目的

串口(UART)是嵌入式设备中比较常用的功能。这篇文章将记录下应用程序中串口操作相关内容。

这篇文章中内容均在下面的开发板上进行测试:
《新唐NUC980使用记录:自制开发板(基于NUC980DK61YC)》

这篇文章是在下面文章基础上进行的:
《新唐NUC980使用记录(5.10.y内核):在用户应用中使用GPIO》

基础说明

Linux中应用程序对于串口的使用可以参考下面文章: https://digilander.libero.it/robang/rubrica/serial.htm
https://blog.csdn.net/qq_37932504/article/details/121125906

这里简单介绍下相关内容。Linux中应用程序对于串口的使用基本上也就是文件操作,使用 open / write / read 等方法。此外通常使用前需要通过 ioctl 方法来获取与设置串口的波特率、数据位、停止位、流控制等。对于串口而言部分设置在 ioctl 方法之上封装了一些函数,可以方便的进行操作。

串口的设置都集中在下面的结构体中:

struct termio
{
	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]; /* 控制字符标志 */
};

结构体中具体内容与设置可以参考上面文章。

开发准备

设备树

首先需要调整设备树来启用串口:

# cd ~/nuc980-sdk/NUC980-linux-5.10.y/
gedit arch/arm/boot/dts/nuc980-dev-v1.0.dts

这里启用了 uart1

uart1: serial@b0071000 {
	status = "okay";
};

根据 nuc980.dtsi 文件的中的定义 uart1 默认使用引脚为 PA0 - RXDPA1 - TXD

# 设置编译工具链
export ARCH=arm; export CROSS_COMPILE=arm-buildroot-linux-gnueabi-
export PATH=$PATH:/home/nx/nuc980-sdk/buildroot-2023.02/output/host/bin

# 编译生成设备树文件
make dtbs

# 编译完成后拷贝到电脑上再拷贝到SD卡中
# sudo cp arch/arm/boot/dts/nuc980-dev-v1.0.dtb /media/sf_common/

# 我这里开发环境和开发板在同一局域网中,所以可以直接通过网络将dtb文件拷贝到开发板上
# 在开发板中挂载boot分区
# mount /dev/mmcblk0p1 /mnt/
# 在ubuntu中使用scp命令拷贝dtb文件到开发板上
# scp arch/arm/boot/dts/nuc980-dev-v1.0.dtb root@192.168.31.142:/mnt/
# 拷贝完成后重启开发板即可测试
# reboot

加载新的设备树之后就可以测试新串口的功能了,使用外部的串口模块连接开发板和电脑:
在这里插入图片描述
可以看到使用默认波特率发送数据其实很简单,但是实际的使用过程中往往还需要修改串口设置以及接收数据等,所以就需要编写应用程序来处理。

应用程序

cd ~

# 创建目应用程序录并进入
mkdir -p ~/nuc980-sdk/apps/uart
cd ~/nuc980-sdk/apps/uart

# 创建应用程序文件
gedit uart_test.c

# 应用程序代码见下面章节

# 设置编译工具链
export ARCH=arm; export CROSS_COMPILE=arm-buildroot-linux-gnueabi-
export PATH=$PATH:/home/nx/nuc980-sdk/buildroot-2023.02/output/host/bin

# 编译生成目标应用程序
arm-linux-gcc -o uart_test uart_test.c

# 编译完成后拷贝到电脑上再拷贝到SD卡中
# sudo cp uart_test /media/sf_common/

# 我这里开发环境和开发板在同一局域网中,所以可以直接通过网络将文件拷贝到开发板上
# 在ubuntu中使用scp命令拷贝文件到开发板上
# scp uart_test root@192.168.31.142:/root/

应用程序与演示

代码

#include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */

int main(int argc, char **argv)
{
    int fd, ret;
    struct termios opt;
    char c;

	if (argc != 2)
	{
		printf("Usage: uart_test </dev/ttyX>\n");
		return -1;
	}

    /* 打开串口 */
    fd = open(argv[1], O_RDWR | O_NOCTTY | O_NDELAY);
    if (fd == -1)
    {
        printf("NX applog: can not open %s\n", argv[1]);
        return -1;
    }
    fcntl(fd, F_SETFL, 0); // 读取使用阻塞方式

    /* 设置串口属性 */
    // tcgetattr(fd, &opt); // 获取现有串口属性
    bzero(&opt, sizeof(opt)); // 以0填充结构体

    cfsetspeed(&opt, B115200); // 设置串口波特率

    opt.c_cflag |= CS8; // 8位数据位
    // opt.c_cflag &= ~PARENB; // 没有校验位
    // opt.c_cflag &= ~CSTOPB; // 1位停止位

    opt.c_cflag |= CREAD | CLOCAL;

	opt.c_cc[VMIN] = 1;	// 每次读取至少读到一个字节
	opt.c_cc[VTIME] = 0; // 读取操作不会超时

    tcflush(fd, TCIOFLUSH); // 清空当前输入/输出缓冲区数据

    ret = tcsetattr(fd, TCSANOW, &opt); // 使能串口设置
    if (ret != 0)
	{
		printf("NX applog: port set error\n");
		return -1;
	}

    /* 数据收发测试 */
    while (1) 
    {
        read(fd, &c, 1); // 
        printf("NX applog: read 0x%02x %c\n", c, c);
        write(fd, &c, 1);
    }

    close(fd);

    return 0;
}

演示

上面代码的作用是接收数据并回传,演示如下:
在这里插入图片描述

总结

串口操作总体来说并不复杂。另外虽然串口有很多可以设置的属性,但是目前很多属性已经不怎使用了,最常见需要修改的也就波特率了。

设备树文件

/*
 * Device Tree Source for NUC980 DEV board
 *
 * Copyright (C) 2018 Nuvoton Technology Corp.
 *
 * The code contained herein is licensed under the GNU General Public
 * License. You may obtain a copy of the GNU General Public License
 * Version 2 or later at the following locations:
 *
 * http://www.opensource.org/licenses/gpl-license.html
 * http://www.gnu.org/copyleft/gpl.html
 */
/dts-v1/;

#include "nuc980.dtsi"

/ {
	model = "Nuvoton NUC980 DEV V1.0";
	compatible = "nuvoton,nuc980-dev-v1.0", "nuvoton,nuc980";

	chosen {
		bootargs = "console=ttyS0,115200n8 noinitrd rootfstype=ext4 root=/dev/mmcblk0p2 rw rootwait mem=64M";
	};

	apb {
		uart1: serial@b0071000 {
			status = "okay";
		};

		uart2: serial@b0072000 {
			status = "disabled";
		};

		uart3: serial@b0073000 {
			status = "disabled";
		};

		uart4: serial@b0074000 {
			status = "disabled";
		};

		uart5: serial@b0075000 {
			status = "disabled";
		};

		uart6: serial@b0076000 {
			status = "disabled";
		};

		uart7: serial@b0077000 {
			status = "disabled";
		};

		uart8: serial@b0078000 {
			status = "disabled";
		};

		uart9: serial@b0079000 {
			status = "disabled";
		};

		can0: can@b00a0000 {
			status = "disabled";
		};

		can1: can@b00a1000 {
			status = "disabled";
		};

		rtc: rtc@b0041000 {
			status = "disabled";
		};

		gpio: gpio@b0004000 {
			pinctrl-0 = <>;
			eint2-config = <0 0 0>;
			eint3-config = <0 0 0>;
		};

		nadc: nadc@b0043000 {
			status = "disabled";
		};

		pwm0: pwm@b0058000 {
			status = "disabled";
		};

		pwm1: pwm@b0059000 {
			status = "disabled";
		};


		etimer0: etimer0@b0050000 {
			status = "disabled";
		};

		etimer1: etimer1@b0050100 {
			status = "disabled";
		};

		etimer2: etimer2@b0051000 {
			status = "disabled";
		};

		etimer3: etimer3@b0051100 {
			status = "disabled";
		};

		i2c0: i2c0@b0080000 {
			status = "disabled";
		};

		i2c1: i2c1@b0081000 {
			status = "disabled";
			pinctrl-0 = <&pinctrl_i2c1_PB>;
		};


		i2c2: i2c2@b0082000 {
			status = "disabled";
			pinctrl-0 = <&pinctrl_i2c2_PB>;
		};

	};

	ahb {

		usbh_ehci@b0015000 {
			pinctrl-0 = <>; /*disable PWREN and OVC*/
			ov_active = <1>;/*disable PWREN and OVC*/
			status = "okay";
		};
		usbh_ohci@b0017000{
			status = "okay";
		};

		usbdev@b0016000 {
			status = "okay";
		};

		fmi@b0019000 {
			status = "disabled";
		};

		sdh@b0018000 {
			status = "okay";
		};

		emac0@b0012000 {
			status = "okay";
		};
		emac1@b0022000 {
			status = "disabled";
		};
		ccap0@b0024000 {
			status = "disabled";
		};
		i2c_gpio0: i2c-gpio-0 {
			status = "disabled";
		};
		ccap1@b0014000 {
			status = "disabled";
		};
		i2c_gpio1: i2c-gpio-1 {
			status = "disabled";
		};
		dma@b0008000 {
			status = "okay";
		};

		i2s: i2s@b0020000 {
			status = "disabled";
		};

		i2s_pcm: i2s_pcm {
			status = "disabled";
		};

		sound {
			compatible = "nuvoton,nuc980-audio";
			i2s-controller = <&i2s>;
			i2s-platform = <&i2s_pcm>;
			status = "disabled";
		};
		ebi: ebi@b0010000 {
			status = "disabled";
		};
	};

	nx_node@0 {
		compatible = "nx_dts_node";
		str = "Naisu 233!";
		num = <0x00000000 0x00000020>;
	};
	
	nx_node@1 {
		compatible = "nx_dts_node";
		str = "Hello Naisu!";
		num = <0x000000 0x00000040>;
	};
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/650763.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

阿里 P8 架构师总结的 Java 面试笔记,上线仅七天,Github 标星 55K

作为一名优秀的程序员&#xff0c;技术面试是不可避免的一个环节&#xff0c;一般技术面试官都会通过自己的方式去考察程序员的技术功底与基础理论知识。 如果你参加过一些大厂面试&#xff0c;肯定会遇到一些这样的问题&#xff1a; 1、看你项目都用的框架&#xff0c;熟悉 …

AI翻唱整合

感谢阅读 不完全原创声明环境部署下载工具包安装人声背景音分离工具分离消除脏数据&#xff08;比如杂音&#xff09;准备自己的声音预处理完工效果参考 不完全原创声明 本人使用了多个第三方软件&#xff0c;并修改了一部分代码使得其可以在PC上训练&#xff0c;如有侵权请联…

看板是什么?使用看板进行任务管理有哪些好处?

看板是一个易于使用的工具&#xff0c;用于可视化和管理工作流程。 它的特点是有一列代表工作流程的各个阶段。看板卡被用来跟踪各个任务和活动在各个阶段的进展情况。 看板的两种主要类型是实体看板和数字看板。实体看板最适合办公室内、同地办公的团队。数字看板更适合远程和…

数据库MySQL学习-数据查询(持续更新中...)

MySQL数据库 MySQL是DBMS软件系统&#xff0c;通过这些系统来维护管理数据库。 DBMS类似于用于和数据库之间的桥梁。 一、安装配置 下载免费的MySQL 社区版&#xff0c;安装后需要下载MySQL workbench vscode phpmyadmin等工具来接入MySQL。 MySQL可以管理多个数据库的&…

广告数仓:数仓搭建

系列文章目录 广告数仓&#xff1a;采集通道创建 广告数仓&#xff1a;数仓搭建 文章目录 系列文章目录前言一、环境搭建1.hive安装2.编写配置文件3.拷贝jar包4.初始化源数据库5.修改字符集6.更换Spark引擎1.上传并解压spark2.修改配置文件3.在hadoop上创建需要的文件夹4.上传…

离散数学题目收集整理练习(期末过关进度10%)

✨博主&#xff1a;命运之光 &#x1f984;专栏&#xff1a;离散数学考前复习&#xff08;知识点题&#xff09; &#x1f353;专栏&#xff1a;概率论期末速成&#xff08;一套卷&#xff09; &#x1f433;专栏&#xff1a;数字电路考前复习 ✨博主的其他文章&#xff1a;点击…

观察者模式(二十)

相信自己&#xff0c;请一定要相信自己 上一章简单介绍了迭代器模式(十九), 如果没有看过, 请观看上一章 一. 观察者模式 引用 菜鸟教程里面 观察者模式介绍: https://www.runoob.com/design-pattern/observer-pattern.html 当对象间存在一对多关系时&#xff0c;则使用观察…

cef支持.net6.0

开发环境&#xff1a;vs2022,.net6.0 cef CefSharp.Common.NETCore 114.2.100 安装 Cefsharp简介 CEF &#xff0c;全称Chromium Embedded Framework &#xff0c;基于谷歌 Chromium项目的开源Web Browser控件&#xff0c;它的主要用途是嵌入了第三方应用以实现浏览器相关的功…

【C#】简单认识TransactionScope,以及常见的事务类型

在实际项目开发时&#xff0c;后端编码少不了事务处理。 为什么要用事务&#xff0c;其中一个最直接的原因就是保持数据完整性和一致性 目录 1、C#事务概念1.1、逻辑单元1.2、Transaction对象1.3、事务简单实例 2、事务场景描述3、事务流程图3.1、没有事务流程3.2、有事务流程 …

黑客是怎样练成的?

网学黑客技术的人越来越多了&#xff0c;不少人都不知道该怎么学&#xff0c;今天就来详细的说一说黑客是如何炼成的。 首先&#xff0c;什么是黑客&#xff1f; 黑客 &#xff1a;泛指擅长IT技术的电脑高手 黑客一词&#xff0c;源自英文Hacker&#xff0c;早期其实就是一群…

【MySQL】一文带你了解检索数据

&#x1f3ac; 博客主页&#xff1a;博主链接 &#x1f3a5; 本文由 M malloc 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f384; 学习专栏推荐&#xff1a;LeetCode刷题集&#xff01; &#x1f3c5; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指…

21 RBM(Restricted Boltzmann Machine)——受限玻尔兹曼机

文章目录 21 RBM(Restricted Boltzmann Machine)——受限玻尔兹曼机21.1 背景介绍22.2 RBM模型表示22.3 Inference问题22.4 Marginal问题 21 RBM(Restricted Boltzmann Machine)——受限玻尔兹曼机 21.1 背景介绍 什么是玻尔兹曼机&#xff1a; 简单来说就是具有条件的Marko…

无线蓝牙耳机排行榜,十大口碑最好蓝牙耳机

近年来&#xff0c;随着生活水平的提高&#xff0c;越来越多的人对高品质蓝牙耳机的需求日益增加。无论我们在选购什么产品&#xff0c;我们都会考虑一个价值范围&#xff0c;买蓝牙耳机也是同样&#xff0c;都会给自己一个预算&#xff0c;然后根据预算去网上搜寻这个价格范围…

【python学习】-读入xlsx文件,将datetime.time转为minute的格式,并将新数据存入csv文件

读入xlsx文件&#xff0c;将datetime.time转为minute的格式&#xff0c;并将新数据存入csv文件 任务概要思路设计代码实现导入相关库时间转换函数算法内核csv文件结果 接到一个需求&#xff0c;师兄在做稳定性测试时&#xff0c;时间显示格式为<class ‘datetime.time’>…

深入剖析 Python 函数参数传递机制及高级应用

前言 在本篇文章中&#xff0c;笔者将带你深入探讨 Python 函数传参的进阶主题。 通过阅读本篇文章&#xff0c;你可以深入了解 Python 函数传参的进阶主题&#xff0c;掌握更多高级的函数技巧&#xff0c;提升你的 Python 编程能力。 前面分享了Python 函数传参基础篇&#xf…

图像生成--对抗生成模型

生成模型概述 对抗生成模型 机器学习中的两大主要问题&#xff1a; 判别生成 判别模型的典型代表即为图像分类任务&#xff0c;即给定一个数据&#xff0c;判定他是哪一类。 判别模型学习到的是一个概率&#xff08;贝叶斯过程&#xff09; 而生成模型的区别在于&#xf…

【Elacticsearch】 原理/数据结构/面试经典问题整理

对Elacticsearch 原理/数据结构/面试经典问题整理的文章&#xff1b; 映射 | Elasticsearch: 权威指南 | Elastic Elacticsearch介绍 Elasticsearch,这里简称ES。ES是一个开源的高可用高扩展的分布式全文搜索与分析引擎&#xff0c;可以提供PB级近实时的数据存储和检索能力&am…

SpringBoot自定义starter入门

一、创建一个普通的Maven项目 pom.xml文件修改 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation&quo…

你知道如何将音频转文字吗?

我跟你们说&#xff0c;我认识一名盲人音乐人&#xff0c;他很热爱音乐创作&#xff0c;但是因为听力的限制&#xff0c;无法像其他人那样从录音中获取音乐素材。然而&#xff0c;有一天他听说了一个神奇的功能——音频转文字&#xff0c;这个功能可以将音频文件转换成文字文本…

从技术谈到管理,把系统优化的技术用到企业管理

很多技术人员在职业上对自己要求高&#xff0c;工作勤奋&#xff0c;承担越来越大的责任&#xff0c;最终得到信任&#xff0c;被提拔到管理岗位。但是往往缺乏专业的管理知识&#xff0c;在工作中不能从整体范围优化工作流程&#xff0c;仍然是“个人贡献者”的工作方式&#…