1. I2C介绍
IIC又简写成I2C,是一种串行通信总线,使用多主从架构。
最初设计目的为了让主板、嵌入式系统或手机用来连接低速周边设备。多用于小数据量的场合,有传输距离短,任意时刻只能有一个主机等特性。
在Linux嵌入式应用开发的情景下,完全可以不必理会IIC协议的详细规定。只需要按照驱动层提供给我们的操作IIC外设的操作接口函数就可以像操作linux中其他普通设备文件那样轻松的操作IIC外设了。
1.1 开发板上I2C资源介绍
EASY EAI Orin-Nano开发板预留引出了2路IIC资源,以供用户自定义调用,它们分别是IIC2和IIC8。确切的分部位置,如下图所示:

1.2 硬件接线示意图

本示例采用ADS1115电压检测模块进行辅助演示。此模块功能是把检测到的电压(模拟信号)转化为数字信号存入寄存器中,然后以IIC的通信方式对外提供电压信息的提取。
ADS1115模块与EASY EAI Orin-Nano的接线原理图如下所示:

2. 快速上手
2.1 例程源码下载
到【百度网盘】上下载相关的单例程序:
链接:https://pan.baidu.com/s/1RXHMGpmGSEfFy0rb1VkXSg?pwd=1234
提取码: 1234
比如在windows环境中,就把单例程序下载到:此电脑D:BaiduNetdisk (无规定,用户可自主选择),如下图所示。

然后把例程【复制粘贴】到nfs挂载目录中。(不清楚目录如何构建的,可以参考《入门指南/开发环境准备/nfs服务搭建与挂载》)

2.2 例程编译&运行
通过adb shell进入开发板环境(不清楚如何通过adb进行调试,可以参考《入门指南/开发板调试方式介绍/adb调试》),执行下方命令定位到demo目录,并且执行编译操作。
cd /home/orin-nano/Desktop/nfs/08_IIC/ ./build.sh

编译成功后,会生成一个test-ads1115的可执行程序在Release目录中。
执行下方命令则可运行测试demo,如下所示。
sudo ./Release/test-ads1115
执行效果如下所示,利用探测分别触碰3V3,1V8,GND三个端子,则可在终端测出对应的电压值。

3. C语言使用案例
ADS1115的C语言使用案例,代码地址为08_IIC/test-ads1115/main.c,供用户编码参考。以下代码展示了对ADS1115操作流程:
int32_t ads1115_config_register(uint32_t fd, uint8_t configH, uint8_t configL)
{
uint8_t reg_data[3] = {ADS1015_REG_POINTER_CONFIG, configH, configL};
return iic_write(fd, ADS1115_ADDRESS, reg_data, sizeof(reg_data));
}
int16_t ads1115_read_data(uint32_t fd)
{
bool ret = false;
/*读取数据*/
uint8_t tx_data[1] = {ADS1015_REG_POINTER_CONVERT};
if(iic_write(fd, ADS1115_ADDRESS, tx_data, sizeof(tx_data)) < sizeof(tx_data)){
printf("iic write faild !n");
return -1;
}
uint8_t rx_data[3]={0};
if(iic_read(fd, ADS1115_ADDRESS, rx_data, 2) < 0){
printf("iic read faild !n");
return -1;
}
int16_t data = rx_data[0]*256+rx_data[1];
return data;
}
double ads1115_get_voltage_val(uint32_t fd, uint8_t configH, uint8_t configL)
{
/*配置寄存器*/
if(ads1115_config_register(fd, configH, configL) < 0){
printf("ads1115 config register faildn");
return 0.0;
}
usleep(100 * 1000);
int16_t ad_val = ads1115_read_data(fd);
if((0x7FFF == ad_val)|(0X8000 == ad_val)) {//是否超量程了
ad_val = 0;
printf("ads1115 over PGArn");
}
double val = 0.0;
switch((0x0E&configH) >>1)//量程对应的分辨率
{
case(0x00):
val = (double)ad_val*187.5/1000000.0; break;
case(0x01):
val = (double)ad_val*125/1000000.0; break;
case(0x02):
val = (double)ad_val*62.5/1000000.0; break;
case(0x03):
val = (double)ad_val*31.25/1000000.0; break;
case(0x04):
val = (double)ad_val*15.625/1000000.0; break;
case(0x05):
val = (double)ad_val*7.8125/1000000.0; break;
default:
val = 0.0; break;
}
return val;
}
int main(int argc, char const *argv[])
{
bool ret = false;
double val;
int fd = iic_init("/dev/i2c-2");
if(fd < 0){
printf("iic init faild n");
return -1;
}
if(0 != iic_set_addr_len(fd, 7)){
return -1;
}
if(0 != iic_set_addr(fd, ADS1115_ADDRESS)){
return -1;
}
while (1) {
val = ads1115_get_voltage_val(fd, CONFIG_REG_H, CONFIG_REG_L);
printf("val: %f Vrn",val);
sleep(2);
}
iic_release(fd);
return 0;
}
其中iic_init(),iic_set_addr_len(),iic_set_addr(),iic_read(),iic_write(),iic_release()是对系统调用的易用化封装。具体实现于08_IIC/commonApi/iic.c
除了需要有对IIC硬件资源进行操作的接口以外,要需要清楚IIC总线上的IIC从机设备的寄存器操作方法。如ADS1115电压检测芯片,与其寄存器相关的操作定义均在08_IIC/test-ads1115/ads1115.h中实现。
审核编辑 黄宇
-
I2C
+关注
关注
28文章
1547浏览量
130482 -
开发板
+关注
关注
25文章
6122浏览量
113310 -
rk3576
+关注
关注
1文章
228浏览量
1370
发布评论请先 登录
基于RK3576开发板的MIPI-DSI使用

基于RK3576开发板的I2C使用说明
评论