基于stm32,使用SGP30 CO2和TVOC传感器的初始化和数据读取程序。SGP30是一款用于测量二氧化碳(CO2)和总挥发性有机化合物(TVOC)浓度的传感器。程序中定义了相关的IIC通信函数,如起始信号、停止信号、发送和接收字节等。此外,程序还包含了一个主函数,用于初始化SGP30传感器,并读取CO2和TVOC的数据。
#include "sgp30_CO2_TVOC.h"
#include "user_peripheral.h"
#include "delay.h"
#include "usart.h"
#if SGP30_CO2_TVOC_Pre
void SGP30_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(SGP30_SCL_GPIO_CLK | SGP30_SDA_GPIO_SDA, ENABLE);
GPIO_InitStructure.GPIO_Pin = SGP30_SCL_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(SGP30_SCL_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = SGP30_SDA_GPIO_PIN;
GPIO_Init(SGP30_SDA_GPIO_PORT, &GPIO_InitStructure);
}
void SGP30_SDA_OUT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = SGP30_SDA_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(SGP30_SDA_GPIO_PORT, &GPIO_InitStructure);
}
void SGP30_SDA_IN(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = SGP30_SDA_GPIO_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(SGP30_SDA_GPIO_PORT, &GPIO_InitStructure);
}
void SGP30_IIC_Start(void)
{
SGP30_SDA_OUT();
SGP30_SDA = 1;
SGP30_SCL = 1;
delay_us(20);
SGP30_SDA = 0;
delay_us(20);
SGP30_SCL = 0;
}
void SGP30_IIC_Stop(void)
{
SGP30_SDA_OUT();
SGP30_SCL = 0;
SGP30_SDA = 0;
delay_us(20);
SGP30_SCL = 1;
SGP30_SDA = 1;
delay_us(20);
}
u8 SGP30_IIC_Wait_Ack(void)
{
u8 ucErrTime = 0;
SGP30_SDA_IN();
SGP30_SDA = 1;
delay_us(10);
SGP30_SCL = 1;
delay_us(10);
while(SGP30_SDA_READ())
{
ucErrTime++;
if(ucErrTime > 250)
{
SGP30_IIC_Stop();
return 1;
}
}
SGP30_SCL = 0;
return 0;
}
void SGP30_IIC_Ack(void)
{
SGP30_SCL = 0;
SGP30_SDA_OUT();
SGP30_SDA = 0;
delay_us(20);
SGP30_SCL = 1;
delay_us(20);
SGP30_SCL = 0;
}
void SGP30_IIC_NAck(void)
{
SGP30_SCL = 0;
SGP30_SDA_OUT();
SGP30_SDA = 1;
delay_us(20);
SGP30_SCL = 1;
delay_us(20);
SGP30_SCL = 0;
}
void SGP30_IIC_Send_Byte(u8 txd)
{
u8 t;
SGP30_SDA_OUT();
SGP30_SCL = 0;
for(t = 0; t < 8; t++)
{
if((txd & 0x80) >> 7)
SGP30_SDA = 1;
else
SGP30_SDA = 0;
txd <<= 1;
delay_us(20);
SGP30_SCL = 1;
delay_us(20);
SGP30_SCL = 0;
delay_us(20);
}
delay_us(20);
}
u16 SGP30_IIC_Read_Byte(u8 ack)
{
u8 i;
u16 receive = 0;
SGP30_SDA_IN();
for(i = 0; i < 8; i++ )
{
SGP30_SCL = 0;
delay_us(20);
SGP30_SCL = 1;
receive <<= 1;
if(SGP30_SDA_READ())
receive++;
delay_us(20);
}
if (!ack)
SGP30_IIC_NAck();
else
SGP30_IIC_Ack();
return receive;
}
void SGP30_Init(void)
{
SGP30_GPIO_Init();
SGP30_Write(0x20, 0x03);
}
void SGP30_Write(u8 a, u8 b)
{
SGP30_IIC_Start();
SGP30_IIC_Send_Byte(SGP30_write);
SGP30_IIC_Wait_Ack();
SGP30_IIC_Send_Byte(a);
SGP30_IIC_Wait_Ack();
SGP30_IIC_Send_Byte(b);
SGP30_IIC_Wait_Ack();
SGP30_IIC_Stop();
delay_ms(100);
}
u32 SGP30_Read(void)
{
u32 dat;
u8 crc;
SGP30_IIC_Start();
SGP30_IIC_Send_Byte(SGP30_read);
SGP30_IIC_Wait_Ack();
dat = SGP30_IIC_Read_Byte(1);
dat <<= 8;
dat += SGP30_IIC_Read_Byte(1);
crc = SGP30_IIC_Read_Byte(1);
crc = crc;
dat <<= 8;
dat += SGP30_IIC_Read_Byte(1);
dat <<= 8;
dat += SGP30_IIC_Read_Byte(0);
SGP30_IIC_Stop();
return(dat);
}
u32 sgp30_dat;
u32 CO2Data,TVOCData;
void SGP30_Init_ALL(void)
{
SGP30_Init();
delay_ms(100);
SGP30_Write(0x20,0x08);
sgp30_dat = SGP30_Read();
CO2Data = (sgp30_dat & 0xffff0000) >> 16;
TVOCData = sgp30_dat & 0x0000ffff;
while(CO2Data == 400 && TVOCData == 0)
{
SGP30_Write(0x20,0x08);
sgp30_dat = SGP30_Read();
CO2Data = (sgp30_dat & 0xffff0000) >> 16;
TVOCData = sgp30_dat & 0x0000ffff;
printf("?y?ú?ì2a?D...\r\n");
OLED_ShowString(0,4,(u8*)"co2 init wait...",16);
delay_ms(249);
delay_ms(251);
}
OLED_ShowString(0,4,(u8*)"co2 init ok...",16);
delay_ms(500);
OLED_Clear();
printf("......OK.....\r\n");
}
#endif
这是一个什么程序
|