【野火秉火STM32 F429开发板试用体验】+驱动PM2.5的传感器

  • 烟花绽放
  • LV3工程师
  • |      2017-12-03 22:06:40
  • 浏览量 1228
  • 回复:2
PM2.5的传感器采用的是GP2Y1010AU0F光学灰尘传感器(GP2Y1010AU0F)在检测非常细的颗粒,如香烟烟雾,是特别有效的,并且是常用的空气净化器系统。该装置中,一个红外发光二极管和光电晶体管,对角布置成允许其检测到在空气中的灰尘反射光。该传感器具有极低的电流消耗(最大20mA,11毫安典型的),可以搭载高达7VDC的传感器。输出的是一个模拟电压正比于所测得的粉尘浓度,敏感性为0.5V/0.1mg/m3。 规格电源电压:5-7V工作温度:-10-65摄氏度消耗电流:20mA最大最小粒子检出值:0.8微米灵敏度:0.5V/(0.1mg/m3)清洁空气中电压:0.9V 典型值工作温度:-10~65℃存储温度:-20~80℃使用寿命:5年尺寸大小:46mm×30mm×17.6mm重量大小:15g 检测原理其原理如下图,传感器中心有个洞可以让空气自由流过,定向发射LED光,通过检测经过空气中灰尘折射过后的光线来判断灰尘的含量。 程序上的话,我们先来看看主程序 /* Includes ------------------------------------------------------------------*/#include "main.h" uint16_t Handshake= {0x1B,0xAA,0xFF,0xFF,0xEF,0xEF};//液晶握手指令 uint16_t ADC_ConvertedValue, num; #define SAMP_COUNT 20 /* 样本个数,表示200ms内的采样数据求平均值 */// 局部变量,用于保存转换计算后的电压值 float ADC_Vol; void GP2Y_GPIOInit(void);uint32_t GP2Y_GetADCValue(void); typedef struct { uint8_t temperature;//温度 uint8_t humidity;//湿度 uint32_t density;}Environment; Environment TemperHumi; extern uint8_t Answer; void ReadData(void); void main(void){ uint8_t i; SystemInit(); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); Bsp_UsartInit(); SysTick_Init(); DHT11_Init(); Rheostat_Init(); GP2Y_GPIOInit(); for(i=0;i<6;i++) //握手 Usart_SendByte(USART2,Handshake); while(Answer != 0x33); while (1) { ReadData(); delay_us(50000); }} void ReadData(void){ DHT11_Read_Data(&TemperHumi.temperature,&TemperHumi.humidity); GP2Y_GetADCValue();// ADC_Vol = (ADC_ConvertedValue /4096) * 3300 ; TemperHumi.density = 0.17 * ADC_ConvertedValue - 1; kongjian(Temperature_DisPlay,(TemperHumi.temperature)); kongjian(Rumidity_DisPlay,(TemperHumi.humidity)); kongjian(Density_DisPlay,(TemperHumi.density));} void GP2Y_GPIOInit(void){ GPIO_InitTypeDef GPIO_InitStructure; /* PA5 output */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //设置为输出模式 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置端口输出速度为50MHZ GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //设置为推挽输出 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //无上拉下拉 GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_ResetBits(GPIOA, GPIO_Pin_5); // } uint32_t GP2Y_GetADCValue(void){ static uint16_t buf; static uint8_t write; uint32_t sum; uint8_t i; GPIO_ResetBits(GPIOA, GPIO_Pin_5); delay_us(28); buf = ADC_GetConversionValue(ADC1); if (++write >= SAMP_COUNT) { write = 0; } sum = 0; for (i = 0; i < SAMP_COUNT; i++) { sum += buf; } ADC_ConvertedValue = sum / SAMP_COUNT; /* ADC采样值由若干次采样值平均 */ ADC_SoftwareStartConv(ADC1); //使能指定的ADC1的软件转换启动功能 delay_us(4); GPIO_SetBits(GPIOA, GPIO_Pin_5); //default low, ILED closed return ADC_ConvertedValue;} /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ AD采集使用单次采集,滤波使用了20次求均值,目前手上没有其他的检测PM2.5的设备,所以无法校准, 之前在写程序的时候,卡在了AD值转换成实际值上面,网上的资料大部分都是使用Arduino驱动的,计算方法相差不大, 但是在调试的时候计算出来的值都在两百以上(ADC_Vol = (ADC_ConvertedValue /4096) * 3300 ;), 后面再网上找到了这个公式TemperHumi.density = 0.17 * ADC_ConvertedValue - 1(因没有校准设备);所以目前无法验证对错。 ADC配置函数:void Rheostat_ADC_GPIO_Config(void){ GPIO_InitTypeDef GPIO_InitStructure; // 使能 GPIO 时钟 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); // 配置 IO GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; //不上拉不下拉 GPIO_Init(GPIOC, &GPIO_InitStructure); } void Rheostat_ADC_Mode_Config(void){ ADC_InitTypeDef ADC_InitStructure; ADC_CommonInitTypeDef ADC_CommonInitStructure; // 开启ADC时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 , ENABLE); // -------------------ADC Common 结构体 参数 初始化------------------------ // 独立ADC模式 ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; // 时钟为fpclk x分频 ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; // 禁止DMA直接访问模式 ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; // 采样时间间隔 ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles; ADC_CommonInit(&ADC_CommonInitStructure); // -------------------ADC Init 结构体 参数 初始化-------------------------- ADC_StructInit(&ADC_InitStructure); // ADC 分辨率 ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; // 禁止扫描模式,多通道采集才需要 ADC_InitStructure.ADC_ScanConvMode = DISABLE; // 连续转换 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //禁止外部边沿触发 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //外部触发通道,本例子使用软件触发,此值随便赋值即可// ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; //数据右对齐 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //转换通道 1个 ADC_InitStructure.ADC_NbrOfConversion = 1; ADC_Init(ADC1, &ADC_InitStructure); //--------------------------------------------------------------------------- // 配置 ADC 通道转换顺序为1,第一个转换,采样时间为3个时钟周期 ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 1, ADC_SampleTime_56Cycles); // ADC 转换结束产生中断,在中断服务程序中读取转换值// ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE); // 使能ADC ADC_Cmd(ADC1, ENABLE); //开始adc转换,软件触发 ADC_SoftwareStartConv(ADC1); } 传感器如下:上图 显示的时候感觉只显示三行数据挺丑的,所以把论坛名称和板子型号加上了,还挺好 程序打包后提示无法保存,后续再上传完整程序吧。。。。
  • 0
  • 收藏
  • 举报
  • 分享
我来回复

登录后可评论,请 登录注册

所有回答 数量:1
15829201179 2017-12-31
源码源码,求源码
0   回复
举报
发布
烟花绽放 回复 2018-01-09
PM2.5传感器的的程序在帖子里了
0   回复
举报
x
收藏成功!点击 我的收藏 查看收藏的全部帖子