⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ds18b20.c

📁 MSP430单片机的DS18B20程序,自动识别ID号,可同时管理5个DS18B20,非常好用
💻 C
📖 第 1 页 / 共 2 页
字号:
    *PB >>= 1;
    if (DATA & 0X80) *PA |= 0X80;
    else *PA &= 0X7F;
    if (DATA & 0X01) *PB |= 0X80;
    else *PB &= 0X7F;
  }
//****************************************************************************
//模块名:CRC_Verify
//编写者:liukang
//描述:  CRC校验子程序。
//功能:  
//版本:  1.0
//修改:  2006年05月12日
//****************************************************************************
const unsigned char CRC_H[16] =
  {0x00,0x9d,0x23,0xbe,0x46,0xdb,0x65,0xf8,0x8c,0x11,0xaf,0x32,0xca,0x57,0xe9,0x74};
const unsigned char CRC_L[16] =
  {0x00,0x5e,0xbc,0xe2,0x61,0x3f,0xdd,0x83,0xc2,0x9c,0x7e,0x20,0xa3,0xfd,0x1f,0x41};

unsigned char CRC_Verify(unsigned char * buf,unsigned char length)
  {
    unsigned char crc = 0x00;
    do
      {
        crc ^= *buf;
        crc = CRC_H[crc >> 4] ^ CRC_L[crc & 0x0f];
        buf++;
      }
    while(--length);
    return(crc);                
  }
//****************************************************************************
//模块名:Search_ROM
//编写者:liukang
//描述:  搜索ds18b20的地址子程序。
//功能:  
//版本:  1.0
//修改:  2006年05月12日
//****************************************************************************
void Search_ROM (void)
  {
    unsigned char A[8],B[8];               //A[8]为已知ID中最大的ID值,B[8]节点表
    unsigned char POINT0,POINT;            //POINT0指向上次检索的最后一个节点位置;
                                        //POINT指向当前节点位置;
    unsigned char I,J,K;                   //I,J为循环计数器;K为检索失败次数
    unsigned char DATA,CRC;
    unsigned char *PA,*PB;

    PA = &A[0];
    PB = &B[0];

    J = 0xFF;
    FLAG |= FLAG_TEMP_OK;                  //预设传感器正常
    I = 5;                                 //
    while ((I != 0) && ~(FLAG & FLAG_TEMP_RET))
      {
        Rst_DS18B20();            //传感器复位,复位成功或5次复位失败跳出循环
        I--;
      }
    if (FLAG && FLAG_TEMP_RET)
      {                                   //复位成功,开始搜索ds18b20的地址
        for (I = 0 ; I <8 ; I++)
          {
            A[I] = 0;                        //已知ID中最大的ID值"0"
            B[I] = 0;                        //所有节点都未处理
          }
        POINT0 = 63;
        POINT = 0XFF;
        K = 0;
        for (J = 0 ; (J<5 && K<5 && POINT != 0) ; J++)
          {
            Rst_DS18B20();                      //传感器复位
            Write_BUS_Byte (0XF0);            //写搜索ID命令
            POINT = 0;
            FLAG &= ~FLAG_TEMP_OVER;
            for (I = 0 ; ((I < 64) && ~(FLAG & FLAG_TEMP_OVER)) ; I++)
              {
                Right_Move_Temp(PA,PB);         //循环右移
                DATA = Read_BUS_2bit();         //读ds18b20两位
                switch (DATA &= 0XC0)
                  {
                    case 0:                       //读数为“0”,此位为一节点
                      {
                        if (B[0] & 0X80)
                          {                           //本节点已处理
                            DATA = 0XFF;
                            A[7] |= 0X80;               //地址表写"1"
                          }
                        else
                          {                           //本节点未处理
                            if (I == POINT0)
                              {                        //当前节点是最后的未处理节点
                                DATA = 0XFF;
                                A[7] |= 0X80;            //地址表写"1"
                                B[0] |= 0X80;            //节点表写"1"
                              }
                            else
                              {
                                A[7] &= ~0X80;           //地址表写"0"
                                POINT = I;               //设置节点指针
                              }
                          }
                        DATA = Write_BUS_bit (DATA);  //选择方向
                      }
                    break;
                    case 0X80:
                      {
                        DATA = 0X00;
                        DATA = Write_BUS_bit (DATA);  //写"0"
                        A[7] &= ~0X80;
//                      B[0] &= ~0X80;
                      }
                    break;
                    case 0X40:
                      {
                        DATA = 0X0F;
                        DATA = Write_BUS_bit (DATA);  //写"1"
                        A[7] |= 0X80;
//                      B[0] &= ~0X80;
                      }
                    break;
                    case 0XC0:
                      {
                        FLAG |= FLAG_TEMP_OVER;
                      }
                    break;
                    default:
                    break; 
                  }
              }                                   //I循环结束
            if(!(FLAG & FLAG_TEMP_OVER))
              {
                CRC = CRC_Verify(PA,7);
                if (CRC == A[7])
                  {
                    for (I=0; I<8; I++) ID[J][I] = A[I];
                    POINT0 = POINT;
                    K = 0;
                  }
                else 
                  {
                    J--;
                    K++;
                  }
              }
          }                                     //J循环结束
        TEMP_NUMBER = J;
      }
    else
      {                     //复位失败,置失败标志
        FLAG &= FLAG_TEMP_OK;
      }
  }
//****************************************************************************
//模块名:Read_Temp
//编写者:liukang
//描述:  读温度子程序。
//功能:  
//版本:  1.0
//修改:  2006年05月12日
//****************************************************************************
void Read_Temp (void)
  {
 
    unsigned char I,J,DATA,CRC;
    unsigned char ROM[9];
    unsigned char *PA;
    Rst_DS18B20();          //温度传感器复位
    if ((TEMP_NUMBER > 0) && (FLAG && FLAG_TEMP_RET))
      {                //温度传感器数量>0并且复位正常
        Write_BUS_Byte (0xcc);      //写"跳过"命令
        Write_BUS_Byte (0x44);      //写"读温度"命令
        DATA = 0;
        I = 0XFF;
        while ((DATA != 0XFF) && (I>0))
          {                    //循环等待温度转换结束
            DATA = Read_BUS_Byte();
            I--;
          }
        for (I=0; I<TEMP_NUMBER; I++)
          {
            PA = ROM;
            Rst_DS18B20();
            Write_BUS_Byte (0x55);   //写"匹配温度传感器"命令
            for (J=0; J<8; J++)      //写温度传感器地址
              {
                Write_BUS_Byte (ID[I][J]);
              }
            Write_BUS_Byte (0xbe);  //写"读存储器"命令
            for (J=0; J<9; J++)
              {
                ROM[J] = Read_BUS_Byte();
              }
            CRC = CRC_Verify(PA,8);
            if (CRC == ROM[8])
              {
                PA =(unsigned char*)&TEMP[I];
                *PA = ROM[0];
                *(PA+1) = ROM[1]; 
              }
          }     //I循环结束
      }
  }

//****************************************************************************
//模块名:Temp
//编写者:liukang
//描述:  温度子程序。
//功能:  
//版本:  1.0
//修改:  2006年05月12日
//****************************************************************************
void Temp (void)
  {
    Rst_DS18B20 ();
    Search_ROM ();
    Read_Temp();
    _NOP();
  }
//****************************************************************************
//模块名:Delay
//编写者:liukang
//描述:  延时子程序。
//功能:  
//版本:  1.0
//修改:  2006年05月12日
//****************************************************************************
void Delay(unsigned int x)
  {
    while(x !=0)x--;
  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -