Jetson 使用IIC接口读取TFmini-plus等传感器数据

4 篇文章 0 订阅
2 篇文章 0 订阅

Jetson 使用IIC接口读取TFmini-plus等传感器数据

最近使用Jetson nx/nano的IIC接口来读取单点激光雷达TFmini-plus的数据,将开发过程记录如下。
首先需要了解IIC通信协议的基本原理,可参考我之前所写的博客:
https://blog.csdn.net/w1050321758/article/details/108956570?spm=1001.2014.3001.5501

我们将Jetson nano定为主机,TFmini-plus定为从机。根据IIC协议,我们需要知道从机地址以及从机的通信协议。
这里我们直接参考北醒光子TFmini-plus的说明书,可以看见其通信协议的格式。要想从从机读数据,我们需要发送5A 05 00 01 60这样的连续几个16进制数据来引起从机的反馈。
在这里插入图片描述
从机返回数据后,我们需要按照下面的协议来解析从机发送过来的数据:

在这里插入图片描述
另外,需要知道从机的IIC地址,如下图可见从机的默认地址为0x10。
在这里插入图片描述
最后我们还可以从产品说明书了解到它的数据时序,(其实这部分东西从机不给也可以,这是标准的IIC协议的通信时序)。

在这里插入图片描述
我们可以观察到,主机要想和TFmini-plus从机间进行通信,需要按照以下方式发送数据:
(1)首先发送起始位。如果我们使用标准Linux自带的IIC函数,那么起始位一般不需要我们自己发送,在调用函数的时候,系统会自动把起始位加上。
(2)从机地址+读写位。从机地址一般为7位,再加1位的“读”或者“写”形成8位,即IIC的一个数据帧,一并通过IIC发送给所有从机,从机接收到和自己地址相同的数据帧后,便会和主机建立连接,进行通信。读为1,写为0。所以这一个字节可以表示成:从机地址<<1|0(写,0加不加都可以);或者:从机地址<<1|1(读)。
(3)从机应答位。确认通信正常的位,该位由从机发出,我们调用系统函数的话一般不需要管。
(4)通过上面三步,主机便和从机建立了IIC通信渠道。此时主机一个字节一个字节往从机发送消息就可以了。为了实现有意义的通信,这里发送的字节需要参考上面从机的通信协议来发。

最后,如何使用Jetson来实现IIC通信呢,首先我们需要知道Jetson的IIC接口,下图可以看见Jetson nano一共2个IIC外部接口,BOARD 3号和5号以及BOARD 27号和28号,选一个接口把自己的从设备接上去就可以了。
在这里插入图片描述
其次,我们需要知道Jetson nx调用IIC的函数接口。
Jetson nano内部安装的是Linux系统,Linux系统内部提供了IIC相关的函数。

#include "/usr/include/linux/i2c.h" 
#include <linux/i2c-dev.h>

那如何用这些函数呢,其实Linux可以通过操作文件的方式来操作IIC设备,因为Linux系统内,一切皆文件。只需要将普通文件通过ioctl函数声明为IIC设备即可,然后按照操作文件的方式来对IIC设备进行读写。
具体的代码如下,参考我上面的讲解,应该可以看懂了,如果不懂的话可以去翻看一下上面的讲解或者补一下IIC通信协议和Linux系统编程相关的知识,然后你一定会恍然大悟:

#include <stdio.h> 
#include <stdint.h> 
#include <fcntl.h> 
#include <unistd.h>
#include <sys/ioctl.h> 
#include "/usr/include/linux/i2c.h" 
#include <linux/i2c-dev.h>
#define LIDAR_SENSOR 0x10     
 
 
int writeReg(int pt, unsigned char add){   
        unsigned char w_buff[5]; 
        //地址+写位,写位为0,所以只需要地址左移1位即可
        w_buff[0] = add<<1; 
        //从机的读取协议
        w_buff[1] = 0x5a;
        w_buff[2] = 0x05;
        w_buff[3] = 0x00;
        w_buff[4] = 0x01;
        w_buff[5] = 0x60;
        //文件写操作
        if (write(pt, w_buff, 6) != 6){ 
                perror("Failed write to device"); 
                return 1; 
        } 
        return 0; 
} 
 
int readReg(int pt, unsigned char s_add, char buf[], int size){ 
        char writeBuff[1];
        //读,从机地址+读位
		writeBuff[0]= (s_add<<1)|1; 
		//先把读的命令发给从机
        if(write(pt, writeBuff, 1)!=1) { 
                perror("Failed to reset the read address\n"); 
                return 1; 
        } 
        //然后利用文件读操作,把读到的数据全部放到buf数组里面
        if(read(pt, buf, size)!=size){ 
                perror("Failed to read in the buffer\n"); 
                return 1; 
        } 
        return 0; 
}
 
float distance=0;
 
int main(){ 
        int file; 
        //打开文件
        if((file=open("/dev/i2c-1", O_RDWR)) < 0) {    
                perror("failed to open the bus\n");  
                return 1; 
        } 
        //声明为IIC设备文件
        if(ioctl(file, I2C_SLAVE, LIDAR_SENSOR) < 0) {    
                perror("Failed to connect to the sensor\n"); 
                return 1; 
        }
        //存储接收到的数据
        char distance_buff[9]={0};    
		while(1)
		{
			//先写,引起从机的反馈
        	if(writeReg(file, LIDAR_SENSOR)==1){ 
            	    return 1; 
        	} 
        	//再读取从机反馈
        	if(readReg(file, LIDAR_SENSOR, distance_buff,9)==1){ 
            	    return 1; 
        	} 
        	//从从机反馈的数据里面根据从机的协议提取我们想要的东西
			distance=short(distance_buff[2]|(distance_buff[3]<<8))*0.01;
			printf("distance: %.2f\n",distance);
		} 
		close(file);
	return 0;
}
  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值