久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3747|回復: 1
打印 上一主題 下一主題
收起左側

單片機+溫度檢測+空氣檢測+PM2.5檢測

[復制鏈接]
跳轉到指定樓層
樓主
基于51單片機的空氣質量監測系統
原理圖:



程序如下:
#include <reg52.h>
#include <intrins.h>
#include <absacc.h>
#include <math.h>
#include "0832.h"

#define uchar unsigned char
#define uint unsigned int



//定義LCD1602端口
sbit E=P2^6;                //1602使能引腳
sbit RS=P2^7;                //1602數據/命令選擇引腳
sbit RW=P2^5;

sbit LED_RED=P2^2;
sbit LED_YELLOW=P2^1;
sbit LED_GREEN=P2^0;


sbit SET_KEY=P3^4;
sbit ADD_KEY=P3^5;
sbit SUB_KEY=P3^6;


sbit BUZZ=P3^7;
sbit jdq=P2^4;

                       
                       
volatile unsigned char BEEP_Cnt = 0;
                       
unsigned char PM_Waring = 50;
unsigned char Temp_Waring = 20;
unsigned char Smok_Waring = 50;


unsigned char Smok_Value = 125;

unsigned char PM_Waring;
unsigned char PM_Value;





bit FlagStartRH=0;
bit flag_BJ=0;

unsigned char a1,a2,a3;




extern volatile unsigned char KEY_Value;
#define KEY_NOP         0
#define KEY_SET                     1
#define KEY_UP                      2
#define KEY_DOWN                           3




void Delay_1ms(unsigned int n)                //@11.0592MHz
{
       
        unsigned char i, j;
        while(n--)
        {
                _nop_();
                i = 2;
                j = 199;
                do
                {
                        while (--j);
                } while (--i);
        }
}



volatile unsigned char KEY_Value = KEY_NOP;



void Key_Scan(void)        //按鍵檢測
{
       
        static volatile unsigned char Trg = 0;
        static volatile unsigned char Cnt = 0;
        unsigned char KeyRead = 0;
       
        KeyRead = ((P3>>4) & 0X07) ^ 0X07;
        Trg = KeyRead ^ (KeyRead & Cnt);
  Cnt =        KeyRead;
       
        if(Trg)
        {
                switch(Trg)
                {
                        case 0x01: KEY_Value = KEY_SET; break;
                        case 0x02: KEY_Value = KEY_UP; break;
                        case 0x04: KEY_Value = KEY_DOWN; break;
                       
                        default:   KEY_Value = KEY_NOP;break;

                       
                }
               
               
        }
       
}









unsigned char Temp_Value = 0; //溫度

/*********************************端口定義**********************************/
sbit DQ=P1^6;                                   //數據傳輸線接單片機的相應的引腳




/*********************************定義全局變量******************************/
bit TemperatureLessZero;
unsigned int Temperature = 850;           //溫度值(整型變量)182表示18.2C
/****************************************************************************
函數功能:延時子程序
入口參數:k
出口參數:
****************************************************************************/
void DS18_delay(unsigned char useconds)                  //延遲17US.根據晶振調節
{
        unsigned char i;
        while(--useconds)
        {
                i = 3;
                while (--i);
        }
}

/***************************************************************************
函數功能:DS18B20初始化子程序
入口參數:
出口參數:
****************************************************************************/
unsigned char Init_DS18B20(void)
{
        unsigned char x=0;

          DQ=0;                             //發送復位脈沖
          DS18_delay(29);                         //延時(>480us)
          DQ=1;                                  //拉高數據線
          DS18_delay(3);                       //等待(15~60us) 等待存在脈沖
    x=DQ;  //獲得存在信號(用于判斷是否有器件)
    DS18_delay(25);  // 等待時間隙結束
    return(x);  //返回存在信號,0 = 器件存在, 1 = 無器件
}

/****************************************************************************
函數功能:向DS18B20讀一字節數據
入口參數:
出口參數:dat
****************************************************************************/
ReadOneChar(void)                         
{
        unsigned char i=0;                
        unsigned char dat=0;
    for (i=8;i>0;i--)                 
                {
                        DQ=1;
                           DS18_delay(1);
                    DQ=0;      
                    dat>>=1;//復合賦值運算,等效dat=dat>>1(dat=dat右移一位后的值)
                           DQ=1;
                    if(DQ)
                           dat|=0x80;
                    DS18_delay(4);
                }
    return(dat);
}

/****************************************************************************
函數功能:向DS18B20寫一字節數據
入口參數:dat
出口參數:
****************************************************************************/
void WriteOneChar(unsigned char dat)//有參函數,功能是"寫",而寫的內容就是括號內的參數
{
        unsigned char i=0;                
        for(i=8;i>0;i--)         
        {
                DQ=0;           
                DQ=dat&0x01;
                DS18_delay(4);
                DQ=1;
                dat>>=1;//復合賦值運算,等效dat=dat>>1(dat=dat右移一位后的值)
        }
//        DS18_delay(4);
}
                       
/****************************************************************************
函數功能:向DS18B20讀溫度值
入口參數:
出口參數:temperature
****************************************************************************/
void ReadTemperature(void)
{  
        unsigned char tempL=0;                         //臨時變量低位(無符號字符變量)
        unsigned char tempH=0;                        //臨時變量高位
        bit flag = 0;
        EA = 0;
        Init_DS18B20();                                 //初始化,調用初始化函數
        WriteOneChar(0xcc);                  //跳過讀序列號的操作,調用寫函數,寫0xcc指令碼(跳過讀序列號)
        WriteOneChar(0x44);                 //啟動溫度轉換,調用寫函數,寫0x44指令碼(啟動溫度轉換)

//  Time = get_time();
//        DS18_delay(125);                           //轉換需要一點時間,延時
        Init_DS18B20();                         //初始化,調用初始化函數
        WriteOneChar(0xcc);                  //跳過讀序列號的操作,調用寫函數,寫0xcc指令碼(跳過讀序列號?
        WriteOneChar(0xbe);                 //調用寫函數,寫0xbe指令碼,讀溫度寄存器(頭兩個值分別為溫度的低位和高位)
        tempL=ReadOneChar();                 //讀出溫度的低位LSB
        tempH=ReadOneChar();                 //讀出溫度的高位MSB  
        TemperatureLessZero = (bit)(tempH&0x80);
  Temperature=((((tempH&0x7F)<<8)+tempL)*10)>>4;  //溫度轉換,把高低位做相應的運算轉化為實際溫度,使用DS18B20溫度傳感器手冊規定的公式,結果是十進制數值
                                                  //這里使用*0.0625,直接增加500+字節代碼
       
        EA = 1;
        Temp_Value = Temperature/10;
       
        if(Temp_Value > 125) Temp_Value =125;
        if(TemperatureLessZero)Temp_Value = 0;

//        DS18_delay(20);
//        return(tempa);//運算結果返回到函數 :ReadTemperature()調用時需要采用i=ReadTemperature(),然后再對i(任意uchar型變量)進行操作
}






void L1602_string(uchar hang,uchar lie,uchar *p);

//定時器0初始化
void Timer0_Init()
{
        //AUXR &= 0x7F;                //定時器時鐘12T模式
        TMOD &= 0xF0;                //設置定時器模式
        TMOD |= 0x01;                //設置定時器模式
        TL0 = 0xB0;                //設置定時初值
        TH0 = 0x3C;                //設置定時初值
        TF0 = 0;                //清除TF0標志
        TR0 = 1;                //定時器0開始計時
        ET0 = 1;
}

bit Time0_300ms_Flag = 1;


//定時器0中斷
void Timer0_ISR (void) interrupt 1 using 0
{
        static uchar RHCounter;
        static uchar Time0_300ms_Cnt;
       
        TR0 = 0;
        TL0 = 0xb0;
        TH0 = 0x3c;     //定時器賦予初值
        TR0 = 1;
       
       
        Key_Scan();
       
        if(++Time0_300ms_Cnt>= 6)
        {
                Time0_300ms_Cnt = 0;
                Time0_300ms_Flag = 1;
        }

    if(++RHCounter >= 20)
    {
                         RHCounter = 0;
                       
       FlagStartRH = 1;
                       
    }
               
        if(BEEP_Cnt)
        {
                BEEP_Cnt--;
                BUZZ = 0;
        }
        else
        {       
                BUZZ = 1;
        }
}


/********************************************************************
* 文件名  : 液晶1602顯示.c
* 描述    :  該程序實現了對液晶1602的控制。
***********************************************************************/


/********************************************************************
* 名稱 : delay()
* 功能 : 延時,延時時間大概為140US。
* 輸入 : 無
* 輸出 : 無
***********************************************************************/

void delay()
{
        int i,j;
        for(i=0; i<=10; i++)
        for(j=0; j<=2; j++);
}

void delay_ms(uint ms)
{
        uint i,j;
        for(i=0;i<ms;i++)
        for(j=0;j<110;j++);
}           
       
/********************************************************************
* 名稱 : enable(uchar del)
* 功能 : 1602命令函數
* 輸入 : 輸入的命令值
* 輸出 : 無
***********************************************************************/

void enable(uchar del)
{
        P0 = del;
        RS = 0;
        E = 1;
        delay();
        E = 0;
        delay();
}

/********************************************************************
* 名稱 : write(uchar del)
* 功能 : 1602寫數據函數
* 輸入 : 需要寫入1602的數據
* 輸出 : 無
***********************************************************************/

void write(uchar del)
{
        P0 = del;
        RS = 1;
        E = 1;
        delay();
        E = 0;
        delay();
}

/********************************************************************
* 名稱 : L1602_init()
* 功能 : 1602初始化,請參考1602的資料
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void L1602_init(void)
{
        RW=0;
        enable(0x38);
        enable(0x0c);
        enable(0x06);
        enable(0x01); //清屏要放在最后
        enable(0x80);
        L1602_string(1,1," PM2.5:   0ug/m3");
        enable(0xc0+0x02);
        write(0xdf);
        L1602_string(2,4,"C");
        L1602_string(2,5," Smok:");
}

/********************************************************************
* 名稱 : L1602_char(uchar hang,uchar lie,char sign)
* 功能 : 改變液晶中某位的值,如果要讓第一行,第五個字符顯示"b" ,調用該函數如下
                 L1602_char(1,5,'b')
* 輸入 : 行,列,需要輸入1602的數據
* 輸出 : 無
***********************************************************************/
void L1602_char(uchar hang,uchar lie,char sign)
{
        uchar a;
        if(hang == 1) a = 0x80;
        if(hang == 2) a = 0xc0;
        a = a + lie - 1;
        enable(a);
        write(sign);
}

/********************************************************************
* 名稱 : L1602_string(uchar hang,uchar lie,uchar *p)
* 功能 : 改變液晶中某位的值,如果要讓第一行,第五個字符開始顯示"ab cd ef" ,調用該函數如下
                  L1602_string(1,5,"ab cd ef;")
* 輸入 : 行,列,需要輸入1602的數據
* 輸出 : 無
***********************************************************************/
void L1602_string(uchar hang,uchar lie,uchar *p)
{
        uchar a;
        if(hang == 1) a = 0x80;
        if(hang == 2) a = 0xc0;
        a = a + lie - 1;
        enable(a);
        while(1)
        {
                if(*p == '\0') break;
                write(*p);
                p++;
        }
}






void LCD1602_Write_String(bit x,unsigned char y,unsigned char *P)
{
       
        if(x)
        {
                enable(0x80 + 0x40 + y);
        }
        else
        {
                enable(0x80 + y);
        }
       
        while(*P)
        {
                write(*P++);
        }
       
}




void LCD1602_Write_8bit(unsigned int x,unsigned char SIZE)
{
        switch(SIZE)
        {
               
                case 3:
               
                                        write(0x30 + ((x/100)%10));
                                        write(0x30 + ((x/10)%10));
                                        write(0x30 + ((x)%10));
               
                                        break;
                case 4:
                       
                        break;
               
               
                default:  break;
               
        }
}



void display()
{

        if(PM_Value%10000/1000!=0)
        L1602_char(1,8,PM_Value%10000/1000+0x30);
        else
        L1602_char(1,8,' ');
        if(PM_Value%10000/100!=0)
        L1602_char(1,9,PM_Value%1000/100+0x30);
        else
        L1602_char(1,9,' ');
        if(PM_Value%10000/10!=0)
        L1602_char(1,10,PM_Value%100/10+0x30);
        else
        L1602_char(1,10,' ');
        L1602_char(1,11,PM_Value%10+0x30);
       

        a1=(Temp_Value/10)%10;
        a3=Temp_Value%10;

        L1602_char(2,1,a1+0x30);
        L1602_char(2,2,a3+0x30);
       
       
        L1602_string(2,5," Smok:");
       
        LCD1602_Write_8bit(Smok_Value,3);
       
        BUZZ=1;         //蜂鳴器關
}



void ALARM()
{
       
        if((PM_Value >= PM_Waring)||(Smok_Value >= Smok_Waring)||(Temp_Value >= Temp_Waring))
        {
                BEEP_Cnt = 20;
               
                LED_RED=0;
                LED_YELLOW=1;
                LED_GREEN=1;
                jdq=0;
        }
        else
        {
                if((PM_Value < PM_Waring)  &&  (PM_Value >= PM_Waring/2) && (Smok_Value < Smok_Waring)&& (Temp_Value < Temp_Waring))
                {
                        LED_RED=1;
                        LED_YELLOW=0;
                        LED_GREEN=1;
                        jdq=1;
                }
                else
                {
                        LED_RED=1;
                        LED_YELLOW=1;
                        LED_GREEN=0;
                        jdq=1;
                }

        }
}





bit LCD1602_Enable = 1;

volatile unsigned char Menu_States = 0;



void KEY_Processing(void)
{
       
        if(KEY_SET == KEY_Value)       
        {
                KEY_Value = KEY_NOP;

                Menu_States = ++Menu_States % 4;
               
                enable(0x01);
                if(Menu_States == 0)
                {
                        L1602_init();
                }       
               
                LCD1602_Enable = 1;
        }
       
       
        if(KEY_UP==KEY_Value)        //下限加
        {
                KEY_Value = KEY_NOP;
                LCD1602_Enable = 1;
                switch(Menu_States)
                {
                        case 1:if(PM_Waring   < 255)PM_Waring++;   enable(0x01);  break;
                        case 2:if(Temp_Waring < 125)Temp_Waring++; enable(0x01); break;
                        case 3:if(Smok_Waring < 100)Smok_Waring++; enable(0x01); break;
                }
        }
       
       
        if(KEY_DOWN ==KEY_Value)        //上限減
        {
                KEY_Value = KEY_NOP;
                LCD1602_Enable = 1;
                switch(Menu_States)
                {
                        case 1:if(PM_Waring   > 0)PM_Waring--;   enable(0x01); break;
                        case 2:if(Temp_Waring > 0)Temp_Waring--; enable(0x01); break;
                        case 3:if(Smok_Waring > 0)Smok_Waring--; enable(0x01); break;
                       
                }
        }

       
       
       
}





void LCD1602_Processing(void)
{
       
        if(Time0_300ms_Flag || LCD1602_Enable)
        {
                Time0_300ms_Flag = 0;
                LCD1602_Enable = 0;
                switch(Menu_States)
                {
                        case 0:
                                                        display();
                                                        break;
                       
                        case 1:
                                                        enable(0x0c);  //不顯示光標
                                                        LCD1602_Write_String(0,0,"PM_Waring:");
                       
                                                        enable(0xC0+4);
                                                        LCD1602_Write_8bit(PM_Waring,3);
                               
                                                        enable(0xC0+6);
                                                        enable(0x0F);  //顯示光標
                       
                                                break;
                       
                        case 2:
                                                        enable(0x0c);  //不顯示光標
                                                        LCD1602_Write_String(0,0,"Temp_Waring:");
                                                        enable(0xC0+4);
                                                        LCD1602_Write_8bit(Temp_Waring,3);
                               
                                                        enable(0xC0+6);
                                                        enable(0x0F);  //顯示光標
                       
                                                break;
                       
                        case 3:
                                                        enable(0x0c);  //不顯示光標
                                                        LCD1602_Write_String(0,0,"Smok_Waring:");
                       
                                                        enable(0xC0+4);
                                                        LCD1602_Write_8bit(Smok_Waring,3);
                                                        enable(0xC0+6);
                                                        enable(0x0F);  //顯示光標
                                                break;
                       
                       
                        default:  break;
                       
                }                       
        }
}



/********************************************************************
* 名稱 : Main()
* 功能 : 主函數
***********************************************************************/
void main()
{
        static bit CH;
        Timer0_Init();  //定時器0初始化
       

        L1602_init();
       
        ReadTemperature();
        ReadTemperature();
        Delay_1ms(1000);
        ReadTemperature();
        Delay_1ms(1000);
  ReadTemperature();
        Delay_1ms(1000);
        ReadTemperature();
        Delay_1ms(1000);
        ReadTemperature();
       
        PM_Value = ADC0832_Read(0);
       
        Smok_Value = ADC0832_Read(1)/2.56;
       
        EA = 1;
        while(1)
        {
                if(FlagStartRH )         //溫濕度轉換標志檢查
                {
                        FlagStartRH = 0;
                                 
                        CH = ~CH;
                       
                        if(CH)
                        {
                                PM_Value = ADC0832_Read(0);
                        }
                        else
                        {
                                Smok_Value = ADC0832_Read(1)/2.56;
                        }
               
                        ReadTemperature();

                }
               
                LCD1602_Processing();
               
                KEY_Processing();
               
                ALARM();
        }
}


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:910466 發表于 2021-4-25 20:06 | 只看該作者
#include "0832.h"
這個文件是什么。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 卡通动漫第一页 | 午夜一区二区三区在线观看 | 91麻豆产精品久久久久久夏晴子 | 国产成人精品午夜视频免费 | 97caoporn国产免费人人 | www.久久99 | 国产在线a | 亚洲欧美视频 | 亚洲一二三区在线观看 | 国产欧美精品一区 | 久久这里有精品 | 性色av香蕉一区二区 | 精品亚洲一区二区三区 | 色橹橹欧美在线观看视频高清 | 国产精品不卡一区 | 国产免费观看一区 | 91在线观看 | 欧美中文 | 亚洲综合大片69999 | 999热精品视频| 在线成人精品视频 | 在线91 | 中文一区二区视频 | 一区二区在线不卡 | 国产精品久久二区 | 在线国产一区 | 欧洲一级毛片 | 国产精品久久欧美久久一区 | 911精品国产 | 中文字幕一区二区三区四区五区 | 婷婷五月色综合香五月 | 日本久久久久久久久 | 欧美在线一区二区三区 | 香蕉久久久 | 国产一区二区三区精品久久久 | 中国美女一级黄色片 | 国产精品人人做人人爽 | 国产一区二区三区 | 亚洲国产精品久久久久秋霞不卡 | 日本在线视频一区二区 | 日本国产精品视频 |