KQM6600空气传感器原理图
相关知识详细介绍
传感器:
数字型传感器:数字信号
关注:接口(UART,单总线,IIC,SPI...)
单总线比如:DHT11(DOUT接口)
模拟型传感器:模拟信号(电压,电流)
电压:ADC,
如果电压太大就需要硬件电路缩小
如果电压太小,就需要硬件电路放大
电流:(4--10mA)串联高精度的采样电阻,把电流转化成电压,然后再通过ADC采集
各种电平:
TTL 232 485 USB
TTL 232 485本质上都是串口电平,但是电平规范不一样
TTL:单片机的串口,ESP8266,KQM6600这些串口接口一般都是TTL电平
电脑收TTL电平的数据
232:232芯片,将TTL电平转化为232电平
485电平:TTL通过485芯片,转换成485电平
USB电平:TTL通过CH340将TTL电平转换成USB电平
获取模块数据手册的途径:
1. 官网
2. 立创商城
3. 淘宝客服要
4. 供应商要
5. 百度
KQM6600简介
看手册关注的点:
(1)供电电压
(2)通信接口(TTL 232 485)
(3)如何获取数据
波特率、输入电压
数据格式
预热阶段:设备刚开机,可能测的不准,稳定一段时间之后,才准确(一般采集气体的传感器都是如此)
休眠控制(有低功耗需求时用到)
KQM6600硬件层
型号与引脚描述
使用电路连接示意图
数据格式
校验和:保证双方数据数据传输的准确:
自己计算的校验和要和对方传递的校验和一致,表示数据没有问题
KQM6600.C
#include "kqm6600.h"
#include "stm32f10x.h" // Device header
#include "stdio.h"
#include "string.h"
KQM Kqm;//定义KQM6600相关的变量
SENSOR Sensor;//传感器参数
/*
串口
PA2 TX 复用推挽输出 确定牧师1看官方例程 2参考手册8.1.11
PA3 RX
*/
void KQM6600_Config(void)
{
//1.开时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
//2.定义结构体
GPIO_InitTypeDef My_TX2={0};
//3.定功能-------KQM6600只需要接收数据不需要发送
My_TX2.GPIO_Mode=GPIO_Mode_AF_PP;
My_TX2.GPIO_Pin=GPIO_Pin_2;
My_TX2.GPIO_Speed=GPIO_Speed_50MHz;
//4.传地址
GPIO_Init(GPIOA,&My_TX2);
My_TX2.GPIO_Mode = GPIO_Mode_IN_FLOATING;//工作模式 (1)参考官方例程 (2)参考手册8.1.11
My_TX2.GPIO_Pin = GPIO_Pin_3; //引脚
GPIO_Init(GPIOA,&My_TX2);
//5.开USART2时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
//6.定义串口结构体
USART_InitTypeDef My_Uart2={0};
//7.定功能
My_Uart2.USART_BaudRate=9600;//波特率
My_Uart2.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
My_Uart2.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;//发送模式--接收功能
My_Uart2.USART_Parity=USART_Parity_No;
My_Uart2.USART_StopBits=USART_StopBits_1;
My_Uart2.USART_WordLength=USART_WordLength_8b;
//8.传地址
USART_Init(USART2,&My_Uart2);
//9.使USART1使能
USART_Cmd(USART2,ENABLE);
// UART1_NVIC_Config();
//10定义结构体
NVIC_InitTypeDef NVIC_InitStruct={0};
//11.给结构体赋值
NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn; //中断通道
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //使能对应的中断
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;//抢占优先级 void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2; //次级优先级 两个优先级的参数要和分组函数NVIC_PriorityGroupConfig保持一致
NVIC_Init(&NVIC_InitStruct);
//12开启需要的中断
//void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState); stm32fo1x_usart.h 371行
USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);//开启接收中断
USART_ITConfig(USART2,USART_IT_IDLE,ENABLE);//开启空闲中断
}
void USART2_IRQHandler(void)
{
uint8_t date=0;
//ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);
//void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);stm32f10x_usart.h 392行
//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>=100)
Kqm.R_Length=0;//避免数组越界
//3.清除中断标志位
USART_ClearITPendingBit(USART2,USART_IT_RXNE);
}
if(USART_GetITStatus(USART2,USART_IT_IDLE)==SET)//空闲情况
{
//参考手册25.6.4位4的介绍 软件序列清除 先读USART_SR寄存器再读USART_DR寄存器
date=USART_ReceiveData(USART2);
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.ch20=((Kqm.R_Buff[3]<<8)+Kqm.R_Buff[4])*0.01;
Sensor.co2=((Kqm.R_Buff[5]<<8)+Kqm.R_Buff[6])*0.01;
printf("voc=%.2f ch20=%.2f co2=%d\r\n",Sensor.voc,Sensor.ch20,Sensor.co2);
}
}
memset(Kqm.R_Buff,0,sizeof(Kqm.R_Buff));//收集完要清理数据,下次从头接收
Kqm.R_Length=0;//这两条数据需要成对使用
}
}
KQM6600.H
#ifndef __KQM6600_H_
#define __KQM6600_H_
#include "stm32f10x.h"
#define KQM_R_Buff_Length 10
void KQM6600_Config(void);
void USART2_IRQHandler(void);
void KQM_Handle(void);
typedef struct
{
uint8_t R_Buff[10];//接收缓冲区
uint8_t R_Length;//接收长度
uint8_t R_Idle;//接收空闲标志位
}KQM;
typedef struct
{
float voc;
float ch20;
uint16_t co2;
}SENSOR;
extern SENSOR Sensor;
#endif
main.c
#include "stm32f10x.h"
#include "BEEP.h"
#include "TIME6.h"
#include "Delay.h"
#include "uart1.h"
#include "stdio.h"
#include "exti.h"
#include "string.h"
#include "kqm6600.h"
int main(void)
{
//中断优先级分组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级分组 分组决定了NVIC结构体和抢占、次级选择的数
KQM6600_Config();
UART1_Config();//因为用的printf函数在此函数内定义
printf("程序进入主循环\n");
BEEP_Config();
while(1)
{
if(Sensor.voc>3)
{
BEEP_ON();//当采集到的空气数据大于相关设定值就报警
}
KQM_Handle();
}
}