ROS i2c 通信(c++版本)
WiringPi是一个用C语言编写的树莓派(RaspberryPi)软件包,可用于树莓派GPIO引脚控制、串口通信、SPI通信及I2C通信等功能,非常适合熟悉C/C++的人员在树莓派上进行软件开发。WiringPi的作者是Gordon Henderson,其官方网址为http://wiringpi.com。WiringPi遵循GNU GPLv3公约,任何人都可以免费使用该软件包。
1、WiringPi的安装与更新
WiringPi预装(Pre-installed)在标准的树莓派操作系统Raspbin中。可以使用下面的命令进行安装:
sudo apt-get install wiringpi
如果需要更新WiringPi,可以使用系统更新命令:
sudo apt-get update
sudo apt-get upgrade
WiringPi安装完成后,可以使用下面的命令测试是否安装成功:
sudo gpio -v
如果系统中安装了WiringPi,该命令可以显示出其版本号、作者及当前树莓派的一些信息;如下图所示:
2、WiringPi的引脚定义
WiringPi对树莓派物理引脚进行了封装,定义了一套自己的引脚编号。
如果要查看当前树莓派的引脚编号,可以使用如下命令:
sudo gpio readall
下面这张图是gpio readall读出的树莓派3B的引脚定义:
树莓派的物理引脚、BCM引脚和WiringPi引脚是三种不同的定义,下面这张图看起来更清晰美观一些:
3、WiringPi的库函数
WiringPi提供了很多函数用于各种功能,包括如下库:
- WiringPi配置函数(WiringPi Setup functions);
- WiringPi核心函数(WiringPi Core functions);
- 树莓派专用函数(Raspberry Pi Specific functions);
- 时间函数(Time functions);
- 程序优先级/中断/线程函数(Process priority/interrupts/thread functions);
- 串口通信库函数(Serial Library functions);
- SPI通信库函数(SPI Library functions);
- I2C通信库函数(IC2 Library functions);
- 移位库函数(Shift Library functions);
- 软件PWM库函数(Software PWM Library functions);
- 软件方波/音频库函数(Software Tone Library functions);
4、 代码编写
树莓派端
#include "stdio.h"
#include "wiringPi.h"
#include "wiringPiI2C.h"
#include "pthread.h"
#include "unistd.h"void *pthread_fun(void *arg)
{int fd = *((int*)arg); int Tx_buf = 12;while(1){wiringPiI2CWrite(fd, Tx_buf);sleep(1);}return NULL;
}int main(int argc, char *argv[])
{int fd, err;int Rx_buf;pthread_t tid;//对wiringPi初始化if(wiringPiSetup() != 0){printf("wiringPi error!\n");return -1;}//指定i2c从机设备,并初始化i2cfd = wiringPiI2CSetup(0x28);if(fd < 0){printf("wiringPiI2CSetup error!\n");return fd;}err = pthread_create(&tid, NULL, pthread_fun, &fd);if(err != 0){printf("create pthread error\n"); return -2;}while(1){Rx_buf = 0;//读取数据Rx_buf = wiringPiI2CRead(fd);//判断是否读取成功if(Rx_buf != 0)printf("Temperature is %d ℃\n", Rx_buf);sleep(1);}return 0;
}
STM32F103硬件i2c代码
/*********************************************************************************************************
* 包含头文件
*********************************************************************************************************/
#include "iic.h"/*********************************************************************************************************
* 宏定义
*********************************************************************************************************//*********************************************************************************************************
* 内部变量
*********************************************************************************************************/
u8 IIC1_Rx_Buff = 0;
u8 IIC1_Tx_Buff = 67;//#define SIZE2 sizeof(IIC1_Tx_Buff)
uint32_t state;
/*********************************************************************************************************
* 内部函数声明
*********************************************************************************************************//*********************************************************************************************************
* 内部函数实现
*********************************************************************************************************/
/*********************************************************************************************************
* 函数名称:
* 函数功能:
* 输入参数:
* 输出参数:
* 返 回 值:
* 创建日期:
* 注 意:
*********************************************************************************************************/ /*********************************************************************************************************
* API函数实现
*********************************************************************************************************/
/*********************************************************************************************************
* 函数名称: InitI2C1
* 函数功能: 初始化I2C1
* 输入参数: void
* 输出参数: void
* 返 回 值: void
* 创建日期: 2019年4月21日
* 注 意: PB6:SCL; PB7:SDA
*********************************************************************************************************/
void InitI2C1(void)
{GPIO_InitTypeDef GPIO_InitStruct;I2C_InitTypeDef I2C_InitStruct;NVIC_InitTypeDef NVIC_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);//GPIO配置GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD; //设置为复用开漏输出,实现iic的线与逻辑GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStruct);//I2C1配置I2C_InitStruct.I2C_Ack = I2C_Ack_Enable; //使能ackI2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; //7位设备地址I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;//占空比为1/2 I2C_InitStruct.I2C_ClockSpeed = 100000; //时钟频率为100kI2C_InitStruct.I2C_Mode = I2C_Mode_I2C;I2C_InitStruct.I2C_OwnAddress1 = 0x50; //设置硬件从机地址I2C_Init(I2C1, &I2C_InitStruct);//NVIC配置NVIC_InitStruct.NVIC_IRQChannel = I2C1_EV_IRQn; //事件中断NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;NVIC_Init(&NVIC_InitStruct);NVIC_InitStruct.NVIC_IRQChannel = I2C1_ER_IRQn; //错误中断NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;NVIC_Init(&NVIC_InitStruct);I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_ERR | I2C_IT_BUF, ENABLE);I2C_Cmd(I2C1, ENABLE);
}/*********************************************************************************************************
* 函数名称: I2C1_EV_IRQHandler
* 函数功能: I2C1事件中断服务函数
* 输入参数: void
* 输出参数: void
* 返 回 值: void
* 创建日期: 2019年4月21日
* 注 意:
*********************************************************************************************************/
void I2C1_EV_IRQHandler(void)
{ //static u8 s_iRdata;//static u8 s_iTdata;state = I2C_GetLastEvent(I2C1);switch(state){ //EV1(receive)(从机匹配地址成功)case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED: I2C_ReadRegister(I2C1, I2C_Register_SR1); //读取SR1I2C_ReadRegister(I2C1, I2C_Register_SR2); //读取SR2后,硬件自动将SR1->ADDR清零//s_iRdata = 0;break;//EV2(Byte received)case I2C_EVENT_SLAVE_BYTE_RECEIVED:IIC1_Rx_Buff = I2C_ReceiveData(I2C1);//读取DR寄存器硬件将自动将SR1->RxNE清零//IIC1_Rx_Buff[s_iRdata] = I2C_ReceiveData(I2C1);//读取DR寄存器硬件将自动将SR1->RxNE清零//s_iRdata++;break;//EV4(stop) case I2C_EVENT_SLAVE_STOP_DETECTED:I2C_ReadRegister(I2C1, I2C_Register_SR1); //读取SR1I2C1->CR1 |= 0x0001; //写CR1->PE为1,启动I2C1break;//EV1(transmitter)case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:I2C_ReadRegister(I2C1, I2C_Register_SR1); //读取SR1I2C_ReadRegister(I2C1, I2C_Register_SR2); //读取SR2后,硬件自动将SR1->ADDR清零//s_iTdata = 0; break;//EV3、EV3-1(Byte transmit)case I2C_EVENT_SLAVE_BYTE_TRANSMITTING:case I2C_EVENT_SLAVE_BYTE_TRANSMITTED://I2C_SendData(I2C1, IIC1_Tx_Buff[s_iTdata++]); //写I2C->DR后硬件将自动清除TxE位I2C_SendData(I2C1, IIC1_Tx_Buff); //写I2C->DR后硬件将自动清除TxE位break;//EV3-2 case I2C_EVENT_SLAVE_ACK_FAILURE:I2C1->SR1 &= 0xFBFF; //写SR1->AF = 0以清除AF位break;default:break;}
}/*********************************************************************************************************
* 函数名称: I2C1_ER_IRQHandler
* 函数功能: I2C1错误中断服务函数
* 输入参数: void
* 输出参数: void
* 返 回 值: void
* 创建日期: 2019年4月21日
* 注 意:
*********************************************************************************************************/
void I2C1_ER_IRQHandler(void)
{ if(I2C_GetITStatus(I2C1, I2C_IT_SMBALERT)){I2C_ClearITPendingBit(I2C1, I2C_IT_SMBALERT);}else if(I2C_GetITStatus(I2C1, I2C_IT_TIMEOUT)) {I2C_ClearITPendingBit(I2C1, I2C_IT_TIMEOUT);}else if(I2C_GetITStatus(I2C1, I2C_IT_PECERR)) {I2C_ClearITPendingBit(I2C1, I2C_IT_PECERR);}else if(I2C_GetITStatus(I2C1, I2C_IT_OVR)) {I2C_ClearITPendingBit(I2C1, I2C_IT_OVR);}else if(I2C_GetITStatus(I2C1, I2C_IT_AF)) {I2C_ClearITPendingBit(I2C1, I2C_IT_AF);}else if(I2C_GetITStatus(I2C1, I2C_IT_ARLO)) {I2C_ClearITPendingBit(I2C1, I2C_IT_ARLO);}else if(I2C_GetITStatus(I2C1, I2C_IT_BERR)) {I2C_ClearITPendingBit(I2C1, I2C_IT_BERR);}I2C1->CR1 |= 0x0001; //启动I2C1I2C1->SR1 = 0;I2C1->SR2 = 0;
}
编译
gcc i2c_wiringPi.c -o i2c_wiringPi -lpthread -lwiringPi
./i2c_wiringPi
Tip: 此外在检索中已经有大神封装好了这部分的工作,各位也可以直接调用。
ROS i2c 通信(c++版本)相关推荐
- ROS——不同版本间ROS进行通信
在相同版本间的ROS进行通信不在赘述了,修改/etc/hosts文件即可. 最近项目遇到在Ubuntu16.04 与Ubuntu18.04两个系统间进行ROS通信,ROS版本分别为Kinetic和Me ...
- 【ROS话题通信】发布者和订阅者
前言 本文记录ROS话题通信的学习过程,便于后续复习.首先明确,ROS中的话题通信,在ROS通信中非常重要,实现了分布式发布接收消息,也是实现了不同编程语言间的解耦,下面记录下自己学习过程中的相关代码 ...
- 【ROS入门-4】嘴对嘴讲解ROS的核心概念——ROS话题通信机制
文章目录 前言 ROS系列文章 ROS的通信机制 话题(topic) 发布者 订阅者 消息(Message) 用C++来写话题通信的代码 发布者 订阅者 使用rqt_graph 源码附录 引用说明 参 ...
- TI - MCU - MSP430使用指南14 - I2C通信(eUSCI)
说到MSP430 MCU的I2C资源,那么首先就得先看一下USCI. 如果你了解过多款MSP430 MCU你会发现,内部资源里有USCI和eUSCI,那么他们什么意思呢? USCI (Universa ...
- linux stm32 主从,STM32F407和STM32F051主从I2C通信方法
STM32F407和STM32F051主从I2C通信方法 作者:华清远见讲师 M4作为主机: int main(void) { HAL_Init(); SystemClock_Config(); MX ...
- ROS服务通信机制原理及示例代码
ROS服务通信:节点间直接通信并获得应答.服务需要用户自己开发,可在功能包下创建srv文件夹并编写源代码,服务类型是功能包名称和.srv文件名称的组合,比如python中引入srv类型为,from g ...
- AT24C0X I2C通信原理
/*********************************************************************** AT24C0X I2C通信原理* 说明:* 之前接触A ...
- 快速对比UART、SPI、I2C通信的区别与应用
参考:带你快速对比SPI.UART.I2C通信的区别与应用! 作者:一口Linux 网址:https://mp.weixin.qq.com/s/4_RSM2jk2W6nTboO1W8HCw 电子设备之 ...
- i2c通信的详细讲解_【博文连载】SCCB(I2C)初始化时序介绍
在正式开始OV7725视频采集实现之前,Bingo不得不先讲解一下OV7725的寄存器配置接口.OV7725上电会默认输出YUV422格式的视频流,但我们希望传感器能够按照我们预期的模式工作,我们需要 ...
最新文章
- ios navigation的返回按钮长按_Android Jetpack架构组件 — Navigation入坑详解 [转]
- 浅入深出Vue:文章编辑
- Java计算器接口策略_Java 基础 接口 ——运算
- golang 标准库间依赖的可视化展示
- log4j2 logger_简单一致的Log4j2 Logger命名
- codeforces 264 B. Good Sequences(dp+数学的一点思想)
- HDU2191——悼念512汶川大地震遇难同胞——珍惜现在,感恩生活
- Python Tricks(十三)—— 欧几里得算法
- 关于attachEvent与addEventListener事件绑定兼容问题
- 抖音api开放平台对接_抖音视频API解析接口
- 平面设计中有趣的词云图如何设计
- c语言快速学习,怎么才能正确快速的学习c语言
- 少男杀手dodolook签约酷6网原创红人阵营
- 宋江是怎么当上老大的
- 利用非约束性委派+Spooler打印机服务 制作黄金票据攻击域控
- uni-app 异形轮播
- 如何进入docker系统
- ElasticSearch入门教程(1)
- Android okhttp3设置代理(http/https)
- 解决把一篇word文档复制到另一篇word文档时, 更改标题格式