SGP30传感器
基本电器特性
SGP30 | value |
---|---|
工作电压 | 1.62v-1.92v |
TVOC测量范围 | 0ppb-60000ppb |
CO2测量范围 | 400ppm-60000ppm |
采样率 | 1HZ |
通信协议 | IIC |
引脚图
SGP30读取数据
SGP30的命令都是双字节的,先发高位,有如下命令:
SGP30初始化命令:0x2003
获取空气质量值命令:0x2008
SGP30获取的数据格式为:2位CO2数据+1位CO2的CRC校验+2位TVOC数据+1位TVOC的CRC校验。
模块上电需要15s左右初始化,在初始化阶段读取的CO2浓度为400ppm,TVOC为0ppd且恒定不变。因此上电后一直读,直到TVOC不为0并且CO2不为400,SGP30模块才初始化完成。
IIC协议
IIC通信时序
START条件:当SCL=1时,SDA由1变成0
STOP条件:当SCL=1时,SDA由0变成1
数据传输只能在SCL=1时进行。
#include<HT66F2390.h>
#define SCL _pf5
#define SDA _pf4
#define SCLC _pfc5
#define SDAC _pfc4
void I2C_START(void)
{ SCL=0; SDA=1; //設定 SCL=0, SDA=1
SCLC=0; SDAC=0; //SCL/SDA為輸出模式
SCL=1; pause(); //SCL=1, SDA=1
SDA=0; //SDA=0
SCL=0; //SCL=0
}
void I2C_STOP(void)
{ SCL=0; SDA=0; //設定 SCL=0, SDA=0
SDAC=0; //SDA 為輸出模式
SCL=1; //SCL=1
SDA=1; //SDA=1
SCL=0; //SCL=0
}
void CheckACK(void)
{ SDAC=1; //SDA 為輸入模式
SCL=1; //設定 SCL=1
while(SDA); //等待 ACK(Low)
SCL=0; //設定 SCL=0
}
void WriteByte(u8 I2CData)
{ u8 temp=0b10000000;
SDAC=0; //SDA為輸出模式
while(temp!=0) //傳送8個位元
{ SDA=(I2CData & temp)?1:0; pause(); //設定 SDA 準位
SCL=1; pause(); SCL=0; //產生 SCL Clock
temp>>=1; //下一位元
}
}
u8 ReadByte(void)
{ u8 I2CData=0, temp=0b10000000;
SDAC=1; //設定 SDA 為輸入模式
while(temp!=0) //接收8個位元
{ SCL=1; pause(); //設定 SCL=1
if(SDA) I2CData|=temp; //接收位元值
SCL=0; //設定 SCL=0
temp>>=1; //下一位元
}
return I2CData;
}
void I2C_ACK(void) //应答函数
{
SDAC=1; //设定SDA为输入模式
SCL=0; //设定SCL=0
delayus(2);
SDA=0;
delayus(2)
SCL=1; //设定SCL=1
delayus(5);
SCL=0; //设定SCL=0
}
void I2C_NACK(void) //非应答函数
{
SDAC=1;
SCL=0;
delayus(2);
SDA=1;
delayus(2);
SCL=1;
delayus(5);
SCL=0;
}
void Delayms(u16 del)
{ u16 i; //@fSYS=8MH,延遲del*1ms
for(i=0;i<del;i++) GCC_DELAY(2000); //Delay 1ms @ 8MHz
}
//时钟频率:8Mhz
//机器周期:2个时钟周期
//指令周期:6个机器周期 = 12个时钟周期
void delay(int count)
{
int i;
for(i=1;i<=count;i++)
;
}
//延时 = (1/8M)*12*50*2(计数) = 0.000075 s= 75us
SGP30实现
代码部分
#SGP30_SlaveAddress 0xB0
void SGP30_Write_Data(uchar address,uchar dat)//向SGP30的地址address中写入一个字节的数据
{
I2C_START();
WriteByte(SGP30_SlaveAddress);
WriteByte(address);
WriteByte(dat);
I2C_STOP();
}
ulong SGP30_Read_Data()//从SGP30的地址address中读取一个字节的数据
{
ulong dat;
SGP30_IIC_Start();
WriteByte(SGP30_SlaveAddress + 1);
dat =ReadByte(); //CO2高位数据
dat <<= 8;
dat += ReadByte(); //CO2低位数据
dat <<= 8;
dat +=ReadByte(); //TVOC高位数据
dat <<= 8;
dat +=ReadByte(); //TVOC低位数据
I2C_STOP();
return(dat);
}
void SGP30_Init(void)//SGP30初始化函数
{
SGP30_Write_Data(0x20,0x03);
}
void SGP30_Get_Co2_Tvoc_Value(uint *co2_value, uint *tvoc_value)//SGP30获取CO2和TVOC值函数
{
ulong sgp30_value;
SGP30_Write_Data(0x20,0x08);
sgp30_value = SGP30_Read_Data();
*co2_value = (sgp30_value & 0xffff0000) >> 16;
*tvoc_value = sgp30_value & 0x0000ffff;
}