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