【STM32MP157应用编程】4.串口接收、发送数据

news2024/11/17 21:23:23

目录

串口文件

指令操作串口

程序操作串口

程序说明

程序代码

4_ChuanKou_2.c

启动交叉编译工具

编译

拷贝到开发板

测试

串口文件

在/dev目录下,存放了串口的文件。

文件名对应的串口
ttySTM0CH340
ttySTM1com2(公头)
ttySTM2com1(母头)
ttySTM3被开发板的蓝牙所使用(不可用)

 注意:文件名的命名只跟驱动有关。

指令操作串口

设置com1串口波特率为115200。

stty -F ttySTM2 115200

 向com1串口发送数据。

echo aaa > ttySTM2

 

 

 com1串口接收数据。

cat ttySTM2

 

程序操作串口

程序说明

参数1:串口文件序号。

        0:ttySTM0。

        1:ttySTM1。

        2:ttySTM2。

参数2:波特率。

程序代码

4_ChuanKou_2.c

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>

//./xxx 1 115200

int main(int argc, char *argv[])
{
    //检查参数个数
    if (argc != 3)
    {
        printf("%s文件的参数个数错误!\n", argv[0]);
        return -1;
    }

    //检查参数1是否为纯数字
    char *endptr;
    strtol(argv[1], &endptr, 10);
    if ((endptr == argv[1]) || ((!isspace(*endptr)) && (*endptr != '\0')))
    {
        perror("参数1错误!\n");
        return -1;
    }
    endptr = NULL;
    //检查参数2是否为纯数字
    strtol(argv[2], &endptr, 10);
    if ((endptr == argv[2]) || ((!isspace(*endptr)) && (*endptr != '\0')))
    {
        perror("参数2错误!\n");
        return -1;
    }
    //检查参数1的取值范围:<3
    if (atol(argv[1]) >= 3)
    {
        perror("参数1错误!\n");
        return -1;
    }

    char tty_path[100];
    sprintf(tty_path, "/dev/ttySTM%s", argv[1]);
    int fd = open(tty_path, O_RDWR | O_NOCTTY);
    if (fd < 0)
    {
        printf("打开%s失败!\n", tty_path);
        return -1;
    }

    //获取串口文件属性,以便于修改相应的属性
    struct termios options;
    if (tcgetattr(fd, &options) < 0)
    {
        printf("获取串口属性错误!\n");
        return -1;
    }
    //设置波特率
    if (strcmp(argv[2], "50") == 0)
    {
        cfsetispeed(&options, B50); //设置串口输入波特率
        cfsetospeed(&options, B50); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "75") == 0)
    {
        cfsetispeed(&options, B75); //设置串口输入波特率
        cfsetospeed(&options, B75); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "110") == 0)
    {
        cfsetispeed(&options, B110); //设置串口输入波特率
        cfsetospeed(&options, B110); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "134") == 0)
    {
        cfsetispeed(&options, B134); //设置串口输入波特率
        cfsetospeed(&options, B134); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "150") == 0)
    {
        cfsetispeed(&options, B150); //设置串口输入波特率
        cfsetospeed(&options, B150); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "200") == 0)
    {
        cfsetispeed(&options, B200); //设置串口输入波特率
        cfsetospeed(&options, B200); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "300") == 0)
    {
        cfsetispeed(&options, B300); //设置串口输入波特率
        cfsetospeed(&options, B300); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "600") == 0)
    {
        cfsetispeed(&options, B600); //设置串口输入波特率
        cfsetospeed(&options, B600); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "1200") == 0)
    {
        cfsetispeed(&options, B1200); //设置串口输入波特率
        cfsetospeed(&options, B1200); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "1800") == 0)
    {
        cfsetispeed(&options, B1800); //设置串口输入波特率
        cfsetospeed(&options, B1800); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "2400") == 0)
    {
        cfsetispeed(&options, B2400); //设置串口输入波特率
        cfsetospeed(&options, B2400); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "2400") == 0)
    {
        cfsetispeed(&options, B2400); //设置串口输入波特率
        cfsetospeed(&options, B2400); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "4800") == 0)
    {
        cfsetispeed(&options, B4800); //设置串口输入波特率
        cfsetospeed(&options, B4800); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "9600") == 0)
    {
        cfsetispeed(&options, B9600); //设置串口输入波特率
        cfsetospeed(&options, B9600); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "19200") == 0)
    {
        cfsetispeed(&options, B19200); //设置串口输入波特率
        cfsetospeed(&options, B19200); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "38400") == 0)
    {
        cfsetispeed(&options, B38400); //设置串口输入波特率
        cfsetospeed(&options, B38400); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "57600") == 0)
    {
        cfsetispeed(&options, B57600); //设置串口输入波特率
        cfsetospeed(&options, B57600); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "115200") == 0)
    {
        cfsetispeed(&options, B115200); //设置串口输入波特率
        cfsetospeed(&options, B115200); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "230400") == 0)
    {
        cfsetispeed(&options, B230400); //设置串口输入波特率
        cfsetospeed(&options, B230400); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "460800") == 0)
    {
        cfsetispeed(&options, B460800); //设置串口输入波特率
        cfsetospeed(&options, B460800); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "500000") == 0)
    {
        cfsetispeed(&options, B500000); //设置串口输入波特率
        cfsetospeed(&options, B500000); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "576000") == 0)
    {
        cfsetispeed(&options, B576000); //设置串口输入波特率
        cfsetospeed(&options, B576000); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "921600") == 0)
    {
        cfsetispeed(&options, B921600); //设置串口输入波特率
        cfsetospeed(&options, B921600); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "1000000") == 0)
    {
        cfsetispeed(&options, B1000000); //设置串口输入波特率
        cfsetospeed(&options, B1000000); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "1152000") == 0)
    {
        cfsetispeed(&options, B1152000); //设置串口输入波特率
        cfsetospeed(&options, B1152000); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "1500000") == 0)
    {
        cfsetispeed(&options, B1500000); //设置串口输入波特率
        cfsetospeed(&options, B1500000); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "2000000") == 0)
    {
        cfsetispeed(&options, B2000000); //设置串口输入波特率
        cfsetospeed(&options, B2000000); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "2500000") == 0)
    {
        cfsetispeed(&options, B2500000); //设置串口输入波特率
        cfsetospeed(&options, B2500000); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "3000000") == 0)
    {
        cfsetispeed(&options, B3000000); //设置串口输入波特率
        cfsetospeed(&options, B3000000); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "3500000") == 0)
    {
        cfsetispeed(&options, B3500000); //设置串口输入波特率
        cfsetospeed(&options, B3500000); //设置串口输出波特率
    }
    else if (strcmp(argv[2], "4000000") == 0)
    {
        cfsetispeed(&options, B4000000); //设置串口输入波特率
        cfsetospeed(&options, B4000000); //设置串口输出波特率
    }
    else
    {
        printf("波特率参数错误!\n");
        return -1;
    }

    //设置串口属性
    if (tcsetattr(fd, TCSANOW, &options) < 0)
    {
        printf("设置串口属性错误!\n");
        return -1;
    }
    printf("设置串口完成!\n");
    printf("串口启动!\n");

    //创建进程,读写串口功能分开
    pid_t jin_cheng = fork();
    if (jin_cheng < 0)
    {
        printf("创建进程错误!\n");
        return -1;
    }
    else if (jin_cheng == 0) //子进程
    {
        char data[1024];
        int num = 0;
        while (1)
        {
            while ((num = read(fd, &data, 1024)) != 0)
            {
                printf("读取到的数据为:%s\n", data);
                memset(data, '\0', strlen(data));
                num = 0;
                read(fd, &data, 1024); //读掉最后的停止位
            }
        }
    }
    else if (jin_cheng > 0) //父进程
    {
        char data[1024];
        while (1)
        {
            scanf("%s", data);
            getchar();
            write(fd, data, strlen(data));
            memset(data, '\0', strlen(data));
        }
    }

    close(fd);
    return 0;
}

启动交叉编译工具

source /opt/st/stm32mp1/3.1-snapshot/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi

编译

${CC} -o 4_ChuanKou_2 4_ChuanKou_2.c 

拷贝到开发板

scp 4_ChuanKou_2 root@10.3.22.219:/home/root/Linux_C_YingYong_BianCheng/JiaoCheng/4_ChuanKou/

 

测试

使用com1串口进行数据收发,设置波特率为115200。

./4_ChuanKou_2 2 115200

 发送数据。

 

 接收数据。

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

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

相关文章

java版云HIS系统源码 微服务架构支持VUE

云his系统源码 一个好的HIS系统&#xff0c;要具有开放性&#xff0c;便于扩展升级&#xff0c;增加新的功能模块&#xff0c;支撑好医院的业务的拓展&#xff0c;而且可以反过来给医院赋能&#xff0c;最终向更多的患者提供更好地服务。 私信了解更多&#xff01; 本套基于…

【C语言】结构体和共用体

目录一、结构体&#xff08;一&#xff09;结构体声明&#xff08;二&#xff09;结构体变量定义&#xff08;三&#xff09;结构体变量的初始化&#xff08;四&#xff09;结构体的引用&#xff08;五&#xff09;结构体数组二、共用体&#xff08;一&#xff09;共用体定义&a…

全球商城库存系统架构设计与实践

业务背景 商城原库存系统耦合在商品系统&#xff0c;考虑到相关业务逻辑复杂度越来越高&#xff0c;库存做了服务拆分&#xff0c;在可售库存管理的基础上新增了实物库存管理、秒杀库存、物流时效 、发货限制、分仓管理等功能&#xff0c;满足了商城库存相关业务需求。 系统架构…

GitLab 存储型XSS漏洞 (CVE-2023-0050)

漏洞描述 GitLab 是由GitLab公司开发的、基于Git的集成软件开发平台。kroki是一款集成在GitLab的基于文本的图表描述自动转为图片的开源工具&#xff0c;在GitLab 13.7引入。 由于Kroki中lib/banzai/filter/kroki_filter.rb对接收的image_src过滤不严&#xff0c;具有AsciiDo…

SpringBoot 整合 clickhouse和mysql 手把手教程全网最详细

最近做一个项目 需要 整合mysql clickhouse 多数据源 后台用的是ruoyi框架 1. 首先pom引入相关依赖 <!--JDBC-clickhouse数据库--><dependency><groupId>com.clickhouse</groupId><artifactId>clickhouse-jdbc</artifactId><version&…

Homekit智能家居产品---智能吸顶灯

买灯要看什么因素 好灯具的灯光可以说是家居的“魔术师”&#xff0c;除了实用的照明功能外&#xff0c;对细节的把控也非常到位。那么该如何选到一款各方面合适的灯呢&#xff1f; 照度 可以简单理解为清晰度&#xff0c;复杂点套公式来说照度光通量&#xff08;亮度&#x…

5款小巧好用的电脑软件,让你的工作生活更加高效!

不得不说良心好软件让大家好评连连&#xff0c;爱不释手&#xff0c;不像某些软件自带广告弹窗。这期就由我给大家安利几款电脑中的得力助手&#xff0c;看看你都用过几个&#xff1f; 1.桌面管理神器——Coodesker Coodesker是一款免费小巧、无广告&#xff0c;功能简单的桌…

【Redis】哨兵机制(三)

目录 3.Redis哨兵 3.1.哨兵原理 3.1.1.集群结构和作用 3.1.2.集群监控原理 3.1.3.集群故障恢复原理 3.1.4.小结 3.2.搭建哨兵集群 3.3.RedisTemplate 3.3.1.导入Demo工程 3.3.2.引入依赖 3.3.3.配置Redis地址 3.3.4.配置读写分离 3.Redis哨兵 Redis提供了哨兵&am…

Spring Cloud Gateway学习

文章大纲 为什么需要网关&#xff1f; 传统的单体架构只有一个服务开放给客户端调用&#xff0c;但是在微服务架构体系中是将一个系统拆分成多个微服务&#xff0c;那么作为客户端如何去调用这些微服务呢&#xff1f;如果没有网关的存在&#xff0c;就只能在本地记录每个微服务…

彻底关闭Windows10更新!!

以下四个步骤都需要执行。 一、禁用Windows Update服务 1、同时按下键盘 Win R&#xff0c;然后输入 services.msc &#xff0c;点击确定。 2、找到 Windows Update 这一项&#xff0c;并双击打开。 3、双击打开它&#xff0c;点击 停止&#xff0c;把启动类型选为 禁用&…

SpringBoot+@Async注解-异步调用

编程开发里&#xff0c;使用java异步执行方法可以让程序同时处理多个请求业务&#xff0c;提升吞吐量来缩短业务的执行时间&#xff0c;在springboot的程序应用中&#xff0c;提供了Async注解来实现异步执行方法。在业务开发中&#xff0c;有些时候是不需要立即返回业务的处理结…

前端代码质量-圈复杂度原理和实践

1. 导读 你们是否也有过下面的想法&#xff1f; 重构一个项目还不如新开发一个项目…这代码是谁写的&#xff0c;我真想… 你们的项目中是否也存在下面的问题&#xff1f; 单个项目也越来越庞大&#xff0c;团队成员代码风格不一致&#xff0c;无法对整体的代码质量做全面的…

【LeetCode】剑指 Offer 25. 合并两个排序的链表 p145 -- Java Version

题目链接&#xff1a;https://leetcode.cn/problems/he-bing-liang-ge-pai-xu-de-lian-biao-lcof/ 1. 题目介绍&#xff08;25. 合并两个排序的链表&#xff09; 输入两个递增排序的链表&#xff0c;合并这两个链表并使新链表中的节点仍然是递增排序的。 【测试用例】&#xf…

软件测试分类知识分享,第三方软件测试机构收费贵不贵?

软件测试可以很好的检验软件产品的质量以及规避产品上线之后可能会发生的错误&#xff0c;随着技术的发展&#xff0c;软件测试已经是一个完整且体系庞大的测试活动&#xff0c;不同的测试领域有着不同的测试方法、技术与名称&#xff0c;那么具体有哪些分类呢? 一、软件测试…

centos7部署KVM虚拟化

目录 centos7部署KVM虚拟化平台 1、新建一台虚拟机 2、系统内的操作 1、修改主机名 2、挂载镜像光盘 3、ssh优化 4、设置本地yum仓库 5、关闭防火墙&#xff0c;selinux 3、安装KVM 4、设置KVM网络 5、KVM部署与管理 6、使用虚拟系统管理器管理虚拟机 创建存储池 …

[曾经沧海难为水]两数求和

本来可以面试成功就差HR面试了&#xff0c;现在给我说恒英也要机试题了。我现在肝机试题吧&#xff01;大环境就是这&#xff0c;记录两周一个机试学习过程V1&#xff1a;自己写的暴力法V2&#xff1a;暴力法2:通过python的**str in list**方式逐个遍历&#xff0c;虽然代码看似…

什么叫GPC爬虫池?

什么叫GPC爬虫池&#xff1f; 答案是&#xff1a;全称光算谷歌爬虫池。 GPC爬虫池是一个深度研究谷歌SEO规律算法而创造的一种吸引谷歌爬虫的技术手段。 主要实现原理是通过建设庞大的站群系统&#xff0c;复杂的内链&#xff0c;外链结构体系&#xff0c;起到吸引谷歌爬虫&…

NetworkMiner网络取证分析工具(26)

预备知识 NetworkMiner是一款windows平台下开放源代码的网络取证分析工具&#xff0c;同时也是一款比较好的协议分析工具&#xff0c;它通过数据包嗅探或解析PCAP 文件能够检测操作系统&#xff0c;主机名和网络主机开放的端口。 除了能够进行基本的数据包抓取分析N…

剑指 Offer day5, day6

剑指 Offer day5&#xff0c; day6 二分查找和二叉树的题目 剑指 Offer 04. 二维数组中的查找 剑指 Offer 04. 二维数组中的查找 - 力扣&#xff08;Leetcode&#xff09; 依然是利用特殊的数据状况改进查找的速度&#xff0c;注意边界条件。 题解这个类比二叉树的思路非常…

第五章:C语言数据结构与算法之双向带头循环链表

系列文章目录 文章目录系列文章目录前言一、哨兵位的头节点二、双向链表的结点三、接口函数的实现1、创建结点2、初始化3、尾插与尾删4、头插与头删5、打印6、查找7、随机插入与随机删除8、判空、长度与销毁四、顺序表和链表的对比总结前言 一般题目给的单链表是无头单向非循环…