【树莓派】用于处理 I2C、SPI 和 UART 的C++库

一、说明

        Raspberry Pi 是一款单板计算机,现在有 4 个修订版和一个简约的零变体。它是不同项目的热门选择,因为它体积小,功耗高,处理速度快,并且是一台完整的基于Linux的计算机。

        连接多台单板计算机和/或微控制器的一种方法是直接布线。为此,最常用的协议是I2C,SPI和UART。博客系列的前几篇文章解释了这些协议的原理,并介绍了Arduino的特定C库。在本文中,我将解释C++能够在 Raspberry Pi 上使用这些协议的库。对于每个协议,我研究了可用的库,并给出了一个简短的解释和代码示例。请不要说这些示例不是我开发的,而是来自库文档,应该作为具体工作示例的基础。

这篇文章最初出现在我的博客 admantium.com。

二、I2C

        借助 SMBus 协议可以支持 I2C,该协议被描述为 I2C 总线的特定变体。此协议可作为 Linux 内核模块使用。要使用它,您需要配置树莓派。在终端中,运行 、 选择 和 。raspi-config3 Interfacing OptionsP5 I2C

        按照 kernel.org 中的代码示例,您需要打开表示连接的 I2C 设备的设备文件,然后通过写入设备寄存器来发送 SMBus 命令。

// SOURCE: https://www.kernel.org/doc/Documentation/i2c/dev-interface */
#include <linux/i2c-dev.h>
#include <i2c/smbus.h>int file;
int adapter_nr = 2;
char filename[20];snprintf(filename, 19, "/dev/i2c-%d", adapter_nr);
file = open(filename, O_RDWR);
if (file < 0) {exit(1);
}  int addr = 0x40;if (ioctl(file, I2C_SLAVE, addr) < 0) {exit(1);
}__u8 reg = 0x10;
__s32 res;
char buf[10];res = i2c_smbus_read_word_data(file, reg);
if (res < 0) {/* ERROR HANDLING: i2c transaction failed */
} else {/* res contains the read word */
}buf[0] = reg;
buf[1] = 0x43;
buf[2] = 0x65;
if (write(file, buf, 3) != 3) {/* ERROR HANDLING: i2c transaction failed */
} 

三、SPI

        要使用 SPI,您还需要添加一个特定的内核模块:Spidev。树莓派支持此模块,需要通过调用来配置它,然后选择 和 。raspi-config3 Interfacing OptionsP4 SPI

        要使用 C/C++ 访问 SPI 函数,可以使用 spidev 包装器库。按照示例代码,您需要配置 SPI 连接,然后打开要连接到的设备,然后使用 library 方法读取和写入数据。

//SOURCE: https://raw.githubusercontent.com/milekium/spidev-lib/master/sample/spidev-testcpp.cc
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <spidev_lib++.h>spi_config_t spi_config;
uint8_t tx_buffer[32];
uint8_t rx_buffer[32];int  main( void)
{  SPI *mySPI = NULL;  spi_config.mode=0;spi_config.speed=1000000;spi_config.delay=0;spi_config.bits_per_word=8;  mySPI=new SPI("/dev/spidev1.0",&spi_config);  if (mySPI->begin()){memset(tx_buffer,0,32);memset(rx_buffer,0,32);sprintf((char*)tx_buffer,"hello world");printf("sending %s, to spidev2.0 in full duplex \n ",(char*)tx_buffer);mySPI->xfer(tx_buffer,strlen((char*)tx_buffer),rx_buffer,strlen((char*)tx_buffer));printf("rx_buffer=%s\n",(char *)rx_buffer);//mySPI->end();delete mySPI;}return 1;
} 

四、UART

        UART 连接可以与公共 C 库建立。按照本文中非常详细的说明,您将需要打开设备,然后使用 定义 TTY 设备的各种属性,然后写入串行端口并从串行端口读取。termios struct

// SOURCE: https://blog.mbedded.ninja/programming/operating-systems/linux/linux-serial-ports-using-c-cpp/
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <unistd.h>int main() {int serial_port = open("/dev/ttyUSB0", O_RDWR);  struct termios tty;  if(tcgetattr(serial_port, &tty) != 0) {printf("Error %i from tcgetattr: %s\n", errno, strerror(errno));return 1;}  tty.c_cflag &= ~PARENB;tty.c_cflag &= ~CSTOPB;tty.c_cflag &= ~CSIZE;tty.c_cflag |= CS8;tty.c_cflag &= ~CRTSCTS;tty.c_cflag |= CREAD | CLOCAL;  tty.c_lflag &= ~ICANON;tty.c_lflag &= ~ECHO;tty.c_lflag &= ~ECHOE;tty.c_lflag &= ~ECHONL;tty.c_lflag &= ~ISIG;tty.c_iflag &= ~(IXON | IXOFF | IXANY);tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL);  tty.c_oflag &= ~OPOST;tty.c_oflag &= ~ONLCR;  tty.c_cc[VTIME] = 10;tty.c_cc[VMIN] = 0;  cfsetispeed(&tty, B9600);cfsetospeed(&tty, B9600);  if (tcsetattr(serial_port, TCSANOW, &tty) != 0) {printf("Error %i from tcsetattr: %s\n", errno, strerror(errno));return 1;}  unsigned char msg[] = { 'H', 'e', 'l', 'l', 'o', '\r' };write(serial_port, "Hello, world!", sizeof(msg));  char read_buf [256];  memset(&read_buf, '\0', sizeof(read_buf);  int num_bytes = read(serial_port, &read_buf, sizeof(read_buf));  if (num_bytes < 0) {printf("Error reading: %s", strerror(errno));return 1;}  printf("Read %i bytes. Received message: %s", num_bytes, read_buf);  close(serial_port)return 0; 

五、通用 GPIO 访问

库libgpiod提供对任何运行Linux的设备的GPIO的通用访问。它检测可用的 GPIO,可以读取和写入数据,并等待触发事件。有了这个,您可以编写 ow 代码来将 UART 与任何连接的设备进行通信。

        要安装它,请运行以下命令:

apt-get install autoconf autoconf-archive libtool libkmod-dev pkg-config
git clone https://github.com/brgl/libgpiod.gitcd libgpiod
./autogen.sh --enable-tools=yes --prefix=/usr/local/bin
make
sudo make install 

        如果编译和安装成功,您将在子文件夹中找到可用于浏览 GPIO 的二进制文件。请参阅以下示例。./toolsgpiodetectgpioinfo

 ./tools/gpiodetect
gpiochip0 [pinctrl-bcm2711] (58 lines)
gpiochip1 [raspberrypi-exp-gpio] (8 lines)./tools/gpioinfo
gpiochip0 - 58 lines:line   0:     "ID_SDA"       unused   input  active-highline   1:     "ID_SCL"       unused   input  active-highline   2:       "SDA1"       unused   input  active-highline   3:       "SCL1"       unused   input  active-highline   4:  "GPIO_GCLK"       unused   input  active-highline   5:      "GPIO5"       unused   input  active-high
... 

        如果要使用该库,请阅读本文以获取详细说明。

六、结论

        为了在Raspberry Pi上使用I2C,SPI和UART,不仅可以使用Python,还可以使用C++库。具体来说,您需要通过 激活 I2C 和 SPI 函数,这会以地方式加载相应的内核模块。然后选择客户端库和其他必要的C++标头。使用库遵循相同的原则:确定连接的设备文件,配置连接对象,打开设备文件,然后读取/写入它。最后,方便的库libgpiod可以帮助您直接访问所有GPIO引脚,这对调试很有帮助。raspi-config

 

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

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

相关文章

智慧消防:如何基于视频与智能分析技术搭建可视化风险预警平台?

一、背景分析 消防安全是一个重要的话题&#xff0c;涉及到每个人的生活和安全。每年都会发生大量的火灾&#xff0c;给人们带来极大的危害&#xff0c;摧毁了大量的财产&#xff0c;甚至造成了可怕的人员伤亡。而消防安全监督管理部门人员有限&#xff0c;消防安全监管缺乏有…

Java读取外链图片忽略ssl验证转为base64

最近在对接外部接口时遇到返回的图片所在的服务器全都没有ssl证书&#xff0c;导致在前端直接用img标签展示时图片开裂。于是转为通过后端获取&#xff0c;绕过ssl验证之后转为base64返回。记录一下代码段。 package com.sy.ai.common.utils;import cn.hutool.core.codec.Base…

SVN - 记录一下无法提交代码 提示:被锁定(locked)

今天遇到一个问题&#xff0c;svn 在提交代码的时候出现了svn is already locked&#xff0c;导致代码无法提交&#xff08;commit&#xff09;和更新&#xff08;update&#xff09; 主要报错如下&#xff1a; 解决方法&#xff1a; 然后点击 Clean up 选中一下选项&#xff…

List、Numpy、Tensor操作基础

要想代码写的顺手&#xff0c; l i s t 、 n u m p y 、 t e n s o r 的操作一定要烂熟于心 要想代码写的顺手&#xff0c;list、numpy、tensor的操作一定要烂熟于心 要想代码写的顺手&#xff0c;list、numpy、tensor的操作一定要烂熟于心 一、list列表 1.1 list创建 list …

WPF实战学习笔记20-设置首页启动页

文章目录 设置首页启动页增加配置接口添加接口文件&#xff1a;实现接口 配置启动选项 设置首页启动页 增加配置接口 添加接口文件&#xff1a; Mytodo.Common/IConfigureInterface.cs using System; using System.Collections.Generic; using System.Linq; using System.T…

k8s 将pod节点上的文件拷贝到本地

要将 Kubernetes&#xff08;k8s&#xff09;中 Pod 节点上的文件拷贝到本地&#xff0c;可以通过使用 kubectl cp 命令来实现。kubectl cp 命令允许你在本地系统和 Pod 之间复制文件和目录。 下面是使用 kubectl cp 命令的语法&#xff1a; kubectl cp <namespace>/&l…

Linux centos7.x系统 下没有ens33 网卡的解决方案

一、背景 安装完windows11 Centos7.9 版本的双系统之后 , 启动Centos7.9时发现没有网卡信息 , 只有ifcfg-lo网卡的信息 , 这个时候就证明没有网卡信息&#xff0c;或者网卡驱动不匹配(我这里是没有网卡)&#xff0c;所以我们要重新安装 , 安装步骤如下 : 二、安装步骤 1.查…

Android各版本号发布日期及详细更新内容

版本号发布日期版本名称API Level更新内容Android 1.02008年9月23日初始版本初始版本&#xff0c;提供基本的手机功能和应用程序。Android 1.52009年4月30日Cupcake添加了文本输入方法&#xff08;包括虚拟键盘&#xff09;和语音搜索。 改进了网络和蓝牙功能。Android 1.62009…

PHP 药店管理系统mysql数据库web结构apache计算机软件工程网页wamp

一、源码特点 PHP 药品管理系统 是一套完善的web设计系统,系统采用smarty框架进行开发设计&#xff0c;对理解php编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 PHP 药店管理系统mysql数据库web结构apache计 下载地址…

开发一个简单的数据库路由进行分库分表

今天我们来看看一个简单的数据库路由组件要怎么开发出来&#xff0c;这篇文章分为几个步骤进行介绍&#xff0c;分别为&#xff1a; 什么是数据库路由 路由组件的作用为什么要自研组件需要用到什么技术 整体的业务流程主要代码 介绍 数据库路由的作用 使用数据库路由是在业…

超越想象的GPT医疗 20230723

7月份读完了这本书&#xff0c;趁着周末写下读书笔记吧 这本书 作者&#xff1a;【美】彼得.李 Peter Lee 【美】凯丽.戈德伯格CareyGoldberg 著 【美】伊萨克.科恩Isaac Kohane 芦义 译 在AI风起云涌时代&#xff0c;在这刚刚过去的新冠三年&#xff0c;“超越想象的GPT医…

产品解读|有了JMeter,为什么还需要MeterSphere?

提起JMeter&#xff0c;相信大部分的测试人员应该都很熟悉。JMeter因其小巧轻量、开源&#xff0c;加上支持多种协议的接口和性能测试&#xff0c;在测试领域拥有广泛的用户群体。一方面&#xff0c;测试人员会将其安装在个人的PC上&#xff0c;用以满足日常测试工作的需要&…

【SpringCloud Alibaba】(一)微服务介绍

此专栏内容皆来自于【冰河】的《SpringCloud Alibaba 实战》文档。 1. 专栏介绍 我们先来看看《SpringCloud Alibaba实战》专栏的整体结构吧&#xff0c;先上图 从上图&#xff0c;大家可以看到&#xff0c;专栏从整体上分为十个大的篇章&#xff0c;分别为 专栏设计、微服务…

Android源码中添加自己的Product

这里假设我们的公司名叫果冻&#xff08;Jelly&#xff09;&#xff0c;我们准备开发一款对标苹果 14 的手机&#xff0c;取名叫 大米14&#xff08;Rice14&#xff09;。 接下来我们在源码中添加我们自己的产品&#xff08;Product&#xff09; 在 device 目录下添加如下的目…

Mybatis基于注解与XML开发

文章目录 1 关于SpringBoot2 关于MyBatis2.1 MyBatis概述2.2 MyBatis核心思想2.3 MyBatis使用流程3 MyBatis配置SQL方式3.1 基于注解方式3.1.1 说明3.1.2 使用流程3.1.3 常用注解 3.2 基于XML方式3.2.1 相比注解优势3.2.2 使用流程3.2.3 常用标签 1 关于SpringBoot SpringBoot…

Java中List与数组之间的相互转换

一、List列表与对象数组 List列表中存储对象&#xff0c;如List<Integer>、List<String>、List<Person>&#xff0c;对象数组中同样存储相应的对象&#xff0c;如Integer[]、String[]、Person[]&#xff0c;对象数组与对象List的转换可通过如下方式实现&…

【Git】

学习来自于&#xff1a; 女朋友乱用Git&#xff0c;差点把我代码删了。。。 一些常用的Git 知识点整理 关于Git这一篇就够了 Git基本命令大全 30分钟精通Git&#xff0c;学不会来找我 Git 版本管理 | 莫烦PYTHON Git 代码版本管理教程 文章目录 【前言】集中式与分布式的…

Jmeter配置起来太繁琐?试试RunnerGo

在用jmeter做性能测试时想看完整一点的测试报告&#xff0c;想配置阶梯模式来压测&#xff0c;想配置不同的接口并发这些都需要安装插件并且影响机器性能&#xff0c;想做自动化测试还得放到jenkins&#xff0c;这些配置起来太繁琐。今天给大家推荐一款测试平台RunnerGo&#x…

听力词汇笔记(6级)

2022年9月六级 1.personality traits:人格特征 2.all of this notwithstanding:尽管如此 3.come under&#xff1a;受到 4.scrutiny&#xff1a;关注 5.highly responsive to:对....高度敏感 6.preteen year:青春期前 7.susceptible to:受....影响 8.take sharp preced…

网络安全 Day21-数据库知识

数据库知识 1. 什么是数据库2. 为什么需要数据库&#xff08;分类不清晰&#xff09;3. 数据库的种类3.1 关系型数据库3.2 NOSQL 数据库3.3 new sql &#xff08;国产数据库&#xff09;分布式数据库3.4 云数据库 4. mysql 关系型数据库5. 安装mariadb6. 为mariadb设置密码7. M…