加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入

嵌入式外設(shè) -- 氣體傳感器(SGP30)驅(qū)動代碼編寫

06/07 11:44
2304
服務(wù)支持:
技術(shù)交流群

完成交易后在“購買成功”頁面掃碼入群,即可與技術(shù)大咖們分享疑惑和經(jīng)驗(yàn)、收獲成長和認(rèn)同、領(lǐng)取優(yōu)惠和紅包等。

虛擬商品不可退

當(dāng)前內(nèi)容為數(shù)字版權(quán)作品,購買后不支持退換且無法轉(zhuǎn)移使用。

加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論
放大
實(shí)物圖
相關(guān)方案
  • 方案介紹
    • 一、前言
    • 二、資料獲取
    • 三、設(shè)備使用
    • 四、代碼編寫
    • 五、參考
  • 相關(guān)文件
  • 推薦器件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

一、前言

SGP30是一種室內(nèi)空氣質(zhì)量傳感器,能夠檢測二氧化碳(CO2)和揮發(fā)性有機(jī)化合物(VOC)的濃度。這個(gè)模塊采用了先進(jìn)的傳感器技術(shù),可以提供高精度的空氣質(zhì)量數(shù)據(jù)。

SGP30模塊通常包括一個(gè)集成的傳感器芯片和相應(yīng)的電路,使其能夠方便地與微控制器連接。它通常通過I2C總線與微控制器通信,因此可以輕松地集成到各種不同的嵌入式系統(tǒng)中。

使用SGP30模塊進(jìn)行空氣質(zhì)量檢測通常包括以下步驟:

1. **初始化模塊**:連接SGP30模塊到微控制器,并初始化I2C通信。在此過程中,還需要進(jìn)行傳感器的初始化設(shè)置,以確保其正常工作。

2. **讀取傳感器數(shù)據(jù)**:通過I2C總線與SGP30傳感器通信,讀取當(dāng)前的二氧化碳和揮發(fā)性有機(jī)化合物的濃度數(shù)據(jù)。這些數(shù)據(jù)通常以數(shù)字形式返回,并且需要進(jìn)一步處理才能得到實(shí)際的濃度值。

3. **處理數(shù)據(jù)**:獲得的傳感器數(shù)據(jù)通常是原始的數(shù)字值,需要通過一些算法或者轉(zhuǎn)換函數(shù)進(jìn)行處理,以得到實(shí)際的CO2和VOC濃度值。通常情況下,傳感器供應(yīng)商會提供相應(yīng)的代碼庫或者示例代碼來幫助處理傳感器數(shù)據(jù)。

4. **應(yīng)用領(lǐng)域**:根據(jù)測得的空氣質(zhì)量數(shù)據(jù),可以進(jìn)行一系列的應(yīng)用,比如室內(nèi)空氣質(zhì)量監(jiān)測、空調(diào)系統(tǒng)控制、智能家居系統(tǒng)等。

總的來說,SGP30模塊是一種方便易用、高精度的室內(nèi)空氣質(zhì)量傳感器,可以幫助我們監(jiān)測和改善室內(nèi)空氣質(zhì)量,提高生活和工作的舒適度。

二、資料獲取

關(guān)注微信公眾號--星之援工作室 發(fā)送關(guān)鍵字(SGP30

網(wǎng)上開源的項(xiàng)目資料,可自行移植

????452c0cf75b1d4e4895194df8a5022c34.png

三、設(shè)備使用

接線

四、代碼編寫

?main.c

?實(shí)現(xiàn)函數(shù)調(diào)用

/*
1.項(xiàng)目名稱:綠深旗艦店SGP30模塊STM32F103C8T6測試程序
2.顯示模塊:串口返回?cái)?shù)據(jù),波特率9600
3.使用軟件:keil5 for ARM
4.配套上位機(jī):無
5.項(xiàng)目組成:SGP30模塊
6.項(xiàng)目功能:串口返回測量的CO2,TVOC數(shù)據(jù)
7.主要原理:具體參考SGP30數(shù)據(jù)手冊
8.購買地址:https://lssz.tmall.com 或淘寶上搜索“綠深旗艦店”
10.版權(quán)聲明:綠深旗艦店所有程序都申請軟件著作權(quán)。均與本店產(chǎn)品配套出售,請不要傳播,以免追究其法律責(zé)任!
接線定義
	VCC--5V
	GND--GND
	SCL--PB0
	SDA--PB1
*/

#include "sys.h"
#include "delay.h"
#include "SGP30.h"
#include "usart.h"

u32 CO2Data,TVOCData;//定義CO2濃度變量與TVOC濃度變量

int main(void)
{
	u32 sgp30_dat;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設(shè)置中斷優(yōu)先級分組為組2:2位搶占優(yōu)先級,2位響應(yīng)優(yōu)先級
	delay_init();
	uart_init(115200);
	SGP30_Init();   //初始化SGP30
	delay_ms(100);
	SGP30_Write(0x20,0x08);
	sgp30_dat = SGP30_Read();//讀取SGP30的值
	CO2Data = (sgp30_dat & 0xffff0000) >> 16;
	TVOCData = sgp30_dat & 0x0000ffff;	
	//SGP30模塊開機(jī)需要一定時(shí)間初始化,在初始化階段讀取的CO2濃度為400ppm,TVOC為0ppd且恒定不變,因此上電后每隔一段時(shí)間讀取一次
	//SGP30模塊的值,如果CO2濃度為400ppm,TVOC為0ppd,發(fā)送“正在檢測中...”,直到SGP30模塊初始化完成。
	//初始化完成后剛開始讀出數(shù)據(jù)會波動比較大,屬于正?,F(xiàn)象,一段時(shí)間后會逐漸趨于穩(wěn)定。
	//氣體類傳感器比較容易受環(huán)境影響,測量數(shù)據(jù)出現(xiàn)波動是正常的,可自行添加濾波函數(shù)。
	while(CO2Data == 400 && TVOCData == 0)
	{
		SGP30_Write(0x20,0x08);
		sgp30_dat = SGP30_Read();//讀取SGP30的值
		CO2Data = (sgp30_dat & 0xffff0000) >> 16;//取出CO2濃度值
		TVOCData = sgp30_dat & 0x0000ffff;			 //取出TVOC值
		printf("正在檢測中...rn");
		delay_ms(500);
	}
	while(1)
	{
		SGP30_Write(0x20,0x08);
		sgp30_dat = SGP30_Read();//讀取SGP30的值
		CO2Data = (sgp30_dat & 0xffff0000) >> 16;//取出CO2濃度值
		TVOCData = sgp30_dat & 0x0000ffff;       //取出TVOC值
		printf("CO2:%dppmrnTVOC:%dppdrn",CO2Data,TVOCData);
		delay_ms(500);
	}
}


sgp30.c

#include "sgp30.h"
#include "delay.h"



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 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 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);
}

//產(chǎn)生IIC起始信號
void SGP30_IIC_Start(void)
{
  SDA_OUT();
  SGP30_SDA = 1;
  SGP30_SCL = 1;
  delay_us(20);

  SGP30_SDA = 0;	//START:when CLK is high,DATA change form high to low
  delay_us(20);
  SGP30_SCL = 0; 	//鉗住I2C總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù)
}

//產(chǎn)生IIC停止信號
void SGP30_IIC_Stop(void)
{
  SDA_OUT();
  SGP30_SCL = 0;
  SGP30_SDA = 0;	//STOP:when CLK is high DATA change form low to high
  delay_us(20);
  SGP30_SCL = 1;
  SGP30_SDA = 1;	//發(fā)送I2C總線結(jié)束信號
  delay_us(20);
}

//等待應(yīng)答信號到來
//返回值:1,接收應(yīng)答失敗
//        0,接收應(yīng)答成功
u8 SGP30_IIC_Wait_Ack(void)
{
  u8 ucErrTime = 0;
  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;  		//時(shí)鐘輸出0
  return 0;
}

//產(chǎn)生ACK應(yīng)答
void SGP30_IIC_Ack(void)
{
  SGP30_SCL = 0;
  SDA_OUT();
  SGP30_SDA = 0;
  delay_us(20);
  SGP30_SCL = 1;
  delay_us(20);
  SGP30_SCL = 0;
}

//不產(chǎn)生ACK應(yīng)答
void SGP30_IIC_NAck(void)
{
  SGP30_SCL = 0;
  SDA_OUT();
  SGP30_SDA = 1;
  delay_us(20);
  SGP30_SCL = 1;
  delay_us(20);
  SGP30_SCL = 0;
}

//IIC發(fā)送一個(gè)字節(jié)
//返回從機(jī)有無應(yīng)答
//1,有應(yīng)答
//0,無應(yīng)答
void SGP30_IIC_Send_Byte(u8 txd)
{
  u8 t;
  SDA_OUT();
  SGP30_SCL = 0; 	    	//拉低時(shí)鐘開始數(shù)據(jù)傳輸
  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);

}

//讀1個(gè)字節(jié),ack=1時(shí),發(fā)送ACK,ack=0,發(fā)送nACK
u16 SGP30_IIC_Read_Byte(u8 ack)
{
  u8 i;
  u16 receive = 0;
  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();//發(fā)送nACK
  else
    SGP30_IIC_Ack(); //發(fā)送ACK
  return receive;
}


//初始化IIC接口
void SGP30_Init(void)
{
  SGP30_GPIO_Init();
  SGP30_Write(0x20, 0x03);
//	SGP30_ad_write(0x20,0x61);
//	SGP30_ad_write(0x01,0x00);
}


void SGP30_Write(u8 a, u8 b)
{
  SGP30_IIC_Start();
  SGP30_IIC_Send_Byte(SGP30_write); //發(fā)送器件地址+寫指令
  SGP30_IIC_Wait_Ack();
  SGP30_IIC_Send_Byte(a);		//發(fā)送控制字節(jié)
  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); //發(fā)送器件地址+讀指令
  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數(shù)據(jù),舍去
  crc = crc;  //為了不讓出現(xiàn)編譯警告
  dat <<= 8;
  dat += SGP30_IIC_Read_Byte(1);
  dat <<= 8;
  dat += SGP30_IIC_Read_Byte(0);
  SGP30_IIC_Stop();
  return(dat);
}




sgp30.h

#ifndef __HX711_H
#define __HX711_H
#include "sys.h"

#define  SGP30_SCL   PBout(0)
#define  SGP30_SDA   PBout(1)


// USART GPIO 引腳宏定義
#define  SGP30_SCL_GPIO_CLK        RCC_APB2Periph_GPIOB
#define  SGP30_SCL_GPIO_PORT       GPIOB
#define  SGP30_SCL_GPIO_PIN        GPIO_Pin_0

#define  SGP30_SDA_GPIO_SDA        RCC_APB2Periph_GPIOB
#define  SGP30_SDA_GPIO_PORT       GPIOB
#define  SGP30_SDA_GPIO_PIN        GPIO_Pin_1

#define  SGP30_SDA_READ()           GPIO_ReadInputDataBit(SGP30_SDA_GPIO_PORT, SGP30_SDA_GPIO_PIN)

#define SGP30_read  0xb1  //SGP30的讀地址
#define SGP30_write 0xb0  //SGP30的寫地址


void SGP30_IIC_Start(void);				//發(fā)送IIC開始信號
void SGP30_IIC_Stop(void);	  			//發(fā)送IIC停止信號
void SGP30_IIC_Send_Byte(u8 txd);			//IIC發(fā)送一個(gè)字節(jié)
u16 SGP30_IIC_Read_Byte(unsigned char ack);//IIC讀取一個(gè)字節(jié)
u8 SGP30_IIC_Wait_Ack(void); 				//IIC等待ACK信號
void SGP30_IIC_Ack(void);					//IIC發(fā)送ACK信號
void SGP30_IIC_NAck(void);				//IIC不發(fā)送ACK信號
void SGP30_IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
u8 SGP30_IIC_Read_One_Byte(u8 daddr,u8 addr);	
void SGP30_Init(void);				  
void SGP30_Write(u8 a, u8 b);
u32 SGP30_Read(void);



#endif

五、參考

物聯(lián)網(wǎng)畢設(shè) -- 智能倉儲(STM32+APP+云平臺icon-default.png?t=N7T8https://blog.csdn.net/herui_2/article/details/136225040?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22136225040%22%2C%22source%22%3A%22herui_2%22%7D


聯(lián)系方式 微信號:13648103287

  • 聯(lián)系方式.docx

推薦器件

更多器件
器件型號 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊 ECAD模型 風(fēng)險(xiǎn)等級 參考價(jià)格 更多信息
AD590MF 1 General Electric Solid State Sensor/Transducer, 2 Pin, Ceramic
$91.96 查看
LM20BIM7/NOPB 1 Texas Instruments ±1.5&deg;C Analog Output Temperature Sensor 5-SC70 -55 to 130

ECAD模型

下載ECAD模型
$1.5 查看
AD7814ARTZ-REEL7 1 Analog Devices Inc Temperature Sensor: 10-Bit Digital in 6-Lead SOT-23

ECAD模型

下載ECAD模型
$2.83 查看

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

方案定制,程序設(shè)計(jì)方案、單片機(jī)程序設(shè)計(jì)與講解、APP定制開發(fā)。本公眾號致力于向讀者傳遞關(guān)于程序設(shè)計(jì)和開發(fā)的相關(guān)知識,并分享一些關(guān)于軟件開發(fā)的最佳實(shí)踐。如果您有什么問題或建議,請隨時(shí)聯(lián)系我們。我們將竭誠為您服務(wù)