仅供测试,本人亲测可用。
#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)%6; TR0=0; ET0=1; TR1=1; EA=1; ES=1; } //1s定时 void time0() interrupt 1 { uchar i; TH0=(65536-45872)/256; TL0=(65536-45872)%6; 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 ); }