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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

采集溫度和測距,越限報警并傳送數據給上位機

[復制鏈接]
跳轉到指定樓層
樓主
#include < reg51.h >
#include < intrins.h >
#define uchar unsigned char
#define uint   unsigned int
#define lcddata P0
sbit LCDRS=P2^0;              //液晶數據選擇命令端
sbit LCDRW=P2^1;             //液晶讀寫命令端
sbit LCDEN=P2^2;            //液晶使能端
uchar mos0,mos1;

sbit DQ = P1^2;   //定義DS18B20端口DQ
sbit trig=P2^3;      //超聲波測距模塊Trig
sbit echo=P3^2;     //超聲波測距模塊Echo
sbit baojing=P1^0;                //baojing
sbit baojing1=P3^7;
sbit baojing2=P3^6;
sbit baojing3=P3^5;
sbit baojing4=P3^4;
sbit baojing5=P3^3;
long int distance;    //測量所得距離
uchar  juli_CS[ ] = "000.0";
uchar  juli_H[ ] = "000";
uchar  juli_L[ ] = "000";

uchar count;           //中斷累加變量
sbit key_H1=P1^7;     //上限加
sbit key_H2=P1^6;     //上限減
sbit key_L1=P1^5;     //下限加
sbit key_L2=P1^4;     //下限減

long int distance1=4000;//上限值
long int        distance2=100;//下限值


bit presence;           //ds18b20 DQ被拉低 信號0允許,1禁止
uint cc,cc2;       //變量cc中保存讀出的溫度值
float cc1;
uchar flag;                   //flag為溫度值正負標志位,“1”表示溫度為復制,“0”表示為正值//flag為溫度值正負標志位,“1”表示溫度為復制,“0”表示為正值
void write_com(uchar com);

uchar code cdis0[ ] = {"Detection signal"};
uchar code cdis1[ ] = {"Plese wait . . ."};
uchar  cdis2[ ] = "+00.00";
uchar code cdis3[ ] = " DS18B20 ERR0R " ;
uchar code cdis4[ ] = "  Please check  " ;
uchar code table[ ]={"0123456789"}; //定義字符數組顯示數字

unsigned char data   temp_data[2] = {0x00,0x00} ;  //存儲16位溫度

/**********************************lcd1602********************************************/

//----------------------------------
void delaylcd(uint z)
{uchar x,y;
for(x=z;x>0;x--)
  {for(y=110;y>0;y--);
  }
}

/*------------------------------------------------
                  延時函數
------------------------------------------------*/
void delayt(uint x)
{
    uchar j;
    while(x-- > 0)
    {
              for(j = 0;j < 125;j++)
        {
          ;
        }
    }
}
/*lcd1602初始化        */
/**********************************/
void lcd_init(void)
{
        write_com(0x38);                 //使用8位數據開關,顯示兩行,使用5*7字形
        write_com(0x0c);                //顯示器開,光標關,字符不閃爍         0x0e 光標開
        write_com(0x06);           //字符不動,光標自動右移動一位
        write_com(0x01);          //清屏
}

/*寫命令to lcd        */
/**********************************/
void write_com(uchar com)//寫命令
{
   LCDRW=0;         //低電平為寫
   LCDRS=0;         //低電平為命令選擇
   LCDEN=1;
   lcddata=com;
   delaylcd(5);
   LCDEN=1;
   delaylcd(5);
   LCDEN=0;
}

/*寫數據to lcd             */
/**********************************/
void write_data(uchar  date)
{
        LCDRW=0;  //低電平為寫
        LCDRS=1;  //高電平為數據選擇
        LCDEN=1;
        lcddata=date;
        delaylcd(5);
        LCDEN=1;
        delaylcd(5);
        LCDEN=0;
}

/*設定顯示位置             */
/********************************/
void lcd_pos(uchar pos)
{                                    //第一行第幾列直接寫pos為幾,第二行pos從0x40開始
   write_com(pos | 0x80) ;   //數據指針=80+地址變量
}

void lcd_pos1(uchar pos1)
{                                    //第?行第幾列直接寫pos為幾,第二行pos從0x40開始
   write_com(pos1 | 0xc0) ;   //數據指針=80+地址變量
}

/*******************************ds18b20*******************************************/
/*ms級別      */
void ddelay(uint ms)
{
uint i;
uchar j;
for(i=0;i<ms;i++)
   for(j=0;j<250;j++)
   {
    _nop_();          //一個機器周期,1us
           _nop_();          //適用于精度高的
        _nop_();
    _nop_();
   }
}
/*********us級延時**********/
void Delayus(uchar i)
{
  while(--i);
}
/*復位,每次讀寫之前都要進行復位*/
/**********************************/
bit ow_reset(void)
{

        DQ = 0; //拉低約600us
        Delayus(150);
        Delayus(150);

        DQ = 1;//產生上升沿,延時約15~60us
        Delayus(30);

        if(DQ==0) {presence=0;}         
        else presence=1;
        return(presence); //等待應答信號 0允許,1禁止
}

/*讀取數據一位            */
//---------------------------------
bit Read_bit()
{
        uint i = 0;
        bit b = 0;

        DQ = 0; //產生讀時隙  
        i++;         //維持低電平至少1us

        DQ = 1; //1us以上后拉高
        Delayus(2); //延時8us,DO下降沿15內ds18b20輸出的數據才有效
        b = DQ; //讀取數據
        Delayus(40);         //每個讀時隙至少持續60us
        return(b);
}

/*讀取一個字節             */
//------------------------------------
uchar Read_byte()
{
        uchar byte_read = 0;
        uchar i, j;

        for(i=0; i<8; i++)
          {
           j = Read_bit();
           byte_read = (j<<i) | byte_read; //低位讀起
          }

        return(byte_read);
}

//-----------------------------------------
/*寫一個字節         */
void Write_byte(uchar byte_to_write)
{
        uchar i = 0;
        uchar j = 0;
        bit write_bit = 0;

        for(j=0; j<8; j++)
          {
           write_bit =         (byte_to_write & 0x01);
            if(write_bit == 1) //寫1
          {
                  DQ = 0;  //產生寫時隙
                 Delayus(3);           //延時15us

                  DQ = 1;  //寫1
                  Delayus(40);   //延時,寫時隙不得低于60us
          }
        else
          {
                  DQ = 0;  //產生寫時隙
                  Delayus(50);   //延時,保持低約60us~120us
                  DQ = 1;  
                 i++;
          }
           byte_to_write = byte_to_write >> 1;
   }
}
//-----------------------------------
/*讀取溫度,啟動溫度轉換*/
/*啟動溫度轉換*/
void start_convert()
{
        ow_reset();          // 發出復位脈沖,每次操作都從復位開始
        ddelay(1);
        Write_byte(0xcc); //skip room命令,跳過序列號命令字
        Write_byte(0x44); //啟動溫度轉換命令
}

/*讀取溫度值*/
void read_tempreture()
{
        ow_reset();          // 發出復位脈沖,每次操作都從復位開始
        ddelay(1);
        Write_byte(0xcc); //skip room命令
        Write_byte(0xbe); //讀取暫存器命令
        temp_data[0] = Read_byte(); //存儲溫度低字節值 (整數部分低四位和小數部分) 先從低字節讀取
        temp_data[1] = Read_byte(); //存儲溫度高字節值 (其中高五位為符號位)
}
//--------------------------------------
/* Detection...顯示              */
void lcd_display()
{
        uchar   m ;
        lcd_pos(0) ;                 //設置顯示位置為第一行的第1個字符
      m = 0 ;
      while(cdis0[m] != '\0')
      {                          //顯示字符
        write_data(cdis0[m]) ;
        m++ ;
      }
        lcd_pos1(0) ;                 //設置顯示位置為第一行的第1個字符
      m = 0 ;
      while(cdis1[m] != '\0')
      {                          //顯示字符
        write_data(cdis1[m]) ;
        m++ ;
      }
}


//-----------------------------------
/*   ERR0R          */
/*PLEASE   CHECK  顯示    */
void Error_Menu ()
{
      uchar   m ;
      lcd_init() ;                 //初始化LCD
      lcd_pos(0) ;                 //設置顯示位置為第一行的第1個字符
      m = 0 ;
      while(cdis3[m] != '\0')
      {                          
        write_data(cdis3[m]) ;           //顯示字符
        m++ ;
      }

      lcd_pos(0x40) ;              //設置顯示位置為第二行第1個字符
      m = 0 ;
      while(cdis4[m] != '\0')
      {
        write_data(cdis4[m]) ;       //顯示字符
        m++ ;
      }
}

//------------------------------------
/*        ℃顯示        */
void temp_c()
{
        lcd_pos(6);                  
    write_data(0xdf);//
        lcd_pos(7);                  
   write_data('C');
}

//------------------------------------
/*溫度顯示                       */
void temperature_display()
{
          uchar m;
          flag=0;
    ddelay(2);
    EA=0;                                //DS18B20讀寫數據按照嚴格的時序,最好不要被打斷,故把所有中斷關閉
    start_convert();                          //啟動溫度轉換
    ddelay(250);
    read_tempreture();                          //讀取溫度
    EA=1;
   cc=temp_data[1]*256.0+temp_data[0];
    if(temp_data[1]>0xF8) {flag=1;cc=~cc+1;} else flag=0;
    cc1=cc*0.0625;
    cc2=cc1*100;
    cdis2[1]=cc2/1000+0x30;
    if(cdis2[1]==0x30)
    {cdis2[1]=0x20;}
    cdis2[2]=cc2/100%10+0x30;
    cdis2[4]=cc2%100/10+0x30;
    cdis2[5]=cc2%10+0x30;
    if(flag==1)
         cdis2[0]='-';
    else
         cdis2[0]='+';
                        lcd_pos(0) ;                 //設置顯示位置為第一行的第6個字符
                     m=0;
    while(cdis2[m]!='\0')
      {                          //顯示字符
                      write_data(cdis2[m]) ;
            m++;
      }                                                                  

}

/*--------------------------------------------
------------------超聲波函數-----------------
-------------------------------------------*/
/*------------------------------------------------
              1602顯示固定字符函數      
------------------------------------------------*/

void lcd_xianshi( )              
{   

         lcd_pos1(0);
           write_data('H');
         lcd_pos1(1);
           write_data('=');

         lcd_pos1(9);
           write_data('L');
         lcd_pos1(10);
           write_data('=');

         lcd_pos(12);
         write_data('.');
         lcd_pos(14);
         write_data('c');
         lcd_pos(15);
         write_data('m');
}


void init_t0()
{
                        PCON=0x00;  
                    SCON=0x50;

         TMOD=0x21;
                                                                                                                
         TL0=0x66;
         TH0=0xfc;              //1ms
                        TH1=0xfd;  
                   TL1=0xfd;  
                    TR1=1;
                     ET0=1;            
         EA=1;                     
}


/*------------------------------------------------
       超聲波模塊觸發信號
------------------------------------------------*/
void trigger()
{
            trig=0;
                  _nop_();
                  _nop_();
                  _nop_();
                  _nop_();
                  _nop_();
                  _nop_();
                  _nop_();
                  _nop_();
                  _nop_();
                  _nop_();
                  _nop_();
                  _nop_();
                  _nop_();
                  _nop_();
                  _nop_();
                  _nop_();
                  _nop_();
                  _nop_();
                  _nop_();
                  _nop_();
                  _nop_();
      trig=1;      
}


/*------------------------------------------------
   超聲波模塊相應端口初始化函數
------------------------------------------------*/
void init_measuring()
{
        trig=1;
        echo=1;
        count=0;
}


/*------------------------------------------------
     超聲波模塊距離測試函數
------------------------------------------------*/
void measuring()
{
        uchar l;
        uint h,y;
             while(echo==0);
        TR0 = 1;
        while(echo==1);         
        TR0 = 0;
        l = TL0;
        h = TH0;
        y = (h << 8) + l;
        y = y - 0xfc66;//us部分
        distance = y + 1000 * count;//計算總時間,單位是微秒
        TL0 = 0x66;
        TH0 = 0xfc;
        delayt(30);
        distance = 3453* distance / 20000;//算出來毫米,原始為:(0.34毫米/us)*時間/2//

}


/*------------------------------------------------
       超聲波模塊測量結果顯示函數
------------------------------------------------*/
void display(uint x)
{
        uchar bai,shi,ge,xiaoshu;
        bai=x/1000;
        shi=(x/100)%10;
        ge=(x/10)%10;
        xiaoshu=x%10;

                  juli_CS[0]=bai+0x30;
                  juli_CS[1]=shi+0x30;                  
                  juli_CS[2]=ge+0x30;
                  juli_CS[4]=xiaoshu+0x30;

        lcd_pos(9);//單位是厘米//
        write_data(table[bai]);//百位顯示
                  write_data(table[shi]);//十位顯示
                  write_data(table[ge]);//各位顯示
             lcd_pos(13);
                   write_data(table[xiaoshu]);//小數點后一位顯示

}
/*------------------------------------------
                                        延時函數1ms
-------------------------------------------*/

void delay_key(uchar m)
{

  uchar i,j;
  for(i=0;i<m;i++)
  for(j=0;j<24;j++);

}

void key()
{
        key_H1=1;     //上限加
        key_H2=1;     //上限減
        key_L1=1;     //下限加
        key_L2=1;       
        if(key_H1==0)
         {
                delay_key(1);       
                if(key_H1==0)
                {
                 distance1 = distance1+10;       
                }
         }

         if(key_H2==0)
         {
                delay_key(1);       
                if(key_H2==0)
                {
                 distance1 = distance1-10;       
                }
         }
               
         if(key_L1==0)
         {
                delay_key(1);       
                if(key_L1==0)
                {
                 distance2 = distance2+10;       
                }
         }

         if(key_L2==0)
         {
                delay_key(1);       
                if(key_L2==0)
                {
                  distance2 = distance2-10;
                  if(distance2<0)
                          {
                                distance2=0;
                        }
                }
         }
}
/*-----------------------------------------------*/
/*--------------上下限顯示----------------------*/
void display_H_L()
{       
        uchar H_bai,H_shi,H_ge;
        uchar L_bai,L_shi,L_ge;
        key();

        H_bai=distance1/1000;
   H_shi=(distance1/100)%10;
   H_ge=(distance1/10)%10;
        juli_H[0] = H_bai+0X30;
        juli_H[1] = H_shi+0X30;
        juli_H[2] = H_ge+0X30;


        L_bai=distance2/1000;
   L_shi=(distance2/100)%10;
   L_ge=(distance2/10)%10;
        juli_L[0] = L_bai+0X30;
        juli_L[1] = L_shi+0X30;
        juli_L[2] = L_ge+0X30;

   lcd_pos1(2);//單位是厘米//
   write_data(table[H_bai]);//百位顯示
        write_data(table[H_shi]);//十位顯示
        write_data(table[H_ge]);//各位顯示
        write_data('c');//各位顯示
        write_data('m');//各位顯示


   lcd_pos1(11);//單位是厘米//
   write_data(table[L_bai]);//百位顯示
        write_data(table[L_shi]);//十位顯示
        write_data(table[L_ge]);//各位顯示
        write_data('c');//各位顯示
        write_data('m');//各位顯示

}

/////////////////////////////////////////////
/*                串口                  */
////////////////////////////////////////////


void comm(uchar *parr)       //串口發送;  
{  
    do  
    {  
        SBUF=*parr++;  
        while(!TI);  
        TI=0;  
    }while(*parr!='\0');  
}  

//-------------------------------------------
/*主函數             */
void main()
{       

        baojing=0;
        baojing1=0;//由于此單片機驅動電流太小
        baojing2=0;//所以用空閑的I/O口作并聯
        baojing3=0;//以提高輸出電流
        baojing4=0;
        baojing5=0;
        lcd_init();                 //初始化LCD
    init_t0();          //定時器0初始化
    init_measuring();  //超聲波相應端口初始化
    lcd_display(); //顯示Detection
    ddelay(1000);   //顯示Detection1s
    ddelay(1000);   //顯示Detection1s
    ddelay(1000);   //顯示Detection1s
         write_com(0x01);//清屏
    ow_reset();//DS18B20復位
         while(1)
         {       
                 comm(cdis2);
                comm("\r\n");
                comm(juli_CS);
                comm("\r\n");
                comm(juli_H);
                comm("\r\n");
                comm(juli_L);
                comm("\r\n");
                comm("\r\n");            
                 if(presence==0)
             {          
                
                 temperature_display();//溫度顯示
                                temp_c();//顯示℃                            

             }
                   else
            {
                 Error_Menu ();//顯示字符串DS18B20 ERR0R Please check
                 while(1)
                 {
                          ow_reset();//DS18B20復位
                          if(presence==0)
                                   {
                                temperature_display();//溫度顯示
                                   }
                 }
            }

                   lcd_xianshi( ) ;  //液晶顯示特定字符
        trigger();      //觸發超聲波啟動

        measuring();           //進行距離測量
                  display_H_L();//顯示上下限
                  if(distance>distance1||distance<distance2)
                                  {
                                        baojing=1;
                                        baojing1=1;//由于此單片機驅動電流太小
                                        baojing2=1;//所以用空閑的I/O口作并聯
                                        baojing3=1;//以提高輸出電流
                                        baojing4=1;
                                        baojing5=1;
                                }
                  else
                                  {
                                        baojing=0;
                                        baojing1=0;//由于此單片機驅動電流太小
                                        baojing2=0;//所以用空閑的I/O口作并聯
                                        baojing3=0;//以提高輸出電流
                                        baojing4=0;
                                        baojing5=0;
                                }
        display(distance);    //對測量結果進行顯示
        init_measuring();    //超聲波相應端口初始化
         }
}
//……………………………………………中斷服務函數……

void T_0()interrupt 1
{

        TL0 = 0x66;
        TH0 = 0xfc;
        count++;
       if(count==39)
       {
          TR0 =0;
          TL0 = 0x66;
          TH0 = 0xfc;
          count = 0;
       }
}


QQ截圖20180531142459.png (71.77 KB, 下載次數: 66)

仿真原理圖

仿真原理圖

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

沙發
ID:383374 發表于 2019-1-22 21:02 來自手機 | 只看該作者
如何區分數據
回復

使用道具 舉報

板凳
ID:439030 發表于 2020-1-2 01:23 | 只看該作者
發送數據給上位機的代碼呢?
回復

使用道具 舉報

地板
ID:438586 發表于 2021-2-28 10:30 | 只看該作者
1121060090 發表于 2020-1-2 01:23
發送數據給上位機的代碼呢?

主程序里的while(1)循環的前幾行就是啊
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产欧美日韩精品一区 | 欧美日韩视频在线第一区 | 精品视频一区在线 | 成人免费在线播放 | 国产一区二区三区视频 | av在线免费观看网址 | 香蕉av免费 | 国产午夜精品久久久久 | 国产午夜精品一区二区三区 | 日本91av视频 | 一区二区视频免费观看 | 亚洲精品在线视频 | 国内久久 | www.99re | 国产视频在线观看一区二区三区 | 福利片在线观看 | 天天操综合网 | 精品国产91乱码一区二区三区 | 欧美a级成人淫片免费看 | 看a网站 | 中文av字幕 | 成人免费黄色片 | 欧美一级二级视频 | 久久久久久久久久久福利观看 | 日本不卡一区二区三区 | 日韩看片 | 久久精品二区 | 亚洲精品久久久久久久不卡四虎 | 欧洲一级毛片 | 天天拍夜夜爽 | 97超级碰碰 | 中文字幕一区二区三区在线乱码 | 亚洲成人精品一区 | 欧美精品久久久久久 | 欧美日韩久久 | 日韩在线 | 亚洲狠狠爱一区二区三区 | 亚洲精品免费在线 | 日本在线小视频 | 91av在线免费看 | 久久精品一区二区三区四区 |