PM2.5 激光粉尘传感器之DSL-08(DS-08)

一款产品里用到粉尘检测,最后在淘宝上找一到了一款,型号是DSL-08。

传感器的产品资料放在百度网盘里

链接:https://pan.baidu.com/s/1oNCwO7n9oEdzju91cF99xg?pwd=1234 
提取码:1234

PM2.5 激光粉尘传感器之DSL-08(DS-08)_第1张图片

芯片:STM32F103C8T6

粉尘传感器:DSL-08

    通电后,粉尘传感器是一直发送32个字节的数据过来,所以我们只要解析出这个数据,对应PDF文档资料换算就可以了。在使用过程中发现单片机对DSL-08传感器发送各种命令都无效。

 过程如下:

一、设置串口3为接收端,利用USART3的DMA空闲不定长收发。

PM2.5 激光粉尘传感器之DSL-08(DS-08)_第2张图片

PM2.5 激光粉尘传感器之DSL-08(DS-08)_第3张图片

PM2.5 激光粉尘传感器之DSL-08(DS-08)_第4张图片PM2.5 激光粉尘传感器之DSL-08(DS-08)_第5张图片

新建两个文档:PMS.C  PMS.H

PMS.C文档

/*
PM2.5驱动文件
型号:DSL-08 
日期:2023.9.18
*/

#include "string.h"
#include "stdio.h"
#include "usart.h"

#include "PMS/PMS.H"

用户自定义变量//
struct PM_Data PM;											//定义一个PM的结构体变量

uint8_t TX3CMD[9]={0XAA,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XBB};			//发送命令包
uint8_t RX3Buffer[BufferSize]={0};			//串口接收缓存
uint8_t RX3Len = 0;											//串口接收数据长度

/*****************************************************************
* 名    称: SendCMD()
* 功    能: 串口3发送1个字节
* 入口参数: t  发送的字节
* 出口参数: 无
*****************************************************************/
void  SendCMD(uint8_t t)
{
	HAL_UART_Transmit(&huart3, &t, 1, 0xffff);
}

/*****************************************************************
* 名    称: WriteCMD
* 功    能: 发送控制命令
* 入口参数: 根据资料,发送相应命令
* 出口参数: 无
* 说明:将命令写入后,生成校验和,DMA发送
* PM2.5模块默认是一直发送数据的,可以不必操作命令也能使用。
	根据资料测试命令无效,不受控制。
*****************************************************************/
void WriteCMD(uint8_t Command)
{
	uint16_t CRCTemp = 0;
	
	CRCTemp=TX3CMD[0]+Command+(uint8_t)TX3CMD[8];	//生成校验和
	
	TX3CMD[6]= CRCTemp>>8;
	TX3CMD[7]= CRCTemp;						//第6 7位为校验和位,将数据拆分

	HAL_UART_Transmit_DMA(&huart3, TX3CMD,sizeof(TX3CMD));	//DMA发送
	
//验证
//	for(uint8_t i=0;i<9;i++)
//	{
//		printf("%d :%0X  ",i,TX3CMD[i]); 
//	}
//	printf("\r\n");
}
/*****************************************************************
* 名    称: 
* 功    能: 将数据显示出来
* 入口参数: 
* 出口参数: 无
*****************************************************************/
void PrintfData(void)
{
	if(RX3Len==32)
	{
		printf("长度:%d\r\n",RX3Len);
		for(uint8_t i=0;i31)
	{
		uint16_t H_valueTemp;
		H_valueTemp=0;
		PM.PM1 = ((H_valueTemp|RX3Buffer[4]) << 8) | RX3Buffer[5];		//PM1.0浓度
		H_valueTemp=0;
		PM.PM2 = ((H_valueTemp|RX3Buffer[6]) << 8) | RX3Buffer[7];		//PM2.5浓度
		H_valueTemp=0;
		PM.PM10 = ((H_valueTemp|RX3Buffer[8]) << 8) | RX3Buffer[9];		//PM10浓度
		
		//0.1升空气中的颗粒物数量
		H_valueTemp=0;
		PM.Dust_03um = ((H_valueTemp|RX3Buffer[16]) << 8) | RX3Buffer[17];		//0.3um
		H_valueTemp=0;
		PM.Dust_05um = ((H_valueTemp|RX3Buffer[18]) << 8) | RX3Buffer[19];		//0.5um
		H_valueTemp=0;
		PM.Dust_1um = ((H_valueTemp|RX3Buffer[20]) << 8) | RX3Buffer[21];			//1um
		H_valueTemp=0;
		PM.Dust_2um = ((H_valueTemp|RX3Buffer[22]) << 8) | RX3Buffer[23];			//2.5um
		H_valueTemp=0;
		PM.Dust_5um = ((H_valueTemp|RX3Buffer[24]) << 8) | RX3Buffer[25];			//5um
		H_valueTemp=0;
		PM.Dust_10um = ((H_valueTemp|RX3Buffer[26]) << 8) | RX3Buffer[27];		//10um

//		printf("\r\nPM浓度:\r\n");
//		printf("PM1.0=%dug/m3  ",PM.PM1);
//		printf("PM2.5=%dug/m3  ",PM.PM2);
//		printf("PM10=%dug/m3 ",PM.PM10);
//		printf("\r\n0.1升空气中的颗粒物:\r\n");
//		printf("0.3um=%d个 0.5um=%d个 1.0um=%d个 2.5um=%d个 5um=%d个 10um=%d个\r\n",PM.Dust_03um,PM.Dust_05um,PM.Dust_1um,PM.Dust_2um,PM.Dust_5um,PM.Dust_10um);

	}
}


PMS.H

/*! 
*  \file hmi_driver.h
*  \brief DS-08 PM2.5激光传感器
*  \version 1.0
*  \date 2023.9.18
*  \copyright 攀藤科技,小米专用
*/

#ifndef _PMS_
#define _PMS_


#include "main.h"


#define BufferSize  64  //缓存宽度最小64


//#define CMD_HEAD 0XAA      //帧头
//#define CMD_TAIL 0XBB      //帧尾

//#define SEND_DATA(P) SendCMD(P)          //发送一个字节
//#define BEGIN_CMD() TX_8(0XAA)            //帧头
//#define END_CMD() TX_8(0XBB)       				//帧尾

//PM2.5相关函数
//数据结构体
struct PM_Data{						
			uint16_t PM1;							//标准下PM1.0浓度
			uint16_t PM2;						//标准下PM2.5浓度
			uint16_t PM10;					//标准下PM10浓度
			uint16_t Dust_03um;			//0.1升空气中0.3um颗粒个数
			uint16_t Dust_05um;			//0.1升空气中0.5um颗粒个数
			uint16_t Dust_1um;			//0.1升空气中1um颗粒个数
			uint16_t Dust_2um;			//0.1升空气中2.5um颗粒个数
			uint16_t Dust_5um;			//0.1升空气中5um颗粒个数
			uint16_t Dust_10um;			//0.1升空气中10um颗粒个数
			uint16_t CheckCRC;
};

extern struct PM_Data PM;									//定义一个PM的结构体变量
extern uint8_t RX3Buffer[BufferSize];			//串口接收缓存
extern uint8_t RX3Len;											//串口接收数据长度

/函数/
void  SendCMD(uint8_t t);
void InitDustSensor(void);
//void ReadDustSensor(void);
void AutoRun(void);
void WriteCMD(uint8_t Command);
void PrintfData(void);
void GetPMData(void);

#endif

 在main.c中加入头文件
//激光粉尘传感器
#include "PMS/PMS.H"

初始化中加入,开启不定长接收

///PM2.5传感器/
//外设:USART3//
	HAL_UARTEx_ReceiveToIdle_DMA(&huart3,RX3Buffer,BufferSize);  //开启空闲中断并调用DMA,数据存入RXBuffer 
//	HAL_UART_Receive_DMA(&huart2,RXBuffer,BUFFER_SIZE);//开启一次接收
	__HAL_UART_ENABLE_IT(&huart3, UART_IT_ERR);//使能串口错误中断

加入中断回调函数

/**
  * 函数功能: 串口空闲中断DMA回调函数
  * 输入参数: huart为串口号,Size为空闲接收数据位数  
  * 返 回 值: 无
  * 说    明:STM32CubeMX中 RX的DMA Mode设置成
  */
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{

	 if(huart->Instance == USART3)
	 {
	//			printf("进入空闲中断,串口3\r\n");
			HAL_UART_AbortReceive(&huart3); //该函数有两个功能,先关闭DMA接收,但DMA能发送,置位RX Ready状态,忽略了错误标志和IT标志处理,比HAL_UART_DMAStop好
			RX3Len=Size;
			HAL_UARTEx_ReceiveToIdle_DMA(&huart3, RX3Buffer, BufferSize);//开启DMA空闲接收,将接收的数据存入RX3Buffer,数据长度 BufferSize
	 }
	
}

while循环中只要调用GetPMData()函数就可以了,记得加个延时,不然可能会卡死

PM2.5 激光粉尘传感器之DSL-08(DS-08)_第6张图片

你可能感兴趣的:(STM32学习,单片机,stm32,嵌入式硬件)