KQM6600空气检测模块的使用以及实现

本文介绍了KQM6600TAUs空气质量检测模块,其使用VOC传感器并通过UART(9600bps)通信,详细说明了数据输出格式、电路连接、以及如何通过代码配置和处理接收到的数据,包括中断服务函数的编写和数据验证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

简介

KQM6600TAUs型空气质量检测模 块,使用MEMS VOC传感器件作为检测空气中有机化合物气体(VOC)的模块。UART通信数据输出,根据VOC数据计算和等效甲醛,CO2输出。其具有体积小,功耗低,灵敏度高,响应速度快等居多优点,广泛应用在空气质量检测及控制领域。

型号与引脚描述

KQM6600TAUs 空气质量模块实现了三种与用户主控 MCU 的数据传输方

式,为 UART 通信输出方式,UART(波特率 9600bps)

分别对应各个型号引脚描述:

使用电路连接示意图

各型号对应应用连接示意图分别如下图所示:(F 引脚休眠和校准功能如果不用,可以空置)

数据输出格式 

起始位:1

数据位:8 位数据

/偶校验:无

停止位:1

波特率:9600bps

BYTE1 地址码:0x5F

数据 1 高位\数据 1 低位:VOC 输出数据(16 进制),单位 0.1PPM

数据 2 高位\数据 2 低位:甲醛输出数据(16 进制),单位 0.01mg/m3

数据 3 高位\数据 3 低位:CO2 输出数据(16 进制),单位 1PPM

校验值: 前三字节的校验和的低位字节 byte1+byte2+byte3+....+byte7

代码

main.c

KQM6600.C 

#include "kqm6600.h"
#include "stdio.h"
#include "string.h"

KQM Kqm;  //定义KQM6600相关的变量
SENSOR sensor;  //传感器参数
/*
串口2
PA2  TX   复用推挽输出  
PA3  RX
*/
void KQM6600_Config(void)
{
	//1.开GPIOA时钟 
//void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);  stm3210x_rcc.h 693行
//void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); 

	//2.定义结构体
//void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);	  stm32f10x_gpio.h 351行
	GPIO_InitTypeDef GPIO_InitStruct={0};
	
	//3.给结构体赋值  TX  -- 串口2和KQM6600通信只需要接收数据,不需要发送   TX管脚可以不配置
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//工作模式  
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;  //引脚
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;  //工作速度
	
	//4.调用XXX_init函数,将参数写入到寄存器中
	GPIO_Init(GPIOA,&GPIO_InitStruct);	
	
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;//工作模式  
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;  //引脚	
	
	GPIO_Init(GPIOA,&GPIO_InitStruct);		
	
	//5.开串口2的时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
	
	//6.定义结构体
//void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);	stm32f10x_usart.h 366行
	USART_InitTypeDef USART_InitStruct={0};
	
	//7.给结构体赋值  关于波特率 数据位 校验方式 停止位 要和KQM6600保持一致
	USART_InitStruct.USART_BaudRate = 9600;//波特率  9600 115200 
	USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件流控制
	USART_InitStruct.USART_Mode = USART_Mode_Tx|USART_Mode_Rx; //发送接收使能
	USART_InitStruct.USART_Parity =  USART_Parity_No; //无校验
	USART_InitStruct.USART_StopBits = USART_StopBits_1;  //1个停止位
	USART_InitStruct.USART_WordLength = USART_WordLength_8b;  //8个数据位
	
	//8.调用xxx_init函数将参数写入到寄存器中
	USART_Init(USART2,&USART_InitStruct);
	
	//9.使能串口功能  xxx_cmd
//	void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);  stm32f10x_usart.h 370行
	USART_Cmd(USART2,ENABLE);
	
	//根据需求配置是否配置中断	
	//10.定义结构体
	NVIC_InitTypeDef NVIC_InitStruct={0};

	//11.给结构体赋值
	NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn;  //中断通道
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;   //使能对应的中断
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级    void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2; //次级优先级   两个优先级的参数要和分组函数NVIC_PriorityGroupConfig保持一致

	//12.调用XXX_Init函数将参数写入到寄存器中
	NVIC_Init(&NVIC_InitStruct);	
	
	//13.开启对应的中断
//void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);	  stm32f10x_usart.h 371行
	USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);  //开启接收中断
	USART_ITConfig(USART2,USART_IT_IDLE,ENABLE);  //开启空闲中断		
}

/*
中断服务函数的编写要求:
1.无参数 无返回值
2.中断服务函数的名字,必须从启动文件startup_stm32f10x_hd.s中复制
3.中断服务函数中,不要有大量延时操作,及时退出 
4.置标志位 
5.中断服务函数不需要声明
注意:
1.如果仿真,中断服务程序不能放断点,函数名字有错误
2.停止仿真,代码卡在启动文件                B       .位置,没有编写中断服务程序,或者名字有误
*/
/*
接收中断:每接收1个字节,触发1次接收中断
空闲中断:如果检测到总线空闲了(连续10位总线都是高)
对方发过来的数据  0x01  0x02  0x03  0x04
总共触发5次中断:触发4次接收中断,触发1次空闲中断

接收中断中:放断点,会导致后面的数据无法接收
一般在空闲中断中放断点
*/
void USART2_IRQHandler(void)
{
	uint8_t date=0;
//ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);    stm32f10x_usart.h 392行
//void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);	
	//1.判断中断是否发生
	if(USART_GetITStatus(USART2,USART_IT_RXNE)==SET)
	{ //触发接收中断
		//2.编写中断服务函数执行内容
		date=USART_ReceiveData(USART2);
		Kqm.R_Buff[Kqm.R_Length++]=date;
		if(Kqm.R_Length >= KQM_R_Buff_Length)  //避免数组越界
			Kqm.R_Length=0;
		//3.清除中断标志位
		USART_ClearITPendingBit(USART2,USART_IT_RXNE);	
	}
	if(USART_GetITStatus(USART2,USART_IT_IDLE)==SET)
	{
//uint16_t USART_ReceiveData(USART_TypeDef* USARTx); 		stm32f10x_usart.h 379行
		date=USART_ReceiveData(USART2);  
		//参考手册 25.6.4的位4的介绍 软件序列清除  先读USART_SR(USART_GetITStatus),然后读USART_DR(USART_ReceiveData)
		Kqm.R_Idle=1;	//接收完成标志位置1	
	}
}


//数据接收完成,调用处理函数
void KQM_Handle(void)
{
	uint8_t temp_date = 0; //存放校验和  局部变量要给初值
	if(Kqm.R_Idle == 1)
	{
		Kqm.R_Idle = 0;
		if(Kqm.R_Buff[0] == 0x5F)
		{//帧头 -- 地址码正确
			temp_date = Kqm.R_Buff[0] + Kqm.R_Buff[1] + Kqm.R_Buff[2] + Kqm.R_Buff[3] + Kqm.R_Buff[4] + Kqm.R_Buff[5] + Kqm.R_Buff[6];
			if(temp_date == Kqm.R_Buff[7])
			{//校验通过
				sensor.voc = ((Kqm.R_Buff[1]<<8) + Kqm.R_Buff[2]) * 0.1;
				sensor.ch2o = ((Kqm.R_Buff[3]<<8) + Kqm.R_Buff[4]) * 0.1;
				sensor.co2 = ((Kqm.R_Buff[5]<<8) + Kqm.R_Buff[6]);
				printf("voc = %.1f,ch2o = %.2f,co2 = %d\r\n",sensor.voc,sensor.ch2o,sensor.co2);
			}
		}
		memset(Kqm.R_Buff,0,sizeof(Kqm.R_Buff));
		Kqm.R_Length = 0;
	}
}

















KQM6600.h

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值