一、前期准备
单片机:STM32F103ZET6
开发环境:MDK5.14
库函数:标准库V3.5
GP2Y10模块:淘宝有售
二、实验效果
三、驱动原理
主要就是采集AD电压,对应转换公式做相关的转换。
需要完整工程或者有问题的请加QQ:1002521871,验证:呵呵。
四、驱动代码
gp2y10.h
#ifndef __GP2Y10_H__
#define __GP2Y10_H__
#include "stm32f10x.h"
#include "gpio.h"
#include "delay.h"
#include "uart.h"
#define GP2Y10_CONTROL PAout(0)
#define GP2Y10_PIN GPIO_Pin_0
#define GP2Y10_CLKLINE RCC_APB2Periph_GPIOA
#define GP2Y10_PORT GPIOA
extern void GP2Y10Configuraiton(void);
extern void GetGP2Y10Value(uint16_t *AQI, uint16_t *PM25);
#endif
gp2y10.c
#include "gp2y10.h"
void GP2Y10Configuraiton(void)
{
GPIO_InitTypeDef GPIO;
//Enable APB2 Bus
RCC_APB2PeriphClockCmd(GP2Y10_CLKLINE, ENABLE);
//Register IO
GPIO.GPIO_Pin = GP2Y10_PIN;
GPIO.GPIO_Speed = GPIO_Speed_50MHz;
GPIO.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GP2Y10_PORT, &GPIO);
GP2Y10_CONTROL = 0;
}
void GetGP2Y10Value(uint16_t *AQI, uint16_t *PM25)
{
uint16_t tmp[10] = {0}, max, min;
uint32_t value = 0;
uint8_t i, pMax = 0, pMin = 0;;
for(i = 0; i < 10; i ++)
{
GP2Y10_CONTROL = 0;
DelayUs(280);
tmp[i] = ADC_GetConversionValue(ADC1);
DelayUs(22);
GP2Y10_CONTROL = 1;
DelayUs(9680);
}
max = min = tmp[0];
for(i = 0; i < 10; i ++)
{
if (min > tmp[i])
{
min = tmp[i];
pMin = i;
}
if (max < tmp[i])
{
max = tmp[i];
pMax = i;
}
}
tmp[pMax] = 0;
tmp[pMin] = 0;
for (i = 0; i < 10; i ++)
{
value += tmp[i];
}
value = (uint16_t)((float)value / 10.0);
//printf("Volatge = %0.2f!\r\n", (float)(((float)value) / 4096.0 * 3.3));
*PM25 = (uint16_t)(((float)(((float)value) / 4096.0 * 3.3) * 0.17 - 0.1) * 1000.0);
if (*PM25 > 0 && *PM25 <= 35)
{
*AQI = (uint16_t)(50.0/35.0*(float)(*PM25 - 0) + 0);
}
if (*PM25 > 35 && *PM25 <= 75)
{
*AQI = (uint16_t)(50.0/40.0*(float)(*PM25 - 35) + 35.0);
}
if (*PM25 > 75 && *PM25 <= 115)
{
*AQI = (uint16_t)(50.0/40.0*(float)(*PM25 - 75) + 75.0);
}
if (*PM25 > 115 && *PM25 <= 150)
{
*AQI = (uint16_t)(50.0/35.0*(float)(*PM25 - 115) + 115.0);
}
if (*PM25 > 150 && *PM25 <= 250)
{
*AQI = (uint16_t)(100.0/100.0 * (float)(*PM25 - 150) + 150.0);
}
if (*PM25 > 250 && *PM25 <= 350)
{
*AQI = (uint16_t)(100.0/100.0*(float)(*PM25 - 250) + 250.0);
}
if (*PM25 > 350 && *PM25 <= 500)
{
*AQI = (uint16_t)(100.0/150.0*(float)(*PM25 - 350) + 350.0);
}
}
由于作者能力有限,有不妥之处欢迎指正,邮箱alex_hua@foxmail.com