|
大學(xué)期間第一次經(jīng)歷小學(xué)期,真是痛苦.....老師還要求做一個PM2.5檢測和處理的仿真,倒騰了兩個星期,又參(chao)照(xi)了論壇內(nèi)諸位大神的仿真圖,總算給倒騰出來了,深感單片機(jī)學(xué)習(xí)真是不容易。給各位共享出來,加油學(xué)習(xí),與諸君共勉......
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載):
仿真圖
單片機(jī)源程序如下:
- #include<reg51.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define LCD P0 //
- sbit PM2_5 = P2^1; //PM2.5模塊PWM輸入口
- sbit busy=P0^7; // "忙"標(biāo)志位
- sbit add=P1^0;
- sbit jian=P1^1;
- sbit ledred=P1^2;
- sbit ledgreen=P1^3;
- sbit sanji=P2^2;
- sbit erji=P2^3;
- sbit yiji=P2^4;
- sbit guolvwang=P2^0;
- sbit warning=P1^7;
- uint ji=120;
- uint LowPulseTime_30s = 0; //30秒內(nèi)低電平的時間,單位為ms
- uint LowPulseTime_3s = 0; //3秒內(nèi)低電平的時間,單位為ms
- uint TotalTime_3s = 0;//總時間,3秒計數(shù)器
- uint TotalTime_30s = 0;//總時間,30秒計數(shù)器*
- uint LowperTotal = 0; //30秒內(nèi)的低脈沖率,就是30秒內(nèi)的低脈沖時間除以30秒的總時間,范圍為5%~25%
- uint Concen = 0;//濃度值,整數(shù)
- uint pulseTime[10] = {0}; //每隔3秒的低電平時間數(shù)組,10項剛好就是30秒
- uchar Index = 0; //上述數(shù)組的索引
- bit bFreshDis = 0; //顯示值刷新標(biāo)志位,每隔3秒刷新一次顯示
- bit bStartDis = 0; //開始顯示濃度值標(biāo)志位,因為上電后要等30秒的預(yù)熱時間才能計算濃度值
- #define INT_CLOCK 1 //INT_CLOCK為定時值,單位為ms ,此處定義為1ms
- #define CRY_FREQUENCY 11059200 //CRY_FREQUENCY為晶振頻率,單位為,Hz
- uchar TL0_temp; //暫存TL0的初值 中斷值
- uchar TH0_temp; //暫存TH0的初值
- unsigned char fuhao;
- //代碼表
- uchar dat=0x00;
- uchar CH;
- uchar dis[]={0x01,0x02,0x03,0x04};
- unsigned char code hutab[10]={"0123456789"};
- uchar code tablewe[]={0xfd,0xfb,0xf7,0xf0,0xdf,0xfe};
- unsigned char code TAB1[]={ 0x0c,0x12,0x12,0x0c,
- 0x00,0x00,0x00,0x00,
- };
- //字符表
- unsigned char code digit[20]={"0123456789"}; //定義字符數(shù)組顯示數(shù)字
- /*************************
- LCD相關(guān)變量
- *************************/
- sbit RS=P2^5;
- sbit RW=P2^6;
- sbit EN=P2^7;
- //------------------------------------ 延時函數(shù) -------------------------------------------
- void delay(unsigned int t) //延時若干微秒
- {
- while(t--);
- }
- //定時器
- void Timer0_init()
- {
- unsigned long T0_temp; //暫存T0的初始值
- T0_temp = 65536-((INT_CLOCK *CRY_FREQUENCY /1000)/12); //T0初始值計算公式,參考教科書
- TL0_temp = T0_temp & 0xff;
- TH0_temp = T0_temp >> 8;
- TL0 = TL0_temp;
- TH0 = TH0_temp;
- TMOD = 0x11;
- TR0 = 1;
- ET0 = 1;
- CH=0x00;
- }
- /************************************************
- 1602相關(guān)函數(shù)定義
- ************************************************/
- //----------------------------------
- void CHECK_BF() //判斷是否忙碌
- {
- do
- {
- LCD=0xff;
- RS=0; // RS=0,選擇指令寄存器
- RW=1; // RW=1,選擇讀模式
- EN=0; // 執(zhí)行顯示命令
- EN=1; // 允許讀/寫
- }
- while(busy); //busy為高電平表示忙,循環(huán)等待
- }
- void WR_COMM()//寫指令//
- {
- RS=0;
- RW=0;
- EN=0;
- CHECK_BF();
- EN=1;
- }
- void WR_DATA()//寫數(shù)據(jù)//
- {
- RS=1;
- RW=0;
- EN=0;
- CHECK_BF();
- EN=1;
- }
- //1602初始化
- void INIT_LCD()
- {
- unsigned char i=200;
- {
- while(--i);
- LCD=0x01; //清屏并光標(biāo)復(fù)位
- WR_COMM(); //寫入命令
- LCD=0x38; //設(shè)置顯示模式:8位2行5x7點陣
- WR_COMM();
- LCD=0x0c; //開顯示屏
- WR_COMM();
- LCD=0x06; //文字不動,光標(biāo)自動右移
- WR_COMM(); //寫入命令
- }
- }
- //顯示模塊
- void DISP_YUJING()//顯示濃度
- {
- LCD=0xc0;
- WR_COMM();
- LCD=('P');
- WR_DATA();
- LCD=0xc1;
- WR_COMM();
- LCD=('M');
- WR_DATA();
- LCD=0xc2;
- WR_COMM();
- LCD=('2');
- WR_DATA();
- LCD=0xc3;
- WR_COMM();
- LCD=('.');
- WR_DATA();
- LCD=0xc4;
- WR_COMM();
- LCD=('5');
- WR_DATA();
- LCD=0xc5;
- WR_COMM();
- LCD=('y');
- WR_DATA();
- LCD=0xc6;
- WR_COMM();
- LCD=('u');
- WR_DATA();
-
- LCD=0xc7;
- WR_COMM();
- LCD=('j');
- WR_DATA();
- LCD=0xc8;
- WR_COMM();
- LCD=('i');
- WR_DATA();
- LCD=0xc9;
- WR_COMM();
- LCD=('n');
- WR_DATA();
-
- LCD=0xca;
- WR_COMM();
- LCD=('g');
- WR_DATA();
- LCD=0xcb;
- WR_COMM();
- LCD=(':');
- WR_DATA();
- LCD=0xcc;
- WR_COMM();
- LCD=ji/100+0x30;
- WR_DATA();
- LCD=0xcd;
- WR_COMM();
- LCD=(ji%100)/10+0x30;
- WR_DATA();
- LCD=0xce;
- WR_COMM();
- LCD=(ji%10)+0x30;
- WR_DATA();
-
-
- }
- void DISP_CONCE()//顯示濃度
- {
- LCD=0x80;
- WR_COMM();
- LCD=('P');
- WR_DATA();
- LCD=0x81;
- WR_COMM();
- LCD=('M');
- WR_DATA();
- LCD=0x82;
- WR_COMM();
- LCD=('2');
- WR_DATA();
- LCD=0x83;
- WR_COMM();
- LCD=('.');
- WR_DATA();
- LCD=0x84;
- WR_COMM();
- LCD=('5');
- WR_DATA();
- LCD=0x85;
- WR_COMM();
- LCD=('j');
- WR_DATA();
- LCD=0x86;
- WR_COMM();
- LCD=('i');
- WR_DATA();
-
- LCD=0x87;
- WR_COMM();
- LCD=('a');
- WR_DATA();
- LCD=0x88;
- WR_COMM();
- LCD=('n');
- WR_DATA();
- LCD=0x89;
- WR_COMM();
- LCD=('c');
- WR_DATA();
-
- LCD=0x8a;
- WR_COMM();
- LCD=('e');
- WR_DATA();
- LCD=0x8b;
- WR_COMM();
- LCD=(':');
- WR_DATA();
- LCD=0x8c;
- WR_COMM();
- LCD=Concen/100+0x30;
- WR_DATA();
- LCD=0x8d;
- WR_COMM();
- LCD=(Concen%100)/10+0x30;
- WR_DATA();
- LCD=0x8e;
- WR_COMM();
- LCD=(Concen%10)+0x30;
- WR_DATA();
-
- }
- void DISP_WAIT()//顯示等待
- {
- LCD=0x80;
- WR_COMM();
- LCD=('P');
- WR_DATA();
- LCD=0x81;
- WR_COMM();
- LCD=('M');
- WR_DATA();
- LCD=0x82;
- WR_COMM();
- LCD=('2');
- WR_DATA();
- LCD=0x83;
- WR_COMM();
- LCD=('.');
- WR_DATA();
- LCD=0x84;
- WR_COMM();
- LCD=('5');
- WR_DATA();
- LCD=0x85;
- WR_COMM();
- LCD=('j');
- WR_DATA();
- LCD=0x86;
- WR_COMM();
- LCD=('i');
- WR_DATA();
-
- LCD=0x87;
- WR_COMM();
- LCD=('a');
- WR_DATA();
- LCD=0x88;
- WR_COMM();
- LCD=('n');
- WR_DATA();
- LCD=0x89;
- WR_COMM();
- LCD=('c');
- WR_DATA();
-
- LCD=0x8a;
- WR_COMM();
- LCD=('e');
- WR_DATA();
- LCD=0x8b;
- WR_COMM();
- LCD=('w');
- WR_DATA();
- LCD=0x8c;
- WR_COMM();
- LCD=('a');
- WR_DATA();
- LCD=0x8d;
- WR_COMM();
- LCD=('i');
- WR_DATA();
- LCD=0x8e;
- WR_COMM();
- LCD=('t');
- WR_DATA();
-
-
- }
- void PM2_5SHUAXIN()
- {
- uchar i;
- if(bStartDis)
- {
- if(bFreshDis) /*開始刷新*/
- {
- bFreshDis = 0;
- LowPulseTime_30s = 0;
- for(i = 0;i < 10;i++)
- LowPulseTime_30s += pulseTime[i]; /**統(tǒng)計30秒內(nèi)的低電平時間**/
- }
- LowperTotal = LowPulseTime_30s/30; //低脈沖率本來是小數(shù),但這里將其變成整數(shù),便于單片機(jī)處理,假如脈沖率為25%,那么經(jīng)過此公式計算得到的值為25
- Concen = (LowperTotal*10)/2; //濃度值 = 低脈沖率/2 ;將濃度值放大十倍,變整數(shù)方便顯示*/
- DISP_CONCE(); //顯示
-
- }
- else /*預(yù)熱過程*/
- {
- DISP_WAIT(); /*顯示預(yù)熱*/
- } }
- /*************************************
- 主程序
- **************************************/
- //main
- void main()
- {
- uint ji2;
- uint ji3;
- Timer0_init(); //中斷初始化
- INIT_LCD(); //1602初始化
- EA = 1; //開中斷
- delay(100);
-
- while(1)
- {
- ji2=ji+50;
- ji3=ji+100;
- if(guolvwang==1)
- warning=1;
- else
- warning=0;
- if(add==0)
- {
- delay(20000);
- ji++;
- }
- if(jian==0)
- {
- delay(20000);
- ji--;
- }
- if(Concen>=ji)
- {
- ledgreen=0;
- ledred=1;
- }
- else
- {
- ledred=0;
- ledgreen=1;
- }
- //報警部分
- if(Concen>=ji3)
- sanji=1;
- else
- sanji=0;
- if(Concen>=ji2)
- {
- if(Concen<ji3)
- erji=1;
- else
- erji=0;
- }
- else
- erji=0;
- if(Concen>=ji)
- {
- if(Concen<ji2)
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
霧霾檢測及處理仿真.zip
(103.03 KB, 下載次數(shù): 303)
2017-7-12 16:32 上傳
點擊文件名下載附件
|
評分
-
查看全部評分
|