光學(xué)灰塵傳感器(CP2Y1014AUOF) 在檢測(cè)非常細(xì)的顆粒、例如香煙煙霧、是很有效的、并且是常用的空氣凈化器系統(tǒng)、改裝置中、一個(gè)紅外發(fā)光二極管和光電晶體管、對(duì)角布置成允許其檢測(cè)到空氣中的灰塵反射光。該傳感器具有很低的電流消耗(限大20mA 11毫安典型的)可以搭載高達(dá)7VDC的傳感器、輸出的是一個(gè)模擬電壓正比于所測(cè)得粉塵濃度、敏感性為0.5V/0.1mg/m3
[attach]229933[/attach]
2. GP2Y1014AU粉塵傳感器的硬件連接
2.png (28.83 KB, 下載次數(shù): 97)
下載附件
2020-4-17 16:15 上傳
3.png (40.83 KB, 下載次數(shù): 79)
下載附件
2020-4-17 16:15 上傳
(1) 電阻R6和電容C9:因?yàn)閂-LED和LED-GND是給紅外發(fā)光二極管供電的,所以不能直接接上5V,需要串一個(gè)150歐的電阻來(lái)限流,另外為了穩(wěn)定供電,還需要在給發(fā)光二極管供電的正極和負(fù)極上并一個(gè)220uf的電容。
(2) 上圖中的3為脈沖輸入腳,為傳感器提供輸入信號(hào)(該P(yáng)WM的占空比規(guī)定為0.032)
(3) 上圖中的5為單片機(jī)的ADC模擬輸入腳,用來(lái)輸出信號(hào)的,空氣質(zhì)量數(shù)據(jù)通過(guò)電壓模擬信號(hào)輸出
(4) 電阻R3和R4:起分壓作用(因?yàn)樵搨鞲衅魇?V供電,而32單片機(jī)的AD采樣最大電壓為3.3V)
4.png (3.95 KB, 下載次數(shù): 69)
下載附件
2020-4-17 16:16 上傳
5.png (4.63 KB, 下載次數(shù): 60)
下載附件
2020-4-17 16:16 上傳
圖1為脈沖輸入波形,周期為10ms,高電平為0.32ms
圖2為AD采樣時(shí)序,由圖可知,在輸入上升沿到輸出的峰值,時(shí)間為280us左右,就在此時(shí)進(jìn)行采樣,因?yàn)檎麄(gè)高電平持續(xù)的時(shí)間為320us,所以在打開(kāi)紅外發(fā)光二極管280us后采樣,然后延時(shí)40us后關(guān)閉紅外發(fā)光二極管,最后再延時(shí)9680us(輸入波形的周期為10ms),這就實(shí)現(xiàn)了一次完整的工作
3. GP2Y1014AU粉塵傳感器的軟件設(shè)計(jì)
(1) tsensor.c包括GP2Y_Adc_Init函數(shù)、GetGP2Y函數(shù)、GP2Y_Get_Adc函數(shù)、GPY2_Get_Adc_Aveurage函數(shù)四個(gè)部分
//初始化ADC
//這里我們僅以規(guī)則通道為例
//我們默認(rèn)將開(kāi)啟通道0~3
void GP2Y_Adc_Init(void) //ADC通道初始化
{
ADC_InitTypeDefADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1 , ENABLE ); //使能GPIOA,ADC1通道時(shí)鐘
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //分頻因子6時(shí)鐘為72M/6=12MHz
//PA1作為模擬通道輸入引腳
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模擬輸入引腳
GPIO_Init(GPIOA, &GPIO_InitStructure);
//PB1 作為脈沖輸出引腳
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GP2Y_High;
ADC_DeInit(ADC1); //將外設(shè) ADC1 的全部寄存器重設(shè)為缺省值
ADC_InitStructure.ADC_Mode= ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在獨(dú)立模式
ADC_InitStructure.ADC_ScanConvMode= DISABLE; //模數(shù)轉(zhuǎn)換工作在單通道模式
ADC_InitStructure.ADC_ContinuousConvMode= DISABLE; //模數(shù)轉(zhuǎn)換工作在單次轉(zhuǎn)換模式
ADC_InitStructure.ADC_ExternalTrigConv= ADC_ExternalTrigConv_None; //轉(zhuǎn)換由軟件而不是外部觸發(fā)啟動(dòng)
ADC_InitStructure.ADC_DataAlign= ADC_DataAlign_Right; //ADC數(shù)據(jù)右對(duì)齊
ADC_InitStructure.ADC_NbrOfChannel= 1; //順序進(jìn)行規(guī)則轉(zhuǎn)換的ADC通道的數(shù)目
ADC_Init(ADC1,&ADC_InitStructure); //根據(jù)ADC_InitStruct中指定的參數(shù)初始化外設(shè)ADCx的寄存器
ADC_Cmd(ADC1,ENABLE); //使能指定的ADC1
ADC_ResetCalibration(ADC1); //重置指定的ADC1的復(fù)位寄存器
while(ADC_GetResetCalibrationStatus(ADC1)); //獲取ADC1重置校準(zhǔn)寄存器的狀態(tài),設(shè)置狀態(tài)則等待
ADC_StartCalibration(ADC1); //開(kāi)啟AD校準(zhǔn)
while(ADC_GetCalibrationStatus(ADC1)); //獲取指定ADC1的校準(zhǔn)程序,設(shè)置狀態(tài)則等待
}
//獲得ADC值
//ch:通道值 0~3
u16 GP2Y_Get_Adc(u8 ch)
{
//設(shè)置指定ADC的規(guī)則組通道,一個(gè)序列,采樣時(shí)間
ADC_RegularChannelConfig(ADC1,ch, 1, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道3,第一個(gè)轉(zhuǎn)換,采樣時(shí)間為239.5周期
ADC_SoftwareStartConvCmd(ADC1,ENABLE); //使能指定的ADC1的軟件轉(zhuǎn)換啟動(dòng)功能
while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC ));//等待轉(zhuǎn)換結(jié)束
returnADC_GetConversionValue(ADC1); //返回最近一次ADC1規(guī)則組的轉(zhuǎn)換結(jié)果
}
//計(jì)算模擬量
Short GetGP2Y(void)
{
u32 AD_PM;
short result;
double pm;
GP2Y_Low; //打開(kāi)紅外二極管
delay_us(280); //延時(shí)280us,延時(shí)時(shí)間到才進(jìn)行采樣
AD_PM = GP2Y_Get_Adc(ADC_Channel_0); //PA0 采樣,讀取AD值
delay_us(40); //延時(shí)33us,280+40=320us,這是LED亮燈的最短時(shí)間
GP2Y_High; //關(guān)閉紅外二極管
delay_us(9680); //延時(shí)9680us,320+9680=10000us=10ms,這是一個(gè)周期的最短時(shí)間
pm = (0.17*AD_PM-0.1)*1000; //電壓-灰塵轉(zhuǎn)換公式乘以1000單位換成ug/m3
printf("%f\n",pm);
result=pm*100;
return result;
//return pm;
}
//獲取通道ch的轉(zhuǎn)換值
//取times次,然后平均
u16 GPY2_Get_Adc_Aveurage(u8 ch,u8 times)
{
u32pm_val=0;
u8t;
for(t=0;t<times;t++)
{
pm_val+=GP2Y_Get_Adc(ch);
delay_ms(5);
}
returnpm_val/times;
}
(2) 主函數(shù):將接收到的PM2.5濃度顯示到LCD上,每秒更新一次
intmain(void)
{
shortPM;
delay_init(); //延時(shí)函數(shù)初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設(shè)置中斷優(yōu)先級(jí)分組為組2:2位搶占優(yōu)先級(jí),2位響應(yīng)優(yōu)先級(jí)
uart_init(115200); //串口初始化為115200
LED_Init(); //初始化與LED連接的硬件接口
LCD_Init(); //初始化LCD
GP2Y_Adc_Init(); //ADC初始化
POINT_COLOR=RED;//設(shè)置字體為紅色
LCD_ShowString(30,50,200,16,16,"EliteSTM32");
LCD_ShowString(30,70,200,16,16,"TemperatureTEST");
LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
LCD_ShowString(30,110,200,16,16,"2020/4/4");
POINT_COLOR=BLUE;//設(shè)置字體為藍(lán)色
LCD_ShowString(30,140,200,16,16,"PM2.5:000.000ug/m3");
while(1)
{
PM=GetGP2Y(); //得到pm2.5值
printf("PM2.5濃度:%f\n",PM);
LCD_ShowxNum(30+6*8,140,PM/100,3,16,0); //顯示數(shù)部分
LCD_ShowxNum(30+10*8,140,PM%100,3,16,0X80); //顯示小數(shù)部分
LED0=!LED0;
delay_ms(1000);
}
}