7,KQM模块的驱动

1,查资料,查模块的通信接口(单片机和模块之间采用什么方式通信)硬件接口,驱动方式(串口驱动用串口发送接收PC10,PC11)

只用了三个脚:VCC GND TX,

RX和F没有用

传输数据,本项目中不要用串口3,串口3是留给wifi的,在硬件上已经固定了, 所以其他的任选一个用串口4传输数据,

KQM.c

#include "kqm.h"
#include "string.h"
//自己能写代码并理解
//voc PPM ,甲醛mg/m3, co2PPM
KQM kqm = {0};
//1.IO初始化
//2.外设初始化
//3.中断初始化
void KQM_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	
	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); 	
	
  //2.外设初始化
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);	
	
	USART_InitTypeDef USART_InitStructure = {0}; 
	USART_InitStructure.USART_BaudRate = 9600; //波特率
	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); 
	
	//3.中断初始化
	NVIC_InitTypeDef NVIC_InitStructure = {0}; 
	NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn; 
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;// 0-3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;//0-3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
	NVIC_Init(&NVIC_InitStructure); 
	//4,中断源
	USART_ITConfig(UART4,USART_IT_RXNE,ENABLE);//开启串口  接收中断
	USART_ITConfig(UART4,USART_IT_IDLE,ENABLE);//串口空闲中断
}

//模块是主动传输数据,不需要写数据发送函数,用中断接收数据,所以也不需要写接收函数

//中断服务函数
void UART4_IRQHandler(void)
{
	if(USART_GetITStatus(UART4,USART_IT_RXNE) == SET)
	{		
		kqm.rxbuff[kqm.rxlen] =  USART_ReceiveData(UART4);
    kqm.rxlen++;
	  USART_ClearITPendingBit(UART4,USART_IT_RXNE);
	}
	
	//空闲中断在UART一段时间没有接收到数据时触发,表示接收完成或空闲状态
	if(USART_GetITStatus(UART4,USART_IT_IDLE) == SET)
	{
	 uint8_t data = USART_ReceiveData(UART4);//接收数据
	 //UART4的接收缓冲区已经处理完毕或达到空闲状态 
		kqm.rxflag=1;
	}	
}

//解析接收的数据

//   1.判断数据接收完成
//   2.判断数据的正确性(校验)
//   3.开始解析数据

#include "led.h"
#include "stdio.h"
void KQMDataAnaly(void)
{
	if(kqm.rxflag == 1)
	{
		//在预热阶段模块传送所有数据的高位以及低位字节为0xff,当接收到此数据时可视为预热数据,不予处理
		//判断是否是预热阶段
		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)
		{
				memset(kqm.rxbuff,0,10);
				 kqm.rxlen=0;
				kqm.rxflag=0;
			   return ;
		}		                   
		  uint8_t checkval =(uint8_t)(kqm.rxbuff[0]+kqm.rxbuff[1]+kqm.rxbuff[2]+kqm.rxbuff[3]+kqm.rxbuff[4]+kqm.rxbuff[5]+kqm.rxbuff[6]);
			if(checkval == kqm.rxbuff[7])	//校验
			{
				
					kqm.voc = (kqm.rxbuff[1]<<8|kqm.rxbuff[2])*0.1;//ppm
					kqm.hcho = (kqm.rxbuff[3]<<8|kqm.rxbuff[4])*0.01;//mg/m3
					kqm.co2 = (kqm.rxbuff[5]<<8|kqm.rxbuff[6])*0.1;//ppm
				//例如:rxbuff[1]:0000 0011
				//			rxbuff[2]: 1011 1001
				//rxbuff[1]<<8得到rxbuff[1]:0000 0011 0000 0000
				//rxbuff[1]<<8|rxbuff[2]得voc:0000 0011	1011 1001 
				
					memset(kqm.rxbuff,0,10);
					kqm.rxlen=0;
					kqm.rxflag=0;
					printf("voc:%.1f,hcho:%.2f,co2:%.1f\r\n",kqm.voc,kqm.hcho,kqm.co2);	

			}
			else//校验失败
			{
				memset(kqm.rxbuff,0,10);
				 kqm.rxlen=0;
				kqm.rxflag=0;
			}
		}
}


kQm.h

#ifndef _KQM_H_
#define _KQM_H_

#include "stm32f10x.h"

typedef struct
{
	uint8_t rxbuff[10];   //rxbuff[1]一个数占8位
	uint8_t rxlen;
	uint8_t  rxflag;
	
	float voc;
	float hcho;
	float co2;
	
}KQM;

extern KQM kqm;

void KQM_Init(void);
void KQMDataAnaly(void);
#endif



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/726715.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

pdf只要前几页,pdf怎么只要前几页

在现代办公和学习环境中&#xff0c;PDF文件已成为我们日常处理信息的重要工具。然而&#xff0c;有时我们并不需要整个PDF文件的内容&#xff0c;而只是其中的几页。那么&#xff0c;如何高效地提取PDF文件中的特定页面呢&#xff1f;本文将为您介绍几种实用的方法。 打开 “ …

Python在Word文档中插入图片,设置文字环绕

在Word文档中插入图片能够提供更直观的信息&#xff0c;使文档变得更加生动和具有吸引力&#xff0c;从而增强阅读体验。插入图片时&#xff0c;我们还可以调整图片大小&#xff0c;以及设置合适的文字环绕方式&#xff0c;确保文字和图片之间的排版不会混乱&#xff0c;达到最…

SVN学习(002 svn冲突解决)

尚硅谷SVN高级教程(svn操作详解) 总时长 4:53:00 共72P 此文章包含第20p-第p29的内容 冲突 产生冲突的操作 &#xff08;第一种 相互不影响的操作&#xff09; 用户1修改第二行 用户2修改第四行 用户1提交 用户2提交&#xff0c;提交的时候会提示版本已过时 这时将用…

树莓派4B学习笔记11:PC端网线SSH连接树莓派_网线连接请求超时问题解决

今日继续学习树莓派4B 4G&#xff1a;&#xff08;Raspberry Pi&#xff0c;简称RPi或RasPi&#xff09; 本人所用树莓派4B 装载的系统与版本如下: 版本可用命令 (lsb_release -a) 查询: Opencv 版本是4.5.1&#xff1a; 今日学习使用网线连接树莓派&#xff0c;网线可以提供更…

STM32学习笔记(六)--引脚重映射详解

STM32F103C8T6引脚定义&#xff1a; 在STM32微控制器中&#xff0c;外设引脚的复用功能&#xff08;Alternate Function&#xff0c;AF&#xff09;有时会出现冲突&#xff0c;例如当USART2_CTS和TIM2_CH1同时需要使用相同的引脚时。此时&#xff0c;可以通过引脚重映射功能&am…

【方法】如何在ZIP文件中添加或删除文件?

ZIP文件是我们在日常工作中常用的压缩格式。有时候&#xff0c;我们需要在已有的ZIP文件中添加或删除文件。下面来看看具体如何操作。 首先&#xff0c;我们要确保安装了ZIP文件管理软件&#xff0c;如WinRAR、7-Zip或Windows自带的文件资源管理器。 添加文件&#xff1a; 使…

redhat-devtoolset备忘

参考&#xff1a; User Guide Red Hat Developer Toolset 12 | Red Hat Customer Portal https://access.redhat.com/documentation/en-us/red_hat_developer_toolset/12/html-single/user_guide/index Red Hat Devtoolset 是 Red Hat 提供的一组开发工具集合&#xff0c;主要用…

1994年美国人口普查数据 分类预测与集成学习

对于分类预测学习任务&#xff0c;从指定的数据源读取数据&#xff0c;对数据进行必要的处理&#xff0c;选取合适的特征&#xff0c;构造分类模型&#xff0c;确定一个人的年收入是否超过50K。 数据来源&#xff1a;1994年美国人口普查数据库。数据存放在data目录中&#xff0…

【K8s】专题五(5):Kubernetes 配置之热更新工具 Reloader

以下内容均来自个人笔记并重新梳理&#xff0c;如有错误欢迎指正&#xff01;如果对您有帮助&#xff0c;烦请点赞、关注、转发&#xff01;欢迎扫码关注个人公众号&#xff01; 目录 一、基本介绍 二、工作原理 三、部署方法 四、使用方法 一、基本介绍 Reloader 是一个用…

基于STM32和人工智能的智能农业监测系统

目录 引言环境准备智能农业监测系统基础代码实现&#xff1a;实现智能农业监测系统 4.1 数据采集模块4.2 数据处理与分析4.3 控制系统4.4 用户界面与数据可视化应用场景&#xff1a;智能农业管理与优化问题解决方案与优化收尾与总结 1. 引言 智能农业监测系统通过结合STM32嵌…

手机照片同步到群辉NAS

手机中最宝贵的数据莫过于“照片”,这些包含美好回忆的数字信息是不能丢失的。NAS的作用就是存储,其中最重要的一项功能就是手机照片的同步。 在群辉NAS丰富的套件中,“Synology Photos”就是解决这个功能,今天我们来看看如何操作。 一、安装套件 打开群晖套件中心→所有…

【拉曼光谱数据处理2024】拉曼数据处理的主要问题和常见方法

一、主要问题分类与解决方法比较 二、常见问题在光谱图上的显示 1、从上到下依次是 理想光谱 理想光谱宇宙尖峰 理想光谱高斯噪声 理想光谱S型背景噪声 理想光谱尖峰高斯噪声S型背景噪声

OS复习笔记ch11-1

外围设备的管理和磁盘调度 外围设备 从CPU的角度来看&#xff0c;外设有几个比较重要的I/O接口&#xff08;interfaces&#xff09; 状态reg&#xff1a;向CPU报告设备的状态&#xff08;忙碌/空闲&#xff09;命令reg&#xff1a;接收CPU命令&#xff0c;存储 CPU 需要执行的…

低温环氧胶在指纹模组封装中的应用有哪些?

低温环氧胶在指纹模组封装中的应用有哪些&#xff1f; 低温环氧胶在指纹模组封装中的应用点主要包括以下几点&#xff1a; 金属环/框与FPC基板固定&#xff1a;低温固化环氧胶被推荐用于固定金属环或框到柔性印刷电路板(FPC)基板上&#xff0c;确保它们之间有稳固的连接。 传感…

RTX5全家桶源码综合模板发布,含FreeRTOS内核版本,将其打造成直接面向实际项目应用的综合框架(2024-06-19)

【说明】 1、RTX5全家桶的优势就是简单易用&#xff0c;初学的话&#xff0c;上手很快&#xff0c;稳定性也是杠杠的&#xff0c;且容易做稳定。 2、同时RTX5也是有汽车级&#xff0c;工业级&#xff0c;医疗和铁路安全认证&#xff0c;只是安全级别比ThreadX要稍微低些。 3…

Easyui Datagrid 解决页面加载重复请求2次后端问题

现象 在页面刚刚打开时&#xff0c;页面加载完毕&#xff0c;显示查询数据&#xff0c;连续请求网络2次&#xff0c; 第一次是只携带了 分页参数&#xff1b; 第二次携带分页和查询参数 问题出现原因 html代码中利用class声明了datagrid&#xff0c;导致easyUI解析class代…

安泰电子:功率放大器的要求是什么

功率放大器是一种用于增强电信号功率的重要设备&#xff0c;在各种应用领域发挥着关键作用。对于功率放大器来说&#xff0c;有一些基本的要求需要满足&#xff0c;以确保其正常工作和提供稳定可靠的功率放大功能。下面将介绍功率放大器的几个主要要求。 高效率&#xff1a;功率…

electron下载失败(electron如何切换镜像源)

打开&#xff1a; 或者&#xff1a; C:\Users\用户名\.npmrc 添加&#xff1a; electron_mirrorhttps://npmmirror.com/mirrors/electron/ 到文件中&#xff0c;保存 方法二&#xff1a; npm config set ELECTRON_MIRROR https://npmmirror.com/mirrors/electron/ ELECTR…

如何低成本试错渠道?Xinstall App来源统计,让您的推广更高效!

随着互联网流量的不断变化&#xff0c;App推广与运营面临着前所未有的挑战。如何在多变的市场环境下迅速搭建起满足用户需求的运营体系&#xff0c;成为众多企业关注的焦点。今天&#xff0c;我们将为您介绍一款强大的工具——Xinstall&#xff0c;它能帮助您精准统计App来源&a…

面试专区|【62道Redis高频题整理(附答案背诵版)】

什么是Redis? Redis是一个高性能的开源内存数据库系统&#xff0c;它使用键值对存储数据&#xff0c;并支持多种数据结构&#xff0c;如字符串、哈希、列表、集合和有序集合。与传统关系型数据库不同&#xff0c;Redis将数据存储在内存中&#xff0c;以实现快速读写操作。同时…