树莓派的的串口通信协议

首先,回顾一下串口的核心知识点,也是面试重点

  • 串口通信通常使用在多机通讯中
  • 串口通信是全双工的
  • 决定串口通信的成功与否的是 数据格式 和 波特率
  • 数据格式:1. 数据位 2.停止位 3. 奇偶校验位

树莓派恢复串口

回忆前几节树莓派刷机的开端,为了能通过串口连接到树莓派,事先将串口设置为了系统交互的方式,这会导致无法进行正常的串口的开发,况且现在已经成功可以使用SSH登录,所以可以将串口设置回来了:

  • 修改 /boot/cmdline.txt:
1. sudo vi /boot/cmdline.txt
2. 将“console=serial,115200”删除

  • sudo reboot重启 

设置完成!

树莓派的串口开发

再打开串口后,由于都是基于wiringPi库,所以串口开发和香橙派的也是一样一样的,这里我直接把在香橙派写好的串口开发文件上传过来然后直接开始写:

(注意,树莓派的串口驱动文件是/dev/下的ttyAMA0

mjm_uart_tool.c:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "wiringSerial.h"int myserialOpen (const char *device, const int baud)
{struct termios options ;speed_t myBaud ;int status, fd ;switch (baud){case 9600: myBaud = B9600 ; break ;case 115200: myBaud = B115200 ; break ;}if ((fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1)return -1 ;fcntl (fd, F_SETFL, O_RDWR) ;// Get and modify current options:tcgetattr (fd, &options) ;cfmakeraw (&options) ;cfsetispeed (&options, myBaud) ;cfsetospeed (&options, myBaud) ;options.c_cflag |= (CLOCAL | CREAD) ;options.c_cflag &= ~PARENB ;options.c_cflag &= ~CSTOPB ;options.c_cflag &= ~CSIZE ;options.c_cflag |= CS8 ;options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG) ;options.c_oflag &= ~OPOST ;options.c_cc [VMIN] = 0 ;options.c_cc [VTIME] = 100 ; // Ten seconds (100 deciseconds)tcsetattr (fd, TCSANOW, &options) ;ioctl (fd, TIOCMGET, &status);status |= TIOCM_DTR ;status |= TIOCM_RTS ;ioctl (fd, TIOCMSET, &status);usleep (10000) ; // 10mSreturn fd ;
}void serialSendstring (const int fd, const char *s)
{int ret;ret = write (fd, s, strlen (s));if (ret < 0)printf("Serial Puts Error\n");
}int serialGetstring (const int fd, char *buffer)
{int n_read;n_read = read(fd, buffer,32);return n_read;
}int serialDataAvail (const int fd)
{int result ;if (ioctl (fd, FIONREAD, &result) == -1)return -1 ;return result ;
}

mjm_uart_tool.h:

int myserialOpen (const char *device, const int baud);
void serialSendstring (const int fd, const char *s);
int serialGetstring (const int fd, char *buffer);
int serialDataAvail (const int fd);

serial_mjm_test.c:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
#include "mjm_uart_tool.h"void *write_serial(void *arg)
{char *sendbuf;sendbuf = (char *)malloc(32*sizeof(char));while(1){memset(sendbuf,'\0',32*sizeof(char));fgets(sendbuf,sizeof(sendbuf),stdin);serialSendstring (*((int *)arg), sendbuf) ;}pthread_exit(NULL);}void *read_serial(void *arg)
{char readbuf[32] = {'\0'};while(1){while(serialDataAvail (*((int *)arg))){serialGetstring (*((int *)arg),readbuf) ;printf("-> %s\n",readbuf);memset(readbuf,'\0',32);}}pthread_exit(NULL);
}int main ()
{int fd ;int ret;pthread_t read_thread;pthread_t write_thread;if ((fd = myserialOpen ("/dev/ttyAMA0", 115200)) < 0) //打开驱动文件,配置波特率{fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ;return 1 ;}/*	if (wiringPiSetup () == -1){fprintf (stdout, "Unable to start wiringPi: %s\n", strerror (errno)) ;return 1 ;}*/ret = pthread_create(&read_thread,NULL,read_serial,(void *)&fd);if(ret != 0){printf("read_serial create error\n");return 1;}ret = pthread_create(&write_thread,NULL,write_serial,(void *)&fd);if(ret != 0){printf("write_serial create error\n");return 1;}pthread_join(read_thread,NULL);pthread_join(write_thread,NULL);return 0 ;
}

编译

由于此处实现的串口函数是我参考wiringPi库自己实现的,所以无需链wiringPi库,只需链线程库就ok

gcc serial_mjm_test.c mjm_uart_tool.c -lpthread

运行效果

可见,轻松的实现了通讯效果!

封装动态库 

由于这里使用的是我自己封装的串口函数,所以可以根据上上节的知识将它封装成动态库:

详见我之前的博文:

使用树莓派学习Linux系统编程的 --- 库编程(面试重点)-CSDN博客

  • 生成动态库,命名为“mjmserial
gcc -shared -fpic mjm_uart_tool.c -o libmjmserial.so
  •  编译main函数所在C文件,链库,将可执行文件命名为“serialtest”:
gcc serial_mjm_test.c -L ./ -lmjmserial -lpthread -o serialtest
  • 此时可以使用环境变量的方法指定动态库搜索路径或者直接复制动态库到/usr/lib下,由于后者上节实现过了,这次尝试前者:

写一个脚本:

1. vi serialtest.sh
2. 内容为:“
export LD_LIBRARY_PATH="/home/pi/mjm_code/"./serialtest”
3. chmod +x serialtest.sh

  • 最后直接执行“ ./serialtest.sh ”:

可见,运行成功! 此时我只需要提供动态库的.so文件和.h文件给别人,别人就可以调用我封装好的串口函数了,并且别人无法看到我封装函数的具体实现

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

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

相关文章

Vue3 配置全局 scss 变量

variables.scss $color: #0c8ce9;vite.config.ts // 全局css变量css: {preprocessorOptions: {scss: {additionalData: import "/styles/variables.scss";,},},},.vue 文件使用

AI大发展:人机交互、智能生活全解析

目录 ​编辑 人工智能对我们的生活影响有多大 人工智能的应用领域 一、机器学习与深度学习 二、计算机视觉 三、自然语言处理 四、机器人技术 五、智能推荐系统 六、智能城市和智能家居 ​编辑 自己对人工智能的应用 自己的人工智能看法&#xff1a;以ChatGPT为例 …

一种全新且灵活的 Prompt 对齐优化技术

并非所有人都熟知如何与 LLM 进行高效交流。 一种方案是&#xff0c;人向模型对齐。 于是有了 「Prompt工程师」这一岗位&#xff0c;专门撰写适配 LLM 的 Prompt&#xff0c;从而让模型能够更好地生成内容。 而另一种更为有效的方案则是&#xff0c;让模型向人对齐。 这也是…

分布式任务调度-XXL-job

目录 源码仓库地址 前置环境 docker容器环境配置 连接linux数据库&#xff0c;并创建任务调度所用到的数据库xxl-job。 用到的表sql 打开映射网址 后端配置使用任务调度 依赖 yml配置 使用架构 config配置 job使用 快速入门使用 任务调度执行器 任务调度执行管理​编…

ck 配置 clickhouse-jdbc-bridge

背景 ck可以用过clickhouse-jdbc-bridge技术来直接访问各数据库 安装配置 需要准备的文件 clickhouse-jdbc-bridge https://github.com/ClickHouse/clickhouse-jdbc-bridge 理论上需要下载源码然后用mavne打包&#xff0c;但提供了打包好的&#xff0c;可以推测用的是mave…

USART的标准库编程

使用USART与计算机通信 电脑上只有usb端口 没有TX 和RX需要一个USB转TTL电平模块来实现通信 芯片C8T6中只有三个UASRT 选其中一个UASRT来通信即可 那么如何定位那个USART的TX 和RX引脚呢&#xff1f; 方式1 查找最小系统板引脚分布图 查找USART1的引脚 RTS CTS是硬件流控 CK…

C练习题_15

一、单项选择题(本大题共20小题&#xff0c;每小题2分&#xff0c;共40分。在每小题给出的四个备选项中&#xff0c;选出一个正确的答案,并将所选项前的字母填写在答题纸的相应位置上。) 在下列说法中&#xff0c;&#xff08;&#xff09;是正确的。 A.C程序从第一个函数开始…

Cache学习(1):常见的程序运行模型多级Cache存储结构

0 背景&#xff1a;常见的程序运行模型&#xff08;为什么要Cache&#xff09; 主存&#xff1a;Main Memory&#xff0c;硬件实现为RAM&#xff0c;产品形态&#xff1a;DDR&#xff08;例如&#xff1a; DDR3、DDR4等&#xff09;磁盘设备&#xff1a;Flash Memory&#xff…

IDEA如何将本地项目推送到GitHub上?

大家好&#xff0c;我是G探险者。 IntelliJ IDEA 是一个强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;它支持多种编程语言和工具。它也内置了对Git和GitHub的支持&#xff0c;让开发者可以轻松地将本地项目推送到GitHub上。以下是一个操作手册&#xff0c;描述了…

Ubuntu下载离线安装包

旧版Ubuntu下载地址 https://old-releases.ubuntu.com/releases/ 下载离线包 sudo apt-get --download-only -odir::cache/ncayu install net-tools下载snmp离线安装包 sudo apt-get --download-only -odir::cache/root/snmp install snmp snmpd snmp-mibs-downloadersudo a…

idea开发jface、swt环境搭建

背景 jface、swt很难找到合适的maven仓库来下载配套的版本idea对eclipse套件不友好eclipse的windowbuilder固然很好&#xff0c; 但本人更喜欢idea编程&#xff0c; 互相取长补短 下载套件 进入swt下载界面 以当前最新的4.29为例&#xff0c; 点击&#xff1a; 找到全部并…

【brpc学习实践四】异步请求案例详解

注意 使用的还是源码的案例&#xff0c;添加个人注解。在前面的篇章我们讲解了客户端、服务端rpc构造的基本流程及同步、异步的案例基础之后&#xff0c;再理解此案例就容易了。 想直接看案例实现请看&#xff1a; server端实现 client端实现 服务端要点概览 controller ser…

2022最新版-李宏毅机器学习深度学习课程-P49 GPT的野望

GPT→类似于Transformer Encoder 训练任务&#xff1a;Predict Next Token 使用MASK-attention&#xff0c;不断预测“下一个token”。 可以用GPT生成文章。 How to use GPT? 给出描述和例子 给出前半段&#xff0c;补上后半段 In-context Learning(no GD) 结果 目前看起…

vue3 uniapp h5 安卓和iOS开发适配踩坑记录

font-size适配屏幕大小及iOS和安卓状态栏及安全距离的处理 App.vue <script setup lang"ts"> import { onLaunch, onShow, onHide } from "dcloudio/uni-app"; import ./main.scss onLaunch(() > {console.log("App Launch");var wid…

广西桂林钢结构钣金折弯件3d扫描全尺寸偏差检测-CASAIM中科广电

钣金是一种针对金属薄板&#xff08;通常在6mm以下&#xff09;的综合冷加工工艺&#xff0c;包括剪、冲/切/复合、折、焊接、铆接、拼接、成型&#xff08;如汽车车身&#xff09;等&#xff0c;其显著的特征就是同一零件厚度一致&#xff0c;通过钣金工艺加工出的产品叫做钣金…

uni-app:实现request请求的递归(设置request请求的访问次数),并且调用自定义方法给出返回值

一、效果展示 失败效果 成功效果 二、写入后端请求部分 分析 ①自定义一个模块common.js主要用于封装所有的请求函数 ②核心代码 function requestWithRetry(cmd, username, password, retryCount) {return new Promise((resolve, reject) > {uni.request({url: ip sys…

Openlayer【三】—— 绘制多边形GeoJson边界绘制

1.1、绘制多边形 在绘制多边形和前面绘制线有异曲同工之妙&#xff0c;多边形本质上就是由多个点组成的线然后连接组成的面&#xff0c;这个面就是最终的结果&#xff0c;那么这里使用到的是Polygon对象&#xff0c;而传给这个对象的值也是多个坐标&#xff0c;坐标会一个个的…

抖音本地生活服务商申请怎么做?无保证金的申请方法来了

想做抖音的本地生活服务项目&#xff0c;却不知道去哪里申请&#xff0c;或者如何申请&#xff0c;其实&#xff0c;官方的通道在今年上半年还是有的&#xff0c;自己去平台上提交资料申请就可以了&#xff0c;但需要缴纳高额的保证金。 而在今年下半年&#xff0c;平台已经关…

揭秘MySQL SLEEP()函数:避免这些常见误区,不再被时间迷惑!

点击上方蓝字关注我 关于MySQL sleep()函数&#xff0c;很多同学会觉得这个很简单&#xff0c;但是在和研发同学沟通时发现&#xff0c;很多人对此函数存在误解&#xff0c;本文举3个典型的例子进行说明。 1.误区一 以下SQL的运行结果是什么样的 SELECT NOW(),SLEEP(2),NOW()&a…

redis的数据类型的增删改查

redis的高可用 在集群中有一个非常重要的指标&#xff0c;提供服务的时间的百分比&#xff08;365天&#xff09;99.9% redis的高可用含义更加宽泛&#xff0c;正常服务是指标之一&#xff0c;数据容量的扩展&#xff0c;数据的安全性 在redis中实现高可用技术 持久化&…