目录
今天整理了一下通过STM32和二氧化碳采集二氧化碳数据的代码,和大家进行分享,希望对大家有所帮助。
一、测试环境
单片机:STM32F103C8T6
co2传感器:TVOC-CO2 数字信号 三合一空气质量监测模块
之前因为使用到了CO2传感器,便在淘宝进行了搜索,发现价格还是比较高的,十几到二十几,价格不等,而且很多还不包邮。经过挑选了购买了下面的传感器,经过多次使用,效果还可以,但是商家只提供了说明书文档,没有其他资料。(主动输出型)
二、CO2传感器说明
1. 主要参数:
可以看出一些主要的参数:模块通讯方式UART,输入电压5V,预热时间60s,这些参数很重要,需要记住。
说明:
B1 B2 的内容 2CH E4H 是模块固定地址。
校验和
(B9)
=unit_8(B1+B2+B3+B4+B5+B6+B7+B8)
污染气体浓度值(mg/m3)=(XX 浓度高*256+XX 浓度低)*0.001
数据范例
2C E4 00 0A 00 03 01 68 86
例如读到值是,则得出如下结果:
校验和:86h=2CH+E4H+00H+0AH+00H+03H+01H+68H
TVOC 数值:(B3*256+B4)*0.001=(00h*256+0Ah)*0.001=0.01mg/m³
CH2O 数值:(B5*256+B6)*0.001=(00h*256+03h)*0.001=0.003mg/m³
CO2 数值:B7*256+B8=01h*256+68h=360PPM
2. 数据格式:
串口的数据格式:
可以看出我们使用到了串口数据的B7和B8,通过解析B7和B8就可以得到CO2数据。
实物照片:

需要注意:商家并没有提供线束,所以最好提前购买接线或者使用杜邦线也可以。
三、单片机和传感器接线
传感器 单片机
+5 5V
G GND
B PA3
四、程序代码
程序编写使用的标准库代码,如果使用HAL库,调整串口代码即可,我们使用UART2连接传感器,UART1进行打印输出,连接串口调试助手。
CO2采集主要代码:
xtern unsigned char rdata[20];
u8 count=0;
extern u8 getflag;
u8 USART2_RX_BUF[USART2_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
u16 USART2_RX_STA=0; //接收状态标记
//u16 CO2=0;
void Usart2_Init(unsigned int baud)
{
GPIO_InitTypeDef gpio_initstruct;
USART_InitTypeDef usart_initstruct;
NVIC_InitTypeDef nvic_initstruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
//PA2 TXD
gpio_initstruct.GPIO_Mode = GPIO_Mode_AF_PP;
gpio_initstruct.GPIO_Pin = GPIO_Pin_2;
gpio_initstruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &gpio_initstruct);
//PA3 RXD
gpio_initstruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
gpio_initstruct.GPIO_Pin = GPIO_Pin_3;
gpio_initstruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &gpio_initstruct);
usart_initstruct.USART_BaudRate = baud;
usart_initstruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件流控
usart_initstruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //接收和发送
usart_initstruct.USART_Parity = USART_Parity_No; //无校验
usart_initstruct.USART_StopBits = USART_StopBits_1; //1位停止位
usart_initstruct.USART_WordLength = USART_WordLength_8b; //8位数据位
USART_Init(USART2, &usart_initstruct);
USART_Cmd(USART2, ENABLE); //使能串口
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); //使能接收中断
nvic_initstruct.NVIC_IRQChannel = USART2_IRQn;
nvic_initstruct.NVIC_IRQChannelCmd = ENABLE;
nvic_initstruct.NVIC_IRQChannelPreemptionPriority = 0;
nvic_initstruct.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&nvic_initstruct);
}
void USART2_IRQHandler(void) //串口1中断服务程序
{
u8 Res;
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
rdata[count] = USART_ReceiveData(USART2);
if(rdata[count]==0x2C)
{
count=0;
rdata[count]=USART_ReceiveData(USART2);
count++;
getflag=1;
}
else count++;
if((USART2_RX_STA&0x8000)==0)//接收未完成
{
if(USART2_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)USART2_RX_STA=0;//接收错误,重新开始
else USART2_RX_STA|=0x8000; //接收完成了
}
else //还没收到0X0D
{
if(Res==0x0d)USART2_RX_STA|=0x4000;
else
{
USART2_RX_BUF[USART2_RX_STA&0X3FFF]=Res;
USART2_RX_STA++;
if(USART2_RX_STA>(USART2_REC_LEN-1))USART2_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
}
主函数代码:
if(getflag==1) //读取二氧化碳
{
getflag=0;
co2=(u16)(rdata[6]*256+rdata[7]); //数据转换成mg/m3 第四位和第五位保存检测返回值
UsartPrintf(USART_DEBUG,"co2: %d\r\n", co2);
UsartPrintf(USART_DEBUG,"co2: %02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x\r\n", rdata[0],rdata[1],rdata[2],rdata[3],rdata[4],rdata[5],rdata[6],rdata[7]);
}
五、最终效果
由于时间仓促,还未打包代码,等整理完,可供大家下载使用。