仅供测试,本人亲测可用。
#include <reg52.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
#define slave_addr_write 0xb0
#define slave_addr_read 0xb1
sbit scl=P0^2;
sbit sda=P0^3;
void delay(uint num);
void usart_init();
uchar send_sgp30_flag;
//起始
void i2c_start()
{
sda=1;
delay(5);
scl=1;
delay(5);
sda=0;
delay(5);
scl=0;
delay(5);
}
//结束
void i2c_stop()
{
sda=0;
delay(5);
scl=1;
delay(5);
sda=1;
delay(5);
scl=0;
delay(5);
}
//主机应答
void master_ack()
{
scl=0;
delay(5);
sda=0;
delay(5);
scl=1;
delay(5);
scl=0;
delay(5);
sda=1;
delay(5);
}
//主机非应答
void master_nack()
{
sda=1;
delay(5);
scl=0;
delay(5);
scl=1;
delay(5);
scl=0;
delay(5);
sda=0;
delay(5);
sda=1;
delay(5);
}
//写一个字节
uchar i2c_write_byte(uchar buffer)
{
uchar i,j;
for(i=0;i<8;i++)
{
sda=(buffer<<i)&0x80;
delay(5);
scl=1;
delay(5);
scl=0;
delay(5);
}
sda=1;
delay(5);
scl=1;
delay(5);
while(sda)
{
j++;
if(j>200)
{
scl=0;
ES=0;
TI=1;
printf("no ack\n");
while(!TI);
TI=0;
ES=1;
return 0;
}
}
scl=0;
delay(5);
return 1;
}
//读一个字节
uchar i2c_read_byte(uchar ack)
{
uchar i,temp;
for(i=0;i<8;i++)
{
scl=1;
delay(5);
temp<<=1;
temp|=sda;
delay(5);
scl=0;
delay(5);
}
if(ack)
{
master_ack();
}
else
{
master_nack();
}
return temp;
}
//初始化
void init_air_quality()
{
i2c_start();
i2c_write_byte(slave_addr_write);
i2c_write_byte(0x20);
i2c_write_byte(0x03);
i2c_stop();
}
//开始测量
void measure_air_quality(uint *p)
{
uint tvoc,co2;
uchar crc;
i2c_start();
i2c_write_byte(slave_addr_write);
i2c_write_byte(0x20);
i2c_write_byte(0x08);
delay(200);
i2c_start();
i2c_write_byte(slave_addr_read);
co2=i2c_read_byte(1);
co2<<=8;
co2|=i2c_read_byte(1);
crc=i2c_read_byte(1);
*p=co2;
p++;
tvoc=i2c_read_byte(1);
tvoc<<=8;
tvoc|=i2c_read_byte(1);
crc=i2c_read_byte(0);
*p=tvoc;
i2c_stop();
}
void main()
{
uint buffer[2];
usart_init();
scl=0;
sda=0;
delay(100);
init_air_quality();
delay(200);
TR0=1;
ES=0;
TI=1;
printf("start! \n");
while(!TI);
TI=0;
ES=1;
measure_air_quality(buffer);
while(1)
{
if(send_sgp30_flag==1)//每隔1s发送一次
{
send_sgp30_flag=0;
measure_air_quality(buffer);
ES=0;
TI=1;
printf("co2 :%u ppm\r\n",buffer[0]);
printf("tvoc:%d ppd\n",buffer[1]);
while(!TI);
TI=0;
ES=1;
}
}
}
//串口和定时器初始化
void usart_init()
{
TMOD=0x21;
SCON=0X50;
TH1=0xfd;
TL1=0xfd;
TH0=(65536-45872)/256;
TL0=(65536-45872)%256;
TR0=0;
ET0=1;
TR1=1;
EA=1;
ES=1;
}
//1s定时
void time0() interrupt 1
{
uchar i;
TH0=(65536-45872)/256;
TL0=(65536-45872)%256;
i++;
if(i==20)
{
i=0;
send_sgp30_flag=1;
}
}
void delay(uint num)
{
uchar i,j;
for(i=0;i<num;i++)
for(j=0;j<20;j++);
}