六、树莓派+MAX30102血氧模块(WiringPi I2C试验)
wiringPi I2C库相关
1、wiringPi包含了一个I2C库,能让您能够轻松的使用树莓派上I2C接口,在使用I2C接口之前,您可能需要使用gpio命令来加载I2C驱动到内核中:
gpio load i2c
注:在实际的使用中先使用 sudo raspi-config 对树莓派I2C接口进行开启


但是在这之后无论怎么使用 gpio load i2c 指令,一直提示如下报错内容
gpio: Unable to load/unload modules as this Pi has the device tree enabled. You need to run the raspi-config program (as root) and select the modules (SPI or I2C) that you wish to load/unload there and reboot.
在网络上查询了老半天也不知道这个问题应该怎么解决,在链接:https://forums.raspberrypi.com/viewtopic.php?t=136867 中得知,使用 raspi-config 打开I2C后,以上报错可以忽略,不影响I2C使用。
2、如果你需要的波特率不是1000Kbps,那么您可以使用如下命令设置波特率为1000Kbps:
gpio load i2c 1000
3、使用I2C库,需要包含wiringPiI2C.h文件,并且在编译时,同样需要使用 -lwiringPi来连接到wiringPi库
4、您仍可以使用标准的系统命令来检测I2C设备,如i2cdetect命令,需要注意的是在V1版本的树莓派上是 0 ,V2版本上是 1,如下:
i2cdetect -y 0 #Rev 1 i2cdetect -y 1 #Rev 1
当然你也可以使用gpio指令来调用 i2cdetect 命令,从而检测I2C设备,如下:
gpio i2cdetect
5、I2C库函数接口如下:
| 函数接口 | 函数原型 | 参数说明 | 功能说明 |
|
wiringPiI2CSetup |
int wiringPiI2CSetup(int devId) |
返回值:标准的Linux句柄,也就是下面各接口中的 fd,如有错误则返回 -1 devId: 设备ID号(即为通过i2cdetect指令扫描出的设备ID) |
该函数使用指定的设备标号来初始化I2C系统 |
| wiringPiI2CRead | int wiringPiI2CRead(int fd) |
返回值:接收到的数据 fd:wiringPiI2CSetup的返回值 |
简单的设备读操作,一些设备可以直接读取,而不需要发送任何寄存器地址 |
| wiringPiI2CWrite | int wiringPiI2CWrite(int fd, int data) |
返回值:写入状态 fd:wiringPiI2CSetup的返回值 data:待写入数据 |
简单的设备写操作,一些设备可以接收数据,而不需要发送任何寄存器地址 |
| wiringPiI2CWriteReg8 | int wiringPiI2CWriteReg8(int fd, int reg ,int data) |
返回值:写入状态 fd:wiringPiI2CSetup的返回值 reg:寄存器地址 data:待写入数据 |
使用该函数,可以写一个8位的数值到指定寄存器 |
| wiringPiI2CWriteReg16 | int wiringPiI2CWriteReg16(int fd, int reg ,int data) |
返回值:写入状态 fd:wiringPiI2CSetup的返回值 reg:寄存器地址 data:待写入数据 |
使用该函数,可以写一个16位的数值到指定寄存器 |
| wiringPiI2CReadReg8 | int wiringPiI2CReadReg8(int fd, int reg ) |
返回值:读取到的数据 fd:wiringPiI2CSetup的返回值 reg:寄存器地址 |
使用该函数,可以从指定寄存器中读一个8位的数值 |
| wiringPiI2CReadReg16 | int wiringPiI2CReadReg16(int fd, int reg ) |
返回值:读取到的数据 fd:wiringPiI2CSetup的返回值 reg:寄存器地址 |
使用该函数可以从指定寄存器中读一个16位的数值 |
代码实现对血氧检测原始数据读取:
#include <stdio.h>
#include <wiringPi.h>
#include <wiringSerial.h>
#include <wiringPiI2C.h>
#define REG_INTR_STATUS_1 0x00
#define REG_INTR_STATUS_2 0x01
#define REG_INTR_ENABLE_1 0x02
#define REG_INTR_ENABLE_2 0x03
#define REG_FIFO_WR_PTR 0x04
#define REG_OVF_COUNTER 0x05
#define REG_FIFO_RD_PTR 0x06
#define REG_FIFO_DATA 0x07
#define REG_FIFO_CONFIG 0x08
#define REG_MODE_CONFIG 0x09
#define REG_SPO2_CONFIG 0x0A
#define REG_LED1_PA 0x0C
#define REG_LED2_PA 0x0D
#define REG_PILOT_PA 0x10
#define REG_MULTI_LED_CTRL1 0x11
#define REG_MULTI_LED_CTRL2 0x12
#define REG_TEMP_INTR 0x1F
#define REG_TEMP_FRAC 0x20
#define REG_TEMP_CONFIG 0x21
#define REG_PROX_INT_THRESH 0x30
#define REG_REV_ID 0xFE
#define REG_PART_ID 0xFF
int num = 0;
void FunMax30102Init(void)
{
//具体寄存器描述可查看MAX30102数据手册
wiringPiI2CWriteReg8(num, REG_MODE_CONFIG , 0x40); //复位
wiringPiI2CWriteReg8(num, REG_MODE_CONFIG , 0x40); //复位
wiringPiI2CWriteReg8(num, REG_INTR_ENABLE_1, 0xC0); //中断1使能 A_FULL_EN、ALC_OVF_EN、PROX_INT_EN
wiringPiI2CWriteReg8(num, REG_INTR_ENABLE_2, 0x00); //中断2使能 DIE_TEMP_RDY_EN
wiringPiI2CWriteReg8(num, REG_FIFO_WR_PTR , 0x00); //FIFO写指针
wiringPiI2CWriteReg8(num, REG_OVF_COUNTER , 0x00); //FIFO计数器
wiringPiI2CWriteReg8(num, REG_FIFO_RD_PTR , 0x00); //FIFO读指针
wiringPiI2CWriteReg8(num, REG_FIFO_CONFIG , 0xFF); //FIFO配置
wiringPiI2CWriteReg8(num, REG_MODE_CONFIG , 0x03); //设置为SPO2血氧检测模式
wiringPiI2CWriteReg8(num, REG_SPO2_CONFIG , 0x27); //SPO2配置
wiringPiI2CWriteReg8(num, REG_LED1_PA , 0x24); //LED1
wiringPiI2CWriteReg8(num, REG_LED2_PA , 0x24); //LED2
wiringPiI2CWriteReg8(num, REG_PILOT_PA , 0x7F); //
}
void FunMAX30102ReadFifo(unsigned int *PunRed, unsigned int *PunIr)
{
//在SPO2模式下,FIFO每个样本中会包括三个字节数据,且前三个字节为 RED,后三个字节为 IR,以此类推,因此在对数据进行读取时每回需要读取6个字节,前3个字节为RED,后三个字节为IR
unsigned int Temp0 = 0;
unsigned int Temp1 = 0;
wiringPiI2CReadReg8(num, REG_INTR_STATUS_1);
wiringPiI2CReadReg8(num, REG_INTR_STATUS_2);
Temp0 = wiringPiI2CReadReg8(num, REG_FIFO_DATA);
Temp0 <<= 16;
*PunRed += Temp0;
Temp0 = wiringPiI2CReadReg8(num, REG_FIFO_DATA);
Temp0 <<= 8;
*PunRed += Temp0;
Temp0 = wiringPiI2CReadReg8(num, REG_FIFO_DATA);
*PunRed += Temp0;
Temp1 = wiringPiI2CReadReg8(num, REG_FIFO_DATA);
Temp1 <<= 16;
*PunIr += Temp1;
Temp1 = wiringPiI2CReadReg8(num, REG_FIFO_DATA);
Temp1 <<= 8;
*PunIr += Temp1;
Temp1 = wiringPiI2CReadReg8(num, REG_FIFO_DATA);
*PunIr += Temp1;
*PunRed &= 0x3FFFF;
*PunIr &= 0x3FFFF;
}
int main()
{
int fd = 0;
int Temp = 0;
int FifoData = 0;
unsigned int PunRed = 0;
unsigned int PunIr = 0;
wiringPiSetup();
num = wiringPiI2CSetup(0x57);//gpio i2cdetect
if (num == -1)
{
printf("I2C Error\r\n");
}
else
{
printf("num = %d\r\n", num);
}
FunMax30102Init();
fd = serialOpen("/dev/ttyS0",115200);
pinMode(26,OUTPUT);
pinMode(27,OUTPUT);
pinMode(7, INPUT);
digitalWrite(26,HIGH);
digitalWrite(27,HIGH);
while(1)
{
//if (digitalRead(7) == 1)
{
FunMAX30102ReadFifo(&PunRed, &PunIr);
//FifoData = wiringPiI2CReadReg8(num, 0x07);
printf("%d , %d\r\n",PunRed, PunIr);
}
}
return 0;
}
试验结果:


相关参考链接:
https://blog.csdn.net/u012183892/article/details/109545972
https://blog.csdn.net/weixin_45633206/article/details/110276226
https://blog.csdn.net/lin5103151/article/details/109412943
本文来自博客园,作者:伽椰子真可爱,转载请注明原文链接:https://www.cnblogs.com/jiayezi/p/16918304.html

浙公网安备 33010602011771号