<acronym id="xonnx"></acronym>
      <td id="xonnx"></td>
    1. <pre id="xonnx"></pre>

      1. 專注電子技術學習與研究
        當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

        DS18B20-64位序列碼讀取程序

        作者:huqin   來源:本站原創   點擊數:  更新時間:2014年03月17日   【字體:

        /*******************************************************************/
        /*                                                                 */
        /*51hei單片機開發系統演示程序 - DS18B20-64位序列碼讀取程序     */
        /*                                                                  *
        * LCD1602顯示                                                     *
        *                                                                 *
        * 工作芯片:STC89C516      晶振頻率:11.0592MHz                   *
        *                                                                 *
        /*******************************************************************/
        /*讀取DS18B20的64位序列碼并顯示在1602液晶上,如果讀取正確結果,則在
        液晶第一行顯示DS18B20 OK,第二行顯示序列碼,如果讀取失敗,則在液晶上
        顯示DS18B20  ERR0R PLEASE CHECK ,用戶可通過更改18B20接口自己外接。 */
        #include <reg51.h>
        #include <intrins.h>

        #define uchar unsigned char
        #define uint  unsigned int

        sbit DQ = P2^2;  //定義DS18B20端口DQ 
        sbit BEEP=P2^3 ; //蜂鳴器驅動線

        bit  presence ;

        sbit LCD_RS = P3^5;            
        sbit LCD_RW = P3^6;
        sbit LCD_EN = P3^4;

        uchar code  cdis1[ ] = {"   DS18B20 OK   "};
        uchar code  cdis2[ ] = {"                "};
        uchar code  cdis3[ ] = {" DS18B20  ERR0R "};
        uchar code  cdis4[ ] = {"  PLEASE CHECK  "};

        unsigned char data  display[2] = {0x00,0x00};
                                           
        unsigned char data  RomCode[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

        unsigned char Temp;
        unsigned char  crc;

        void beep();

        #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};

        /*******************************************************************/
        void delay1(int ms)
        {
         unsigned char y;
          while(ms--)
         {
          for(y = 0; y<250; y++)
          {
           _nop_();
           _nop_();
           _nop_();
           _nop_();
          }
         }
        }

        /******************************************************************/
        /*                                                                */
        /*檢查LCD忙狀態                                                   */
        /*lcd_busy為1時,忙,等待。lcd-busy為0時,閑,可寫指令與數據。     */
        /*                                                                */
        /******************************************************************/

        bit lcd_busy()
         {                         
            bit result;
            LCD_RS = 0;
        LCD_RW =0;
            LCD_EN = 1;
            delayNOP();
            result = (bit)(P0&0x80);
            LCD_EN = 0;
            return(result);
         }

        /*******************************************************************/
        /*                                                                 */
        /*寫指令數據到LCD                                                  */
        /*RS=L,RW=L,E=高脈沖,D0-D7=指令碼。                             */
        /*                                                                 */
        /*******************************************************************/

        void lcd_wcmd(uchar cmd)

        {                         
         //  while(lcd_busy());
            LCD_RS = 0;
          LCD_RW = 0;
            LCD_EN = 0;
            _nop_();
            _nop_();
            P0 = cmd;
            delayNOP();
            LCD_EN = 1;
            delayNOP();
            LCD_EN = 0; 
        delay1(5);
        }

        /*******************************************************************/
        /*                                                                 */
        /*寫顯示數據到LCD                                                  */
        /*RS=H,RW=L,E=高脈沖,D0-D7=數據。                               */
        /*                                                                 */
        /*******************************************************************/

        void lcd_wdat(uchar dat)
        {                         
        //   while(lcd_busy());
            LCD_RS = 1;
        LCD_RW = 0;
            LCD_EN = 0;
            P0 = dat;
            delayNOP();
            LCD_EN = 1;
            delayNOP();
            LCD_EN = 0;
        delay1(5);
        }

        /*******************************************************************/
        /*                                                                 */
        /*  LCD初始化設定                                                  */
        /*                                                                 */
        /*******************************************************************/

        void lcd_init()
        {
            delay1(15);  
            lcd_wcmd(0x01);      //清除LCD的顯示內容
                   
            lcd_wcmd(0x38);      //16*2顯示,5*7點陣,8位數據
            delay1(5);
            lcd_wcmd(0x38);        
            delay1(5);
            lcd_wcmd(0x38);        
            delay1(5);

            lcd_wcmd(0x0c);      //顯示開,關光標
            delay1(5);
            lcd_wcmd(0x06);      //移動光標
            delay1(5);
            lcd_wcmd(0x01);      //清除LCD的顯示內容
            delay1(5);
        }

        /*******************************************************************/
        /*                                                                 */
        /*  設定顯示位置                                                   */
        /*                                                                 */
        /*******************************************************************/

        void lcd_pos(uchar pos)
        {                         
          lcd_wcmd(pos | 0x80);  //數據指針=80+地址變量
        }

        /*******************************************************************/
        /*                                                                 */
        /*us級延時函數                                                     */
        /*                                                                 */
        /*******************************************************************/

        void Delay(unsigned int num)
        {
          while( --num );
        }

        /*******************************************************************/
        /*                                                                 */
        /*初始化ds1820                                                     */
        /*                                                                 */
        /*******************************************************************/
        Init_DS18B20(void)

             DQ = 1;      //DQ復位
             Delay(8);    //稍做延時

             DQ = 0;      //將DQ拉低
             Delay(90);   //精確延時 大于 480us

             DQ = 1;       //拉高總線
             Delay(8);

             presence = DQ;    //讀取存在信號
             Delay(100);
             DQ = 1;
            
             return(presence); //返回信號,0=presence,1= no presence
        }

        /*******************************************************************/
        /*                                                                 */
        /* 讀一位(bit)                                                   */
        /*                                                                 */
        /*******************************************************************/
        uchar read_bit(void)
        {
        unsigned char i;
        DQ = 0;     //將DQ 拉低開始讀時間隙
        DQ = 1; // then return high
        for (i=0; i<3; i++); // 延時15μs
        return(DQ); // 返回 DQ 線上的電平值
        }

        /*******************************************************************/
        /*                                                                 */
        /* 讀一個字節                                                      */
        /*                                                                 */
        /*******************************************************************/
         ReadOneChar(void)
        {
        unsigned char i = 0;
        unsigned char dat = 0;

        //for (i = 8; i > 0; i--)
        //  {
        //   read_bit();
        //    DQ = 0; // 給脈沖信號
        //     dat >>= 1;
        //    DQ = 1; // 給脈沖信號
        for (i=0;i<8;i++)
        {   // 讀取字節,每次讀取一個字節
        if(read_bit()) dat|=0x01<<i;   // 然后將其左移

        //    if(DQ)
        //     dat |= 0x80;
            Delay(4);
          }

            return (dat);
        }

        /*******************************************************************/
        /*                                                                 */
        /* 寫一位                                                          */
        /*                                                                 */
        /*******************************************************************/
        void write_bit(char bitval) {
        DQ = 0;       // 將DQ 拉低開始寫時間隙
        if(bitval==1) DQ =1; // 如果寫1,DQ 返回高電平
        Delay(5);      // 在時間隙內保持電平值,
        DQ = 1;             // Delay函數每次循環延時16μs,因此delay(5) = 104μs

        /*******************************************************************/
        /*                                                                 */
        /* 寫一個字節                                                      */
        /*                                                                 */
        /*******************************************************************/
         WriteOneChar(unsigned char dat)
        {
          unsigned char i = 0;
          unsigned char temp;
        //  for (i = 8; i > 0; i--)
        //  {
           for (i=0; i<8; i++) // 寫入字節, 每次寫入一位
           {
        //    DQ = 0;
        //    DQ = dat&0x01;
        //    Delay(5);

        //    DQ = 1;
           temp = dat>>i;
           temp &= 0x01;
           write_bit(temp);
        //    dat>>=1;
          
          }
          Delay(5);
        }

        /*******************************************************************/
        /*                                                                 */
        /* 讀取64位序列碼                                                  */
        /*                                                                 */
        /*******************************************************************/
         Read_RomCord(void)
        {
             unsigned char j;
             Init_DS18B20();
         
             WriteOneChar(0x33);  // 讀序列碼的操作
             for (j = 0; j < 8; j++)
        {
         RomCode[j] = ReadOneChar() ;
        }
        }

        /*******************************************************************/
        /*                                                                 */
        /*DS18B20的CRC8校驗程序                                            */
        /*                                                                 */
        /*******************************************************************/
        uchar CRC8()
        {
           uchar i,x; uchar crcbuff;
          
           crc=0;
           for(x = 0; x <8; x++)
           {
            crcbuff=RomCode[x];
            for(i = 0; i < 8; i++)
             {
              if(((crc ^ crcbuff)&0x01)==0)
              crc >>= 1;
               else {
                      crc ^= 0x18;   //CRC=X8+X5+X4+1
                      crc >>= 1;
                      crc |= 0x80;
                    }        
              crcbuff >>= 1;      
        }
           }
             return crc; 
        }
        /*******************************************************************/
        /*                                                                 */
        /* 數據轉換與顯示                                                  */
        /*                                                                 */
        /*******************************************************************/

         Disp_RomCode()
        {
           uchar j;
           uchar H_num=0x40;       //LCD第二行初始位置

           for(j=0;j<8;j++)
           {
            Temp = RomCode[j];

            display[0]=((Temp&0xf0)>>4);
            if(display[0]>9)
             { display[0]=display[0]+0x37;}
            else{display[0]=display[0]+0x30;}

            lcd_pos(H_num);            
            lcd_wdat(display[0]);        //高位數顯示

            H_num++;
            display[1]=(Temp&0x0f);
            if(display[1]>9)
             {display[1]=display[1]+0x37;}
            else {display[1]=display[1]+0x30;}

            lcd_pos(H_num);            
            lcd_wdat(display[1]);        //低位數顯示
            H_num++;
           }

        /*******************************************************************/
        /*                                                                 */
        /* 蜂鳴器響一聲                                                    */
        /*                                                                 */
        /*******************************************************************/
        void beep()
          {
            unsigned char y;
            for (y=0;y<100;y++)
            {
              Delay(60);
              BEEP=!BEEP;                //BEEP取反
            }
            BEEP=1;                      //關閉蜂鳴器
        Delay(40000);
          }

        /*******************************************************************/
        /*                                                                 */
        /* DS18B20 OK 顯示菜單                                             */
        /*                                                                 */
        /*******************************************************************/
        void  Ok_Menu ()
        {
            uchar  m;
            lcd_init();                //初始化LCD
                   
            lcd_pos(0);                //設置顯示位置為第一行的第1個字符
             m = 0;
            while(cdis1[m] != '\0')
             {                         //顯示字符
               lcd_wdat(cdis1[m]);
               m++;
             }

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

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

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

        /*******************************************************************/
        /*                                                                 */
        /* 主函數                                                          */
        /*                                                                 */
        /*******************************************************************/
        void main()
         {
             P0 = 0xff;
             P2 = 0xff;

           while(1)
          {
             Ok_Menu ();
             Read_RomCord();    //讀取64位序列碼
             CRC8();            //CRC效驗
             if(crc==0)         //CRC效驗正確
        {
         Disp_RomCode(); //顯示64位序列碼
           beep();
             }
             while(!presence)
        {
         Init_DS18B20();
         delay1(1000);
        }

             Error_Menu ();
        do

          Init_DS18B20();
          beep();
             }
        while(presence);
          }
        }

        /*******************************************************************/

        關閉窗口

        相關文章

        欧美性色欧美精品视频,99热这里只有精品mp4,日韩高清亚洲日韩精品一区二区,2020国自产拍精品高潮