JW01二氧化碳传感器(串行通信 STM32)

news2024/11/15 9:15:32

目录

一、介绍

二、传感器原理

1.工作原理介绍

2.串口数据流格式

三、程序设计

main.c文件

usart3.h文件

usart3.c文件

四、实验效果 

五、资料获取

项目分享


一、介绍

        JW01-CO2检测模块是一种用于检测空气中二氧化碳浓度的传感器模块。它可以广泛应用于室内空气质量检测、智能家居、温室气体监测等领域。模块采用非分散红外(NDIR)技术进行测量,可以测量空气中的CO2浓度范围从3502000ppm,具有高精度和快速响应的特点。模块采用串口通信方式,可以与单片机或其他设备进行通信。

以下是JW01二氧化碳传感器的参数:

型号

JW01-CO2-V2.2

工作电压

 5.0±0.2VDC

工作电流

80mA

量程

 350-2000PPM

工作温度

-10~40

探测气体

二氧化碳

预热时间

60s

哔哩哔哩视频链接:

JW01二氧化碳传感器(串行通信 STM32)

(资料分享见文末) 

二、传感器原理

1.工作原理介绍

特别说明:

本模块是用TVOC类型传感器经过软件换算的二氧化碳模拟数值,对于其它气体不具有抗干扰性,选择使用时,请留意本说明事项。

2.串口数据流格式

B1的内容2Ch是模块定地址

校验和(B6)=unit_8(B1+B2+B3+B4+B5)

C02气体浓度值(PPM)=(C0z浓度高(B2)*256+C0z浓度低(B3))

数据范例:

例如读到值是2Ch,0lh,90h,03h,0FFh,BFh,则得出如下结果:

校验和:BFh=2Ch+01h+90h+03h+0FFh

C02数值:B2*256+B3=01h*256+90h=400ppm

三、程序设计

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

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

JW01_A

PB10

JW01_B

PB11

OLED_SCL

PB1

OLED_SDA

PB0

串口

串口1

注意:初次上电使用建议需预热 5-10 分钟以上进行测试

main.c文件

#include "stm32f10x.h"
#include "led.h"
#include "usart.h"
#include "delay.h"
#include "oled.h"
#include "usart3.h"

/*****************辰哥单片机设计******************
											STM32
 * 项目			:	JW01二氧化碳传感器实验                     
 * 版本			: V1.0
 * 日期			: 2024.9.14
 * MCU			:	STM32F103C8T6
 * 接口			:	参看usart3.h							
 * BILIBILI	:	辰哥单片机设计
 * CSDN			:	辰哥单片机设计
 * 作者			:	辰哥 

**********************BEGIN***********************/

uint16_t co2;

u8 buff[30];

int main(void)
{ 
	
  SystemInit();//配置系统时钟为72M	
	delay_init(72);
	LED_Init();
	LED_On();
	USART1_Config();
	USART3_Config();
	
	OLED_Init();
	printf("Start \n");
	delay_ms(1000);
	//显示“二氧化碳:”
	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();
		CO2GetData(&co2);
		
		sprintf((char*)buff,"%dppm  ",co2);
//		
		printf("二氧化碳浓度: %dppm\r\n",co2);
		
		OLED_ShowString(50,30,buff,16,1);

		delay_ms(500);
  }
}

usart3.h文件

#ifndef __USART1_H
#define	__USART1_H

#include "stm32f10x.h"
#include <stdio.h>

void USART1_Config(void);
int fputc(int ch, FILE *f);
void USART1_printf(USART_TypeDef* USARTx, uint8_t *Data,...);

#endif /* __USART1_H */

usart3.c文件

#include "usart3.h"	

/*****************辰哥单片机设计******************
											STM32
 * 项目			:	JW01二氧化碳传感器实验                     
 * 版本			: V1.0
 * 日期			: 2024.9.14
 * MCU			:	STM32F103C8T6
 * 接口			:	串口3						
 * BILIBILI	:	辰哥单片机设计
 * CSDN			:	辰哥单片机设计
 * 作者			:	辰哥 

**********************BEGIN***********************/

uint8_t Usart3_RxPacket[6];				//定义接收数据包数组
uint8_t Usart3_RxFlag;					//定义接收数据包标志位

void USART3_Config(void){
    //GPIO端口设置
    GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	 
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);	//使能USART3,GPIOA时钟
  	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	//使能GPIOB时钟
	
	//USART3_TX   GPIOB.10
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PB10
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
    GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB.10
   
    //USART3_RX	  GPIOB.11初始化
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;//PB11
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB.11  

  //Usart3 NVIC 配置
    NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4;		//子优先级4
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
  
   //USART 初始化设置

	USART_InitStructure.USART_BaudRate = 9600;//串口波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式

    USART_Init(USART3, &USART_InitStructure); //初始化串口3
    USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启串口接受中断
    USART_Cmd(USART3, ENABLE);                    //使能串口3 

}

void USART3_IRQHandler(void)                	//串口3中断服务程序
{
		uint8_t Res;
		static uint8_t RxState = 0;		//当前状态机状态
		static uint8_t pRxPacket = 0;	//当前接收数据位置

		if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
		{
			Res =USART_ReceiveData(USART3);	//读取接收到的数据	
			switch (RxState)
			{
				case 0: 
					if (Res == 0x2C)
					{
						Usart3_RxPacket[pRxPacket] = Res;	//将数据存入数组
						pRxPacket++;
						RxState = 1;

					}
					else
					{
						pRxPacket = 0;
						RxState = 0;
					}
					break;
				case 1: 
						Usart3_RxPacket[pRxPacket] = Res;	//将数据存入数组
						pRxPacket++;
						if(pRxPacket >= 6)
						{
							pRxPacket = 0;
							RxState = 2;
						}
					break;
				case 2:
					if (Usart3_RxPacket[5] == (uint8_t)(Usart3_RxPacket[0] + Usart3_RxPacket[1]	//验证接收到的数据是否正确
						+ Usart3_RxPacket[2] + Usart3_RxPacket[3] + Usart3_RxPacket[4]))
					{
						
						RxState = 0;
						pRxPacket = 0;
						Usart3_RxFlag = 1;		//接收数据包标志位置1,成功接收一个数据包
					}
					else
					{
						pRxPacket = 0;
						RxState = 0;
					}
					break;
			}
			
			USART_ClearITPendingBit(USART3, USART_IT_RXNE);		//清除标志位
		} 
} 


void CO2GetData(uint16_t *data)
{
	if (Usart3_RxFlag == 1)
	{
		Usart3_RxFlag = 0;
		*data = Usart3_RxPacket[1] * 256 + Usart3_RxPacket[2];
	}
}

四、实验效果 

五、资料获取

项目分享

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2161512.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java算法OJ(1)位运算

目录 1.前言 2.正文 2.1位运算符号 2.1俩数相除 2.1.1题目 2.1.2示例 2.1.3题解 2.2二进制求和 2.2.1题目 2.2.2示例 2.2.3题解 2.3只出现一次的数字 2.3.1题目 2.3.2示例 2.3.3题解 2.4只出现一次的数字&#xff08;进阶版&#xff09; 2.4.1题目 2.4.2示例…

glb数据格式

glb数据格式 glb 文件格式只包含一个glb 文件&#xff0c;文件按照二进制存储&#xff0c;占空间小 浏览 浏览glb工具的很多&#xff0c;ccs&#xff0c;3D查看器等都可以&#xff0c;不安装软件的话用下面网页加载就可以&#xff0c;免费 glTF Viewer (donmccurdy.com) glb…

uniapp小程序中通过uni.setClipboardData实现复制功能无效的原因和解决方案

// 复制下载链接const shareFile (filePath) > {const pdfUrl 复制内容uni.showModal({title: 下载提示,content: 请复制链接到浏览器中下载,confirmColor: #eb2444,confirmText: 复制链接,success(res) {if (res.confirm) {uni.setClipboardData({data: pdfUrl, // url地…

C++: unordered系列关联式容器

目录 1. unordered系列关联式容器1.1 unordered_map1.2 unordered_set 2. 哈希概念3. 哈希冲突4. 闭散列5. 开散列 博客主页: 酷酷学 感谢关注!!! 正文开始 1. unordered系列关联式容器 在C98中&#xff0c;STL提供了底层为红黑树结构的一系列关联式容器&#xff0c;在查询时…

【笔记】自动驾驶预测与决策规划_Part4_时空联合规划

文章目录 0. 前言1. 时空联合规划的基本概念1.1 时空分离方法1.2 时空联合方法 2.基于搜索的时空联合规划 &#xff08;Hybrid A* &#xff09;2.1 基于Hybrid A* 的时空联合规划建模2.2 构建三维时空联合地图2.3 基于Hybrid A*的时空节点扩展2.4 Hybrid A* &#xff1a;时空节…

多线程——“死锁”

目录 前言 一、一个线程&#xff0c;一把锁 1.问题介绍 2.可重入锁 二、两个线程&#xff0c;两把锁 1.问题介绍 2.解决方式 三、N个线程&#xff0c;M把锁 1.哲学家就餐问题 2.解决方式 结尾 前言 “死锁”是多线程代码中一类常见的问题&#xff0c;加锁是能解决线…

plt的简单使用

目录 介绍示例 介绍 plt 是 Python 中 Matplotlib 库的一个常用别名&#xff0c;它表示 pyplot&#xff0c;这是一个用于创建图形和图形的可视化表示的工具。下面是一些 plt 函数的详解和示例&#xff0c;以帮助大家理解和使用。 示例 示例1&#xff1a; import matplotlib…

AV1 Bitstream Decoding Process Specification--[9]:语法结构语义-5

原文地址&#xff1a;https://aomediacodec.github.io/av1-spec/av1-spec.pdf 没有梯子的下载地址&#xff1a;AV1 Bitstream & Decoding Process Specification摘要&#xff1a;这份文档定义了开放媒体联盟&#xff08;Alliance for Open Media&#xff09;AV1视频编解码…

loadrunner个人笔记

创建场景配置&#xff1a; 两个同时 去四&#xff1a;日志、时间、模拟、其他自动事务 加一&#xff1a;首选项 1、写脚本&#xff0c;沟通官方、文件打印扫描 MFI-sw.support.gsd.imsc.sda.globalopentext.com support.casemicrofocus.com 支持资源 | Micro Focus | OpenT…

【毕业论文+源码】基于ASP的课程指导平台的开发

引 言 随着全球信息化技术的兴起&#xff0c;特别是Internet的日益普及&#xff0c;解决了信息Internet上传递的问题&#xff0c;建立了一个组织得很好的信息结构框架&#xff0c;使得Internet用户能够在Internet上的任何一个终端&#xff0c;以一种简单、统一的方式来访问超…

Leetcode Hot 100刷题记录 -Day18(反转链表)

反转链表&#xff1a; 问题描述&#xff1a; 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]示例 2&#xff1a; 输入&#xff1a;head [1,2] 输出&a…

视频监控相关笔记

一、QT 之 QTreeWidget 树形控件 Qt编程指南&#xff0c;Qt新手教程&#xff0c;Qt Programming Guide 一个树形结构的节点中的图表文本 、附带数据的添加&#xff1a; QTreeWidgetItem* TourTreeWnd::InsertNode(NetNodeInfo node, QTreeWidgetItem* parent_item) { // …

回文子串通用做法

647. 回文子串 先引出力扣链接 给定一个字符串&#xff0c;你的任务是计算这个字符串中有多少个回文子串。 具有不同开始位置或结束位置的子串&#xff0c;即使是由相同的字符组成&#xff0c;也会被视作不同的子串。示例 1&#xff1a; 输入&#xff1a;"abc" 输出…

for循环的应用

正三角 for (int i 0; i < 8; i) { for (int j 0; j < 15; j) { int kong 8 - i - 1; int star 2 * i 1; if (j < kong) { Console.Write(" "); } else if (j < kong star)…

【LLM学习之路】9月23日24日 第十、十一天 Attention代码解读

【LLM学习之路】9月23日24日 第十、十一天 Attention代码解读 Transformer模型大致分为三类 纯 Encoder 模型&#xff08;例如 BERT&#xff09;&#xff0c;又称自编码 (auto-encoding) Transformer 模型&#xff1b;纯 Decoder 模型&#xff08;例如 GPT&#xff09;&#…

多颜色绘制语义分割/变化检测结果图

在论文绘图时&#xff0c;传统的二元语义分割结果图颜色单一&#xff08;下图左&#xff09;&#xff0c;所以论文中常根据混淆矩阵类别使用多颜色进行绘制&#xff08;下图右&#xff09;&#xff0c;可以看到&#xff0c;结果的可视化效果更好。 以下是绘制代码&#xff1a; …

同等学力申硕英语网课如何选择

很多考生想知道同等学力申硕英语网课如何选择&#xff0c;小编告诉大家&#xff0c;首先明确自己的学习目标和需求是为了提高口语、阅读、写作还是听力能力? 只有明确了自己的学习目标和需求&#xff0c;才能更好地选择适合自己的课程和平台。 二、选择知名品牌和口碑良好的平…

UE5地图白屏/过曝/非常亮の解决方法

今天遇到一个问题 , 新建项目 , 打开虚幻第三人称地图的默认关卡 , 发现白屏 , 啥也看不见 猜测可能是虚幻编辑器的bug , 造成白屏的原因应该是场景过曝了 记录一下解决方案 第一种解决方法 找到场景中的 后期处理体积 (PostProcessVolume) 直接删掉 或者找到 细节面板中 -…

衍射的角谱理论

一、单色平面波与本征函数 不考虑夫琅禾费近似, 则相干光场在给定二平面间的传播过程就是通过一个二维线性空不变系统。 上式函数是这个系统的本征函数,表示振幅为1的平面波在xy平面上的复振幅分布,空间频率分量 = cos / , = cos / 与平面波的传播方向相联系, 空间…

java和mysql命名规则不一样,每次在mybatis中起别名太麻烦?来看看如何设置自动自动映射!

简介&#xff1a; 在 Java 开发中&#xff0c;当使用 MyBatis 框架连接 Java 代码与 MySQL 数据库时&#xff0c;常常会遇到 Java 和 MySQL 命名规则不一致的问题&#xff0c;这使得每次在 MyBatis 中为查询结果起别名变得繁琐。本教程将深入探讨如何设置自动映射&#xff0c;以…