Linux串口应用编程——STM32MP157

news2024/11/24 3:23:09

文章目录

  • 替换设备树文件
  • 串口API
    • 设置行规程
      • struct termios 结构体
      • 行规程函数
  • 串口应用——回环

替换设备树文件

挂载boot分区:

mount /dev/mmcblk2 /boot

拷贝新的设备树文件到boot分区

cp /mnt/stm32mp157c-100ask-512d-lcd-v1.dtb /boot

reboot重启,查询设备节点

ls /dev/ttySTM*

发现新的设备节点ttySTM3

/dev/ttySTM0  /dev/ttySTM1  /dev/ttySTM3

设备树开启串口8的原理就是通过Pinctrl指定芯片连接的扩展板引脚,涉及到驱动方面的知识,具体查看视频:修改设备树,开启串口驱动

串口API

在 Linux 系统中,操作设备的统一接口就是:open/ioctl/read/write。
对于 UART,又在 ioctl 之上封装了很多函数,主要是用来设置行规程。所以对于 UART,编程的套路就是:

  • open;
  • 设置行规程,比如波特率、数据位、停止位、检验位、RAW 模式、一有数据就返回;
  • read/write;

在这里插入图片描述

行规程采用默认模式时,需要按下enter键才能执行上传

设置行规程

struct termios 结构体

在这里插入图片描述
该结构体主要用于与驱动进行通信的载体

行规程函数

函数名作用
tcgetattrget terminal attributes,获得终端的属性
tcsetattrset terminal attributes,修改终端参数
tcflush清空终端未完成的输入/输出请求及数据
cfsetispeedsets the input baud rate,设置输入波特率
cfsetospeedsets the output baud rate,设置输出波特率
cfsetspeed同时设置输入、输出波特率

这些函数在名称上有一些惯例:

  • tc:terminal contorl
  • cf: control flag

串口应用——回环

接线
在这里插入图片描述
代码:

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <stdlib.h>

/* set_opt(fd,115200,8,'N',1) */
int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)
{
	struct termios newtio,oldtio;
	//获取默认的参数,保存在oldtio结构体中
	if ( tcgetattr( fd,&oldtio) != 0) { 
		perror("SetupSerial 1");
		return -1;
	}
	
	bzero( &newtio, sizeof( newtio ) );
	newtio.c_cflag |= CLOCAL | CREAD; 
	newtio.c_cflag &= ~CSIZE; 

	newtio.c_lflag  &= ~(ICANON | ECHO | ECHOE | ISIG);  /*Input*/
	newtio.c_oflag  &= ~OPOST;   /*Output*/

	switch( nBits )
	{
	case 7:
		newtio.c_cflag |= CS7;
	break;
	case 8:
		newtio.c_cflag |= CS8;
	break;
	}

	switch( nEvent )
	{
	case 'O':
		newtio.c_cflag |= PARENB;
		newtio.c_cflag |= PARODD;
		newtio.c_iflag |= (INPCK | ISTRIP);
	break;
	case 'E': 
		newtio.c_iflag |= (INPCK | ISTRIP);
		newtio.c_cflag |= PARENB;
		newtio.c_cflag &= ~PARODD;
	break;
	case 'N': 
		newtio.c_cflag &= ~PARENB;
	break;
	}

	switch( nSpeed )
	{
	case 2400:
		cfsetispeed(&newtio, B2400);
		cfsetospeed(&newtio, B2400);
	break;
	case 4800:
		cfsetispeed(&newtio, B4800);
		cfsetospeed(&newtio, B4800);
	break;
	case 9600:
		cfsetispeed(&newtio, B9600);
		cfsetospeed(&newtio, B9600);
	break;
	case 115200:
		cfsetispeed(&newtio, B115200);
		cfsetospeed(&newtio, B115200);
	break;
	default:
		cfsetispeed(&newtio, B9600);
		cfsetospeed(&newtio, B9600);
	break;
	}
	
	if( nStop == 1 )
		newtio.c_cflag &= ~CSTOPB;
	else if ( nStop == 2 )
		newtio.c_cflag |= CSTOPB;
	
	newtio.c_cc[VMIN]  = 1;  /* 读数据时的最小字节数: 没读到这些数据我就不返回! */
	newtio.c_cc[VTIME] = 0; /* 等待第1个数据的时间: 
	                         * 比如VMIN设为10表示至少读到10个数据才返回,
	                         * 但是没有数据总不能一直等吧? 可以设置VTIME(单位是10秒)
	                         * 假设VTIME=1,表示: 
	                         *    10秒内一个数据都没有的话就返回
	                         *    如果10秒内至少读到了1个字节,那就继续等待,完全读到VMIN个数据再返回
	                         */

	tcflush(fd,TCIFLUSH);
	//通过该结构体设置行规程
	if((tcsetattr(fd,TCSANOW,&newtio))!=0)
	{
		perror("com set error");
		return -1;
	}
	//printf("set done!\n");
	return 0;
}

int open_port(char *com)
{
	int fd;
	//fd = open(com, O_RDWR|O_NOCTTY|O_NDELAY);
	fd = open(com, O_RDWR|O_NOCTTY);//O_NOCTTY表示不设置为控制终端,不会接收控制信号
    if (-1 == fd){
		return(-1);
    }
	
	  if(fcntl(fd, F_SETFL, 0)<0) /* 设置串口为阻塞状态,若第三个参数为FNDELAY则表示没有数据返回0*/
	  {
			printf("fcntl failed!\n");
			return -1;
	  }
  
	  return fd;
}


/*
 * ./serial_send_recv <dev>
 */
int main(int argc, char **argv)
{
	int fd;
	int iRet;
	char c;

	/* 1. open */

	/* 2. setup 
	 * 115200,8N1
	 * RAW mode
	 * return data immediately
	 */

	/* 3. write and read */
	
	if (argc != 2)
	{
		printf("Usage: \n");
		printf("%s </dev/ttySAC1 or other>\n", argv[0]);
		return -1;
	}

	fd = open_port(argv[1]);
	if (fd < 0)
	{
		printf("open %s err!\n", argv[1]);
		return -1;
	}

	iRet = set_opt(fd, 115200, 8, 'N', 1);
	if (iRet)
	{
		printf("set port err!\n");
		return -1;
	}

	printf("Enter a char: ");
	while (1)
	{
		scanf("%c", &c);
		iRet = write(fd, &c, 1);
		iRet = read(fd, &c, 1);
		if (iRet == 1)
			printf("get: %02x %c\n", c, c);
		else
			printf("can not get data\n");
	}

	return 0;
}

参考博文:
Linux串口—struct termios结构体
Linux串口编程

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

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

相关文章

C++ set和map使用

搜索平衡二叉树的封装 1. 关联容器2. 键值对3. 树形结构的关联式容器3.1 set3.1.1 set介绍3.1.2 set 的使用1. set模板参数列表2. set的构造3. set 的迭代器4. set的容量5. set修改5. set的使用 3.2 multiset3.2.1 multiset的介绍3.2.1 multiset的使用 3.3 map3.3.1 map的介绍3…

Could not load the Qt platform plugin “xcb“

qt.core.plugin.loader: QLibraryPrivate::loadPlugin failed on “/home/ly/Qt/6.5.1/gcc_64/plugins/platforms/libqxcb.so” : “Cannot load library /home/ly/Qt/6.5.1/gcc_64/plugins/platforms/libqxcb.so: (libxcb-cursor.so.0: cannot open shared object file: No su…

VTK8.2手动卸载

利用源代码方式安装的VTK, 进行手动卸载[参考] 1、进入.. /VTK-8.2.0/build目录 make2、记录sudo make install的log log在uninstall.sh文件中 touch uninstall.sh && chmod 775 uninstall.sh && echo #!/bin/bash -v > uninstall.sh && sudo m…

【unity实战】制作俯视角射击游戏多种射击效果(一)

文章目录 本期目标前言欣赏开始1. 角色移动和场景搭建2. 绑定枪械2.1 首先将各种枪械的素材添加给人物作为子物体2.2 给枪械也分别添加两个子物体用作标记枪口和弹仓位置 3. 枪械动画4. 切换枪械5. 发射功能5.1 手枪(1) 枪械随着鼠标旋转(2) 射击时间间隔(3) 创建好子弹、弹壳和…

手把手教你如何做手机PCB电磁兼容性设计

电磁兼容性是指电子设备在各种电磁环境中仍能够协调、有效地进行工作的能力。电磁兼容性设计的目的是使电子设备既能抑制各种外来的干扰&#xff0c;使电子设备在特定的电磁环境中能够正常工作&#xff0c;同时又能减少电子设备本身对其它电子设备的电磁干扰。 1、选择合理的导…

【霹雳吧啦Wz】Transformer中Self-Attention以及Multi-Head Attention详解

文章目录 来源Transformer起源Self-Attention1. 求q、k、v2. 计算 a ^ ( s o f t m a x 那块 ) \hat{a} (softmax那块) a^(softmax那块)3. 乘V&#xff0c;计算结果 Multi-Head Attention位置编码 来源 b站视频 前天啥也不懂的时候点开来一看&#xff0c;各种模型和公式&#…

FreeRTOS 低功耗模式设计 STM32平台

1. STM32F105RBT6 的三种低功耗模式 1.1 sleep睡眠模式、stop停机模式、standby 待机模式 1.2 STM32中文参考手册有介绍STM32 低功耗模式的介绍 2. FreeRTOS 采用的是时间片轮转的抢占式任务调度机制&#xff0c;其低功耗设计思路一般是&#xff1a; ① 当运行空闲任务&#…

启动网站调试提示 HTTP 错误 403.14 – Forbidden Web 服务器被配置为不列出此目录的内容。

启动网站调试提示 HTTP 错误 403.14 – Forbidden Web 服务器被配置为不列出此目录的内容。 解决方案第一种.在网站的配置文件里添加第二种.ISS管理界面修改 解决方案 第一种.在网站的配置文件里添加 <system.webServer><directoryBrowse enabled"true" /&…

【RH850/U2A】:休眠唤醒

休眠唤醒 唤醒差异休眠差异休眠是解决整个系统待机时尽可能的减少功耗,相应的唤醒则是低功耗模式下整个系统可以被已知的条件唤醒系统,进而进入全功能模式。 RH850/U2A的配置和RH850/F1KM大同小异,本文只讲述差异部分,其他部分详见 【Davinci开发】:IO唤醒系统 唤醒差异 …

API验证器,帮助ReSharper开启VS插件新时代!

实质上&#xff0c;ReSharper特征可用于C#&#xff0c;VB.net&#xff0c;XML&#xff0c;Asp.net&#xff0c;XAML&#xff0c;和构建脚本。 使用ReSharper&#xff0c;你可以进行深度代码分析&#xff0c;智能代码协助&#xff0c;实时错误代码高亮显示&#xff0c;解决方案范…

WideNet:让网络更宽而不是更深

这是新加坡国立大学在2022 aaai发布的一篇论文。WideNet是一种参数有效的框架&#xff0c;它的方向是更宽而不是更深。通过混合专家(MoE)代替前馈网络(FFN)&#xff0c;使模型沿宽度缩放。使用单独LN用于转换各种语义表示&#xff0c;而不是共享权重。 混合专家(MoEs) 条件计…

STM32 串口代码配置

一、首先开发板上关于串口1的引脚配置已经配置好了&#xff0c;位置在SYSTEM的 usart.c 文件中&#xff08;注意&#xff1a;只配置了串口1的&#xff0c;其他使用时需要自己配置&#xff09; 重要的是明白配置的参数都是什么意思&#xff0c;针对实现不同的串口功能有什么影响…

入门Python笔记(基础)

入门Python笔记 入门Python笔记(基础)1. Python的特点2. Python安装3. Python中的数据类型3.1 数字类型3.1.1 整数类型3.1.2 浮点类型3.1.3 复数类型3.1.4 布尔类型 3.2 数字类型的相互转换 4. 运算符4.1 算术运算符4.2 比较运算符4.3 逻辑运算符4.4 位运算符4.5 赋值运算符4.6…

基于Java SpringBoot和Vue UniAPP的微信商城小程序

摘要 近年来&#xff0c;随着我国网络基础设施的不断完善和信息技术的不断发展&#xff0c;第三方支付手段得到了广泛的普及&#xff0c;网上购物已经成为人们生活中的重要内容&#xff0c;基于PC平台的网上商城系统可以足不出户就可以享受购物。 基于手机的网购微信小程序发挥…

Spark学习--1、Spark入门(Spark概述、Spark部署、Local模式、Standalone模式、Yarn模式)

1、Spark概述 1.1 什么是Spark Spark是一个基于内存的快速、通用、可扩展的大数据分析计算引擎。 1.2 Hadoop和Spark历史 Hadoop的Yarn框架比Spark框架诞生的晚&#xff0c;所以Spark自己也设计了一套资源调度框架。 1.3 Hadoop和Spark框架对比 1.4 Spark内置模块 模块名作…

前端Vue自定义轮播图视频播放组件 仿京东商品详情轮播图视频Video播放效果 可图片预览

前端Vue自定义轮播图视频播放组件 仿京东商品详情轮播图视频Video播放 &#xff0c;可图片预览&#xff0c;下载完整代码请访问uni-app插件市场地址&#xff1a;https://ext.dcloud.net.cn/plugin?id13325 效果图如下: # cc-videoSwiper #### 使用方法 使用方法 <!-- g…

怎么学习PHP会话管理和用户认证? - 易智编译EaseEditing

学习PHP会话管理和用户认证可以按照以下步骤进行&#xff1a; 理解基本概念&#xff1a; 首先&#xff0c;了解会话管理和用户认证的基本概念和原理。会话管理涉及在Web应用程序中跟踪用户状态和数据的技术&#xff0c;而用户认证涉及验证用户身份的过程。 学习PHP的会话管理…

telnet登录ARM开发板

telnet远程登录ARM开发板 1、ARM开发板中telnet设置2、ubuntu登录开发板 Telnet协议是TCP/IP协议族中的一员&#xff0c;是Internet远程登录服务的标准协议和主要方式。它为用户提供了在本地计算机上完成远程主机工作的能力。在终端使用者的电脑上使用telnet程序&#xff0c;用…

2023年7月8日(星期六):骑行小空山

2023年7月8日(星期六)&#xff1a;骑行小空山&#xff0c;早8:30到9:00&#xff0c; 昆明氧气厂门囗红绿灯下&#xff08;学府路和普吉路交叉路囗&#xff09;&#xff0c;9:30点准时出发 【因迟到者&#xff0c;骑行速度快者&#xff0c;可自行追赶偶遇。】 偶遇地点: 昆明氧…

Mysql,使用 UNION ALL 处理 ‘无中生有‘ 的数据。

在日常的开发工作中&#xff0c;有时我们需要在SQL层面添加一些数据库表中没有的数据&#xff0c;那么我们就可以使用 UNION ALL 关键字来解决。 一、简单的无中生有&#xff1a;在查询返回结果中添加数据 以下方的SQL1为例&#xff0c;我们根据 id 查询 user 表中的数据&#…