目录
树莓派使能I2C
sudo raspi-config 进行配置树莓派,启动I2C完成使能
sudo reboot 重启树莓派,使其完成配置
lsmod | grep i2c命令可以查看当前系统支持的i2c协议模块
(lsmod(list modules)命令用于显示已载入系统的模块)
i2c-tools命令
sudo apt install i2c-tools 这个工具在i2c硬件设备识别和故障诊断中很重要,一共只有四条命令。
①i2c设备查询
如果总线上挂载I2C从设备,可以使用i2cdetect -y 1显示总线上的所有设备
如图,通过该条命令可以查看i2c从设备的地址,此处挂载的设备是sht20,其从机地址是0x40
说明:-y是一个可选参数,表示是否有与用户进行交互的过程,如果写入该参数,则没有交互过程
1 则是代表i2c总线编号
②扫描寄存器的内容
通过i2cdump命令可以导出i2c设备中多有寄存器的内容
如: i2cdump -y 1 0x40
说明:-y代表取消用户交互过程,直接执行指令
1 代表i2c总线编号
0x40 代表i2c从机设备的地址,这里指的是sht20
③寄存器内容写入
要向特定的寄存器中写入内容使用i2cset命令
如:i2cset -y 1 0x40 0x00 0x13
说明:-y代表取消用户交互过程,直接执行指令
1 代表i2c总线编号
0x40 代表i2c从机设备的地址,这里指的是sht20
0x00 代表寄存器的地址
0x13 代表需要写入的内容
④读取寄存器内容
如:i2cget -y 1 0x40 0x00
说明:-y代表取消用户交互过程,直接执行指令
1 代表i2c总线编号
0x40 代表i2c从机设备的地址,这里指的是sht20
0x00 代表寄存器的地址
C程序获取SHT20温湿度
#include <string.h>
#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <linux/i2c.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/stat.h>
#define DEV_FILE "/dev/i2c-1"
#define SHT2X_ADDR 0x40
#define SHT2X_SOFTRESET 0xFE
#define SHT2X_MEAS_TEMPER 0xF3
#define SHT2X_MEAS_HUMIDITY 0xF5
void msleep(unsigned int time);
int sht2x_init(void);
int sht2x_softreset(int fd);
int sht2x_send_cmd_wr(int fd, char *which);
int sht2x_get_temper_rh(int fd, float *temper, float *rh);
int main(int argc, char **argv)
{
int fd = -1;
int ret = -1;
float temper;
float rh; //humidity
fd = sht2x_init();
if( fd < 0 )
{
printf("sht2x_init failure.\n");
return -1;
}
ret = sht2x_softreset(fd);
if( ret < 0 )
{
printf("sht2x_softreset failure.\n");
return -2;
}
ret = sht2x_get_temper_rh(fd, &temper, &rh);
if( ret < 0 )
{
printf("sht2x_get_temper_rh failure.\n");
return -3;
}
printf("Temperature = %fC Relative humidity = %f%\n", temper, rh);
close(fd);
return 0;
}
void msleep(unsigned int time)
{
struct timespec sleeper, temp;
sleeper.tv_sec = (time_t)(time/1000);
sleeper.tv_nsec = (long)(time%1000)*1000000;
nanosleep(&sleeper, &temp);
return ;
}
int sht2x_init(void)
{
int fd = -1;
fd = open(DEV_FILE, O_RDWR);
if( fd < 0 )
{
printf("i2c device open failure: %s\n", strerror(errno));
return -1;
}
ioctl(fd, I2C_TENBIT, 0);
ioctl(fd, I2C_SLAVE, SHT2X_ADDR);
return fd;
}
int sht2x_softreset(int fd)
{
int ret = -1;
uint8_t buf[2] = {0};
if( fd < 0 )
{
printf("input the invalid argument.\n");
return -1;
}
buf[0] = SHT2X_SOFTRESET;
ret = write(fd, buf, 1);
if( ret < 0 )
{
printf("write softrest cmd to sht2x failure.\n");
return -2;
}
msleep(50);
return 0;
}
int sht2x_send_cmd_wr(int fd, char *which)
{
int ret = -1;
uint8_t buf[2] = {0};
if( fd < 0 )
{
printf("input the invalid argument.\n");
return -1;
}
if( strcmp(which, "temper") == 0 )
{
buf[0] = SHT2X_MEAS_TEMPER;
ret = write(fd, buf, 1);
if( ret < 0 )
{
printf("write temper cmd to sht2x failure.\n");
return -2;
}
msleep(85); //datasheet typ=66, max=85
}
else if( strcmp(which, "rh") == 0 )
{
buf[0] = SHT2X_MEAS_HUMIDITY;
ret = write(fd, buf, 1);
if( ret < 0 )
{
printf("write humidity cmd to sht2x failure.\n");
return -3;
}
msleep(29); //datasheet typ=22, max=29
}
return 0;
}
int sht2x_get_temper_rh(int fd, float *temper, float *rh)
{
uint8_t buf[4] = {0};
int ret = -1;
if( fd<0 || !temper || !rh )
{
printf("input the invalid arguments.\n");
return -1;
}
ret = sht2x_send_cmd_wr(fd, "temper");
if( ret < 0 )
{
printf("sht2x_send_cmd_wr temper failure.\n");
return -2;
}
else
{
ret = read(fd, buf, 3);
if( ret < 0 )
{
printf("get the temper failure.\n");
return -3;
}
*temper = 175.72 * (((((int) buf[0]) << 8) + buf[1]) / 65536.0) - 46.85;
}
ret = sht2x_send_cmd_wr(fd, "rh");
if( ret < 0 )
{
printf("sht2x_send_cmd_wr rh failure.\n");
return -2;
}
else
{
read(fd, buf, 3);
if( ret < 0 )
{
printf("get the temper failure.\n");
return -3;
}
*rh = 125 * (((((int) buf[0]) << 8) + buf[1]) / 65536.0) - 6;
}
return 0;
}