JW01-CO2-V2.2二氧化碳检测模块
硬件外观
JW01介绍及供电
JW01:三合一空气检测。可以检测CO2、甲醛、TVOC(有机气态物质)三种气体浓度。
- 供电:
- JW01的输出口(TXD)是5V的
-
- 如上图所示,IO口有标注FT的引脚即是可以接受5V电压的。
- STM32F103C8T6的USART2就不能接受5V电压的,USART1、和USART3支持5V,我们下面的代码选择USART1
- 使用时需要预热大概60s
- 在下面的代码里,两个uint8_t的数组元素相加的结果是一个uint16_t类型的值
- OLED用的江科大的
示例代码
网上买到的分两种串口数据流格式:
-
第一种串口数据流格式:有6个字节
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
void JW01_Init(void){
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能外设时钟
GPIO_InitTypeDef GPIO_Init_Struct;
GPIO_Init_Struct.GPIO_Mode=GPIO_Mode_AF_PP; //TXD为复用推挽输出
GPIO_Init_Struct.GPIO_Pin=GPIO_Pin_9; //9号为TXD
GPIO_Init_Struct.GPIO_Speed=GPIO_Speed_50MHz; //这个随意
GPIO_Init(GPIOA,&GPIO_Init_Struct);
GPIO_Init_Struct.GPIO_Mode=GPIO_Mode_IN_FLOATING; //RXD为浮空输入
GPIO_Init_Struct.GPIO_Pin=GPIO_Pin_10; //10号为RXD
GPIO_Init(GPIOA,&GPIO_Init_Struct);
USART_InitTypeDef Usart_Init_Struct;
Usart_Init_Struct.USART_BaudRate=9600; //波特率
Usart_Init_Struct.USART_HardwareFlowControl=USART_HardwareFlowControl_None; //无硬件控制流
Usart_Init_Struct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx; //收发模式
Usart_Init_Struct.USART_Parity=USART_Parity_No; //无校验
Usart_Init_Struct.USART_StopBits=USART_StopBits_1; //停止位1位
Usart_Init_Struct.USART_WordLength=USART_WordLength_8b; //数据位8位
USART_Init(USART1,&Usart_Init_Struct);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //开启接收中断
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //NVIC中断配置
NVIC_InitTypeDef nitd;
nitd.NVIC_IRQChannel=USART1_IRQn;
nitd.NVIC_IRQChannelCmd=ENABLE;
nitd.NVIC_IRQChannelPreemptionPriority=2;
nitd.NVIC_IRQChannelSubPriority=2;
NVIC_Init(&nitd);
USART_Cmd(USART1,ENABLE);
}
uint8_t CO2_Data[6]; //存放接收到的数据包
void USART1_IRQHandler(void){
static uint8_t index=0;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){
CO2_Data[index]=USART_ReceiveData(USART1);
if(index==0&&CO2_Data[index]!=0x2C){ //固定数据包的开头
return;
}else{
if(++index>=6) index=0;
}
USART_ClearITPendingBit(USART1,USART_FLAG_RXNE); //清除数据接收标志位
}
}
int main(void){
OLED_Init();
JW01_Init();
OLED_ShowString(1,1,"Hello World");
OLED_ShowString(2,1,"CO2 is ");
while(1){
if(CO2_Data[5]==(uint8_t)(CO2_Data[0]+CO2_Data[1]+CO2_Data[2]+CO2_Data[3]+CO2_Data[4])){
OLED_ShowNum(2,8,CO2_Data[1]*256+CO2_Data[2],5);
}else{
OLED_ShowString(2,8,"ERROR");
}
OLED_ShowHexNum(3,1,CO2_Data[0],2);
OLED_ShowHexNum(3,4,CO2_Data[1],2);
OLED_ShowHexNum(3,7,CO2_Data[2],2);
OLED_ShowHexNum(4,1,CO2_Data[3],2);
OLED_ShowHexNum(4,4,CO2_Data[4],2);
OLED_ShowHexNum(4,7,CO2_Data[5],2);
}
}
-
第二种串口数据流格式:有9个字节
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
void JW01_Init(void){
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能外设时钟
GPIO_InitTypeDef GPIO_Init_Struct;
GPIO_Init_Struct.GPIO_Mode=GPIO_Mode_AF_PP; //TXD为复用推挽输出
GPIO_Init_Struct.GPIO_Pin=GPIO_Pin_9; //9号为TXD
GPIO_Init_Struct.GPIO_Speed=GPIO_Speed_50MHz; //这个随意
GPIO_Init(GPIOA,&GPIO_Init_Struct);
GPIO_Init_Struct.GPIO_Mode=GPIO_Mode_IN_FLOATING; //RXD为浮空输入
GPIO_Init_Struct.GPIO_Pin=GPIO_Pin_10; //10号为RXD
GPIO_Init(GPIOA,&GPIO_Init_Struct);
USART_InitTypeDef Usart_Init_Struct;
Usart_Init_Struct.USART_BaudRate=9600; //波特率
Usart_Init_Struct.USART_HardwareFlowControl=USART_HardwareFlowControl_None; //无硬件控制流
Usart_Init_Struct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx; //收发模式
Usart_Init_Struct.USART_Parity=USART_Parity_No; //无校验
Usart_Init_Struct.USART_StopBits=USART_StopBits_1; //停止位1位
Usart_Init_Struct.USART_WordLength=USART_WordLength_8b; //数据位8位
USART_Init(USART1,&Usart_Init_Struct);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //开启接收中断
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //NVIC中断配置
NVIC_InitTypeDef nitd;
nitd.NVIC_IRQChannel=USART1_IRQn;
nitd.NVIC_IRQChannelCmd=ENABLE;
nitd.NVIC_IRQChannelPreemptionPriority=2;
nitd.NVIC_IRQChannelSubPriority=2;
NVIC_Init(&nitd);
USART_Cmd(USART1,ENABLE);
}
uint8_t CO2_Data[9]; //存放接收到的数据包
void USART1_IRQHandler(void){
static uint8_t index=0;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){
CO2_Data[index]=USART_ReceiveData(USART1);
if(index==0&&CO2_Data[index]!=0x2C){ //固定数据包的开头
return;
}else{
if(++index>=9) index=0;
}
USART_ClearITPendingBit(USART1,USART_FLAG_RXNE); //清除数据接收标志位
}
}
int main(void){
OLED_Init();
JW01_Init();
OLED_ShowString(1,1,"Hello World");
OLED_ShowString(2,1,"CO2 is ");
while(1){
if(CO2_Data[8]==(uint8_t)(CO2_Data[0]+CO2_Data[1]+CO2_Data[2]+CO2_Data[3]+CO2_Data[4]+CO2_Data[5]+CO2_Data[6]+CO2_Data[7]))
{
OLED_ShowNum(2,8,CO2_Data[6]*256+CO2_Data[7],5);
}else{
OLED_ShowString(2,8,"ERROR");
}
OLED_ShowHexNum(3,1,CO2_Data[0],2);
OLED_ShowHexNum(3,4,CO2_Data[1],2);
OLED_ShowHexNum(3,7,CO2_Data[2],2);
OLED_ShowHexNum(3,10,CO2_Data[3],2);
OLED_ShowHexNum(3,13,CO2_Data[4],2);
OLED_ShowHexNum(4,1,CO2_Data[5],2);
OLED_ShowHexNum(4,4,CO2_Data[6],2);
OLED_ShowHexNum(4,7,CO2_Data[7],2);
OLED_ShowHexNum(4,11,CO2_Data[8],3);
}
}