当前位置: 首页 > news >正文

SGP30气体传感器详解 (STM32)

目录

一、介绍

二、传感器原理

原理图

三、程序设计

main.c文件

sgp30.c文件

sgp30.h文件

四、实验效果 

五、资料获取

项目分享


一、介绍

        SGP30是一种室内空气质量传感器,能够检测二氧化碳(CO2)和挥发性有机化合物(VOC)的浓度。这个模块采用了先进的传感器技术,可以提供高精度的空气质量数据。SGP30模块通常包括一个集成的传感器芯片和相应的电路,使其能够方便地与微控制器连接。它通常通过I2C总线与微控制器通信,因此可以轻松地集成到各种不同的嵌入式系统中。

以下是气体传感器的参数:

哔哩哔哩视频链接:

SGP30气体传感器(二氧化碳 STM32)

(资料分享见文末) 

二、传感器原理

原理图

三、程序设计

1.使用STM32F103C8T6读取SGP30气体传感器采集的二氧化碳数据,通过串口发送至电脑

2.将读取得到信息数据同时在OLED上显示

main.c文件

#include "stm32f10x.h"
#include "led.h"
#include "usart.h"
#include "delay.h"
#include "oled.h"
#include "sgp30.h"/*****************辰哥单片机设计******************STM32* 项目			:	SGP30气体传感器实验                     * 版本			:   V1.0* 日期			:   2025.8.1* MCU			:	STM32F103C8T6* 接口			:	参看sgp30.h							* BILIBILI    	:	辰哥单片机设计* CSDN			:	辰哥单片机设计* 作者			:	辰哥 **********************BEGIN***********************/uint16_t co2_value = 0;						  	//co2值
u8 buff[30];//参数显示缓存数组int main(void){ SystemInit();//配置系统时钟为72M	delay_init(72);LED_Init();LED_On();SGP30_Init();USART1_Config();//串口初始化OLED_Init();printf("Start \n");delay_ms(1000);OLED_Clear();//显示“二氧化碳:”OLED_ShowChinese(0,0,0,16,1);OLED_ShowChinese(16,0,1,16,1);OLED_ShowChinese(32,0,2,16,1);OLED_ShowChinese(48,0,3,16,1);OLED_ShowChar(64,0,':',16,1);while (1){LED_Toggle();Sgp30_Get_Co2_Value(&co2_value);	OLED_ShowNum(40,20,co2_value,3,16,1);OLED_ShowString(70,20,"ppm",16,1);delay_ms(100);	//延时100ms}
}

sgp30.c文件

#include "sgp30.h"
#include "delay.h"/*****************辰哥单片机设计******************STM32* 文件			:	SGP30气体传感器c文件                   * 版本			:   V1.0* 日期			:   2025.8.1* MCU			:	STM32F103C8T6* 接口			:	见代码							* BILIBILI    	:	辰哥单片机设计* CSDN			:	辰哥单片机设计* 作者			:	辰哥**********************BEGIN***********************/void SGP30_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(SGP30_IIC_CLK, ENABLE);GPIO_InitStructure.GPIO_Pin = SGP30_IIC_SCL_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(SGP30_IIC_PORT, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = SGP30_IIC_SDA_PIN;GPIO_Init(SGP30_IIC_PORT, &GPIO_InitStructure);
}void SDA_OUT(void)
{GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = SGP30_IIC_SDA_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(SGP30_IIC_PORT, &GPIO_InitStructure);
}void SDA_IN(void)
{GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = SGP30_IIC_SDA_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(SGP30_IIC_PORT, &GPIO_InitStructure);
}//产生IIC起始信号
void SGP30_IIC_Start(void)
{SDA_OUT();SGP30_IIC_SDA = 1;SGP30_IIC_SCL = 1;delay_us(20);SGP30_IIC_SDA = 0;	//START:when CLK is high,DATA change form high to lowdelay_us(20);SGP30_IIC_SCL = 0; 	//钳住I2C总线,准备发送或接收数据
}//产生IIC停止信号
void SGP30_IIC_Stop(void)
{SDA_OUT();SGP30_IIC_SCL = 0;SGP30_IIC_SDA = 0;	//STOP:when CLK is high DATA change form low to highdelay_us(20);SGP30_IIC_SCL = 1;SGP30_IIC_SDA = 1;	//发送I2C总线结束信号delay_us(20);
}//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
u8 SGP30_IIC_Wait_Ack(void)
{u8 ucErrTime = 0;SDA_IN();SGP30_IIC_SDA = 1;delay_us(10);SGP30_IIC_SCL = 1;delay_us(10);while(SGP30_READ_SDA){ucErrTime++;if(ucErrTime > 250){SGP30_IIC_Stop();return 1;}}SGP30_IIC_SCL = 0;  		//时钟输出0return 0;
}//产生ACK应答
void SGP30_IIC_Ack(void)
{SGP30_IIC_SCL = 0;SDA_OUT();SGP30_IIC_SDA = 0;delay_us(20);SGP30_IIC_SCL = 1;delay_us(20);SGP30_IIC_SCL = 0;
}//不产生ACK应答
void SGP30_IIC_NAck(void)
{SGP30_IIC_SCL = 0;SDA_OUT();SGP30_IIC_SDA = 1;delay_us(20);SGP30_IIC_SCL = 1;delay_us(20);SGP30_IIC_SCL = 0;
}//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
void SGP30_IIC_Send_Byte(u8 txd)
{u8 t;SDA_OUT();SGP30_IIC_SCL = 0; 	    	//拉低时钟开始数据传输for(t = 0; t < 8; t++){if((txd & 0x80) >> 7)SGP30_IIC_SDA = 1;elseSGP30_IIC_SDA = 0;txd <<= 1;delay_us(20);SGP30_IIC_SCL = 1;delay_us(20);SGP30_IIC_SCL = 0;delay_us(20);}delay_us(20);}//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
u16 SGP30_IIC_Read_Byte(u8 ack)
{u8 i;u16 receive = 0;SDA_IN();for(i = 0; i < 8; i++ ){SGP30_IIC_SCL = 0;delay_us(20);SGP30_IIC_SCL = 1;receive <<= 1;if(SGP30_READ_SDA)receive++;delay_us(20);}if (!ack)SGP30_IIC_NAck();//发送nACKelseSGP30_IIC_Ack(); //发送ACKreturn receive;
}//初始化IIC接口
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 = crc;  //为了不让出现编译警告dat <<= 8;dat += SGP30_IIC_Read_Byte(1);dat <<= 8;dat += SGP30_IIC_Read_Byte(0);SGP30_IIC_Stop();return(dat);
}
/****
*******SGP30获取CO2和TVOC值函数
*****/
void Sgp30_Get_Co2_Value(u16 *co2_value)
{u32 sgp30_data = 0;SGP30_Write(0x20,0x08);sgp30_data = SGP30_Read();if(sgp30_data != 0x01900000){*co2_value = (sgp30_data & 0xffff0000)>>16;}
}

sgp30.h文件

#ifndef __SGP30_H
#define	__SGP30_H
#include "stm32f10x.h"
#include "delay.h"
#include "sys.h"/*****************辰哥单片机设计******************STM32* 文件			:	SGP30二氧化碳传感器h文件                   * 版本			:   V1.0* 日期			:   2025.8.1* MCU			:	STM32F103C8T6* 接口			:	见代码							* BILIBILI    	:	辰哥单片机设计* CSDN			:	辰哥单片机设计* 作者			:	辰哥**********************BEGIN***********************//***************根据自己需求更改****************/
// SGP30 GPIO宏定义#define		SGP30_IIC_CLK										RCC_APB2Periph_GPIOA
#define 	SGP30_IIC_PORT									GPIOA
#define 	SGP30_IIC_SCL_PIN								GPIO_Pin_6	
#define 	SGP30_IIC_SDA_PIN								GPIO_Pin_7	//IO操作函数	 
#define SGP30_IIC_SCL    PAout(6) 		//SCL
#define SGP30_IIC_SDA    PAout(7) 		//SDA	 
#define SGP30_READ_SDA   PAin(7) 		//输入SDA /*********************END**********************/#define SGP30_read  0xb1                                    //SGP30的读地址
#define SGP30_write 0xb0                                    //SGP30的写地址//SGP30
void SGP30_IIC_Start(void);				                          //发送IIC开始信号
void SGP30_IIC_Stop(void);	  			                        //发送IIC停止信号
void SGP30_IIC_Send_Byte(u8 txd);			                      //IIC发送一个字节
u16 SGP30_IIC_Read_Byte(unsigned char ack);                 //IIC读取一个字节
u8 SGP30_IIC_Wait_Ack(void); 				                        //IIC等待ACK信号
void SGP30_IIC_Ack(void);					                          //IIC发送ACK信号
void SGP30_IIC_NAck(void);				                          //IIC不发送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);
void Sgp30_Get_Co2_Value(u16 *co2_value);#endif

四、实验效果 

五、资料获取

项目分享

http://www.dtcms.com/a/395917.html

相关文章:

  • stm32 BootLoader之检查栈顶地址是否合法(否则无法跳转到APP程序)
  • PyTorch 神经网络工具箱学习总结
  • 容器化 Spring Boot 应用程序
  • python 打包单个文件
  • Python自学21 - Python处理图像
  • 比特浏览器的IP适配性
  • LLHTTP测试
  • 2. 基于IniRealm的方式
  • 第三十四天:矩阵转置
  • MySQL执行计划:如何发现隐藏的性能瓶颈?
  • embedding多模态模型
  • ⚡ GitHub 热榜速报 | 2025 年 09 月 第 3 周
  • Synchronized的实现原理:深入理解Java线程同步机制
  • 初识C++、其中的引用、类(class)和结构体(struct)
  • Qt之常用控件之QWidget(四)
  • Pod生命周期
  • 【课堂笔记】复变函数-3
  • 深度学习-自然语言处理-序列模型与文本预处理
  • 【C语言】迭代与递归:两种阶乘实现方式的深度分析
  • CLIP多模态模型
  • 快手前端三面(准备一)
  • 前端-JS基础-day1
  • 【开题答辩全过程】以 J2EE在电信行业的应用研究为例,包含答辩的问题和答案
  • C++ QT Json数据的解析
  • RAG——动态护栏
  • Spring Boot 全局鉴权认证简单实现方案
  • 【靶场】webshop渗透攻击
  • 深入浅出现代GPU架构:核心类型、精度模式与选择
  • 开发避坑指南(53):git 命令行标签维护方法
  • javaEE初阶 网络编程(socket初识)