KQM6600空气质量传感器

KQM6600空气质量传感器

目录

KQM6600空气质量传感器

查找资料

编程

1、初始化(时钟、IO、外设、中断、其他)

2、中断服务函数

3、数据解析函数

kqm6600.h

硬件连接

安装ST-LINK驱动

实验结果


查找资料

  • 找相应的资料,看资料

  • 1、看引脚(看接线图)

-- 可以看出只有kqm向单片机发送数据,所以单片机编写代码只用写接收函数

  • 2、然后看数据的输出格式

-- 可以看出数据输出的数据位数是8位,但是传输数据是10位,因为还有起始位和停止位

-- 已知数据1是voc,数据2是pcho(甲醛),数据3是co2,都是16进制数的形式,所以需要转换成10进制数,并且单位都不同,还要进行换算。

编程

1、初始化(时钟、IO、外设、中断、其他)

  • 1、配置时钟(A端口和UART4(外设自身也有时钟))

-- 这里注意串口4的名字有点特殊,是UART4,没有S。

cs 复制代码
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);			//看数据手册在哪条线上 - APB1				//注意串口名字

-- 注意看数据手册,该外设在那条线上,这里明显是在APB1线上,所以用RCC_APB1PeriphClockCmd,至于为什么用串口4,是因为在这个单片机上其他的串口被别的外设使用了,所以只能用串口4,

而根据原理图可以看出串口4连接在单片机上的引脚是PC10和PC11,所以需要配置这两个引脚

  • 2、配置IO口

-- PC10是TX,PC11是RX,所以配置PC10为复用推挽输出,PC11为浮空输入

cs 复制代码
//IO PC10,PC11
	GPIO_InitTypeDef GPIO_InitStructure = {0};						//定义结构体变量,并且将结构体变量赋初值
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 						//引脚
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;			//速度
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;				//复用推挽
	GPIO_Init(GPIOC, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; 							//引脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;		//浮空输入
	GPIO_Init(GPIOC, &GPIO_InitStructure);
  • 3、配置外设

-- 将外设名字改为串口4即可

cs 复制代码
    USART_InitTypeDef USART_InitStructure = {0};
	USART_InitStructure.USART_BaudRate = 9600;   					 			//波特率  常用的是4800 9600  115200
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;	//数据位长度
	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_Tx | USART_Mode_Rx;//模式
	USART_Init(UART4, &USART_InitStructure);
	
	USART_Cmd(UART4,ENABLE);//开启串口    //使能或者失能 UART4 外设(一般外设都要写这个)
  • 4、配置中断

-- 配置中断,不仅要开启中断通道,还要使能中断源

cs 复制代码
	//使能中断源			//串口有10个,用哪一个就要开哪一个中断源
	USART_ITConfig(UART4,USART_IT_RXNE,ENABLE);
	
	//中断
	NVIC_InitTypeDef NVIC_InitStructure = {0}; 
	NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn; //中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能(使能哪个中断通道,就要写哪个(必须写)中断服务函数)
	NVIC_Init(&NVIC_InitStructure);

2、中断服务函数

  • 因为这里单片机只用接收数据,所以只写接收函数即可,而接收数据用中断来接收
cs 复制代码
//中断服务函数
void UART4_IRQHandler()
{	
	//判断接收中断是否发生
	if(USART_GetITStatus(UART4, USART_IT_RXNE) == SET)
	{
		//处理中断:保存数据
		kqm.rxbuff[kqm.rxlen++] = USART_ReceiveData(UART4);
		if(kqm.rxlen == 8)
		kqm.rxflag = 1;
		kqm.rxlen %= 10;//对10求余,他就一直会小于10
		//清理终端
		USART_ClearITPendingBit(UART4,USART_IT_RXNE);
	}
}

3、数据解析函数

cs 复制代码
//数据解析函数

void data_parsing(void)//解析
{
	if(kqm.rxflag  == 1 )
	{
		//错误判断
		if(kqm.rxlen != 8 )//异常情况
		{
			goto AAA;
		}
		
		
		//预热
		if(kqm.rxbuff[1] == 0xff && kqm.rxbuff[2] == 0xff && \
			kqm.rxbuff[3] == 0xff && kqm.rxbuff[4] == 0xff && \
		  kqm.rxbuff[5] == 0xff && kqm.rxbuff[6] == 0xff)//S数据的高位和低位
			{
				printf("当前模式处在预热模式\r\n");
				goto AAA;
			}
		
		uint8_t check = kqm.rxbuff[0]+kqm.rxbuff[1]+kqm.rxbuff[2]+kqm.rxbuff[3]+kqm.rxbuff[4]+kqm.rxbuff[5]+kqm.rxbuff[6];
		if(check !=kqm.rxbuff[7])
		{
			printf("校验错误\r\n");
			goto AAA;
		}
		
		//解析数据
		kqm.voc = (kqm.rxbuff[1]<<8|kqm.rxbuff[2])*0.1;//两个8位数合成1个16位
		kqm.hcho = (kqm.rxbuff[3]<<8|kqm.rxbuff[4])*0.01;
		kqm.co2 = (kqm.rxbuff[5]<<8|kqm.rxbuff[6])*1;
		
		printf("voc:%.2fPPM\r\n",kqm.voc);
		printf("hcho:%.2fmg/m3\r\n",kqm.hcho);
		printf("co2:%.2fPPM\r\n",kqm.co2);
		
AAA:
			memset(kqm.rxbuff,0,10);
			kqm.rxlen = 0;
			kqm.rxflag = 0;
		
	}
	
}

kqm6600.h

-- 这里选择定义一个结构体来存取数据

cs 复制代码
#ifndef _KQM6600_H_
#define _KQM6600_H_

#include "stdio.h"
#include "STM32f10x.h"

void kqm6600_init(void);

typedef struct {
	uint8_t rxbuff[10];//接收缓冲区
	uint8_t rxlen;//接收计数值
	uint8_t rxflag;
	
	float voc;//空气质量
	float co2;//二氧化碳
	float hcho;//甲醛
}KQM;



void data_parsing(void);
#endif

硬件连接

  • G是GND
  • V是VCC
  • A是PC11

安装ST-LINK驱动

-- 在文件夹中找到安装包

-- 安装完毕,会有这个图标

-- 点击魔法棒

-- 连接下载器

-- 程序编译没错误后,点击下载

实验结果

  • mian.c
cs 复制代码
int main()
{
	relay_on();
	Delay_nms(100);
	relay_off();
    relay_init();

	kqm6600_init();
	
	SysTick_Config(72000);
	while(1)
	{
		
		if(kqmtime >= 500)
		{
			kqmtime =0 ;
			data_parsing();
			
			if(kqm.voc >= 7)
			{
				relay_on();
				Delay_nms(100);
				relay_off();
			}
			//printf("1\r\n");
		}	
    }
}

补充:

  • 注:数据解析函数可以参考这个框架

//数据解析函数 //1、判断数据是否接收完毕 //2、错误判断(预热、校验。。。) //3、解析数据 //4、清除接收缓冲区

  • 注:每次收到一个字节就会触发一次中断,而不是收到8个数据才会触发
相关推荐
OH五星上将14 分钟前
OpenHarmony(鸿蒙南向)——平台驱动开发【Regulator】
驱动开发·嵌入式硬件·硬件工程·harmonyos·openharmony·鸿蒙开发·鸿蒙嵌入式
智控工作室2 小时前
STM32-HAL库驱动DHT11温湿度传感器 --2024.9.28
stm32·单片机·嵌入式硬件
Projectsauron2 小时前
STM32 时钟树(基于 STM32F407)
stm32·单片机·时钟树
MikelSun3 小时前
梳理一下C语言中的格式说明符
c语言·开发语言·c++·单片机·物联网·算法
0南城逆流04 小时前
【STM32】RTT-Studio中HAL库开发教程七:IIC通信--EEPROM存储器FM24C04
stm32·单片机·嵌入式硬件
森旺电子5 小时前
STM32 Modbus主从站实例程序-FreeRTOS
stm32·单片机·嵌入式硬件·modbus
zcxinmiao6 小时前
光伏发电生活废水处理设备产地货源
单片机·其他
代码敲不对.7 小时前
【STM32】江科大STM32笔记汇总(已完结)
笔记·stm32·单片机·嵌入式硬件
乐思智能科技有限公司7 小时前
C语言编写一个五子棋游戏-代码实例讲解与分析
c语言·开发语言·嵌入式硬件·算法·游戏