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

📄 ds1820.c

📁 上载的程序可以用于PIC单片机,也可以用于430单片机,本人原创,到至今还没有发现哪位网友想出这种办法,希望站长能多加分.
💻 C
字号:
//文件名:DS18B20.c
#define uchar unsigned char
#define uint unsigned int

#define  XF_MCU    1       //定义用哪一种单片机,1时,用于PIC; 0时,用于MSP430;

#if      XF_MCU==0
#include <msp430x14x.h>
#include "DS1820.h"
#else
#include <pic.h>
#include "DS1820.h"
uchar pa_out;
uchar pb_out;
uchar pc_out;
uchar pd_out;
uchar pe_out;
#endif

const unsigned char digit[10] = {'0','1','2','3','4','5','6','7',
 '8','9'};

 unsigned char temp_display [9] = {'x','0','0','0','.','0','0','0','\0'};


//定义
unsigned char Error = 0;
float   Temper=0.0;             //真正有效温度值
int     temperature=0;          //读取两字节温度数据
unsigned char symbol = 1 ;      //温度正负符号

//----------------------------------
//功能:us 级别延时
// n=10,则延时10*5+6=56uS
//----------------------------------
void DelayNus(unsigned int n)
 {
    while(n--){};
 }
//-----------------------------------


//功能:写18B20
//-----------------------------------
void Write_18B20(unsigned char n)
{
    unsigned char i;
    for(i=0;i<8;i++)
    {
        DQ0;
        _NOP();_NOP();            //延时5us
        _NOP();_NOP();_NOP();
        if((n&0X01)==0X01)      //DQ=1
          DQ1;
        else 
         DQ0;                   //DQ=0     
        n=n>>1;                  //下一位
        DelayNus(6);            //延时50us 以上
        DQ1;
    }
}
//------------------------------------


//功能:读取18B20
//------------------------------------
unsigned char Read_18B20(void)
{
    unsigned char i;
    unsigned char temp;
    for(i=0;i<8;i++)
    {
        temp=temp>>1;            //移向下一位
        DQ0;                  
        _NOP();                  //延时1us
        DQ1;
        _NOP();_NOP();            //延时5us
        _NOP();     
        
        DQIO_IN;            //DQ口设为输入
      if((DS_IN&DS_IT)==0)      //DQ是否等于0
          {
            temp=temp&0x7F;      //读入DQ为0
          }
      else
        {
         temp=temp|0x80;      //读入DQ为1
        }

      DelayNus(5);            //延时40us
      DQIO_OUT;                    //DQ口设为输出
      DQ1;                  //DQ输出1
    }
    return    temp;            //返回一个数据
}
//-----------------------------------


//复位说明:复位要求主CPU将数据线下拉500us,然后释放,
//当DS18B20收到信号后等待16~60us左右,后发出60~240微秒的存在低脉冲,
//主CPU收到此信号表示复位成功。 
//初始化DS18B20
void Init (void)
{
    DQ0;                  
    DelayNus(50);            //延时500us
    DQ1;
    DelayNus(12);            //延时16~60us

    DQIO_IN;                    //设DQ为输入
    if((DS_IN&DS_IT)==DS_IT)        //1000 0000b=1f,DQ是否为1
     {
      Error =1;                //失败1
      DQIO_OUT;                    //设DQ为输输出
     }
    else
     {
      Error = 0;            //初始化成功
      DQIO_OUT;                    //设DQ为输输出
      DQ1;
     }
}
//----------------------------------

//指令描述:跳过ROM命令,指定代码为CCH,忽略64位ROM地址,直接向DS1820发温度变换
//命令,适用于单片机工作.
void Skip(void)
{
    Write_18B20(0xcc);
}
//----------------------------------

//指令描述:温度转换命令,指定代码为44H.启动DS1820进行温度转换,12位转换时最长
//为750ms(9位为93.75ms).结果存入内部9字节RAM中.
 void Convert (void)
 {
    Write_18B20(0x44);
  }
//----------------------------------

//指令描述:读暂存器,指定代码为BEH.读内部RAM中9字节的内容.
  void ReadDo (void)
  {
    Write_18B20(0xbe);
  }
//----------------------------------

//读取温度值
void ReadTemp (void)
 {
    char temp_low,  temp_high;      //温度值
    temp_low = Read_18B20();      //读低位
    temp_high = Read_18B20();      //读高位
    
    if((temp_high|positive)==positive)
        symbol=1;                //测到的温度为正
    else
        symbol=0;                //测到的温度为负
    
    temperature=(temp_high&0x0f);//屏蔽高4位
    temperature<<=8;            //将temp_high部分数据移到temperature高8位
    temperature|=temp_low;      //将高低两字节内部合并成一个16位数据
    
    if(symbol==0)                       //是否为负温度
     { temperature = (~temperature)+1;   //将其取反后加1
     }
    Temper=temperature*0.0625;      //计算真实温度值
 }
//----------------------------------

//MCU对DS18B20进行温度转换时,其操作必须满足以下过程:
// 1- 每一次读写之前都要对DS18B20进行复位.
// 2- 完成复位后发送一条ROM命令到DS18B20.
// 3- 最后发送一条RAM命令到DS18B20.
// 以上系列动作是根据DS18B20的通讯协议所得.
//读取温度
void GetTemp(void)
 {
        Init();                  //DS1820初始化
        Skip();                  //跳过64位ROM(ROM命令)
        Convert();            //转换(RAM命令)
        DelayNus(60000);        //60000x5us=0.3s
        DelayNus(60000);        //0.3s
        DelayNus(60000);      //0.3s
        Init();                  //DS1820初始化
        Skip();                  //跳过64位ROM
        ReadDo();            //读暂存器
        ReadTemp();            //读取温度值
 }
//END--------------------------------------------------------------

 //另外,由于MSP430F14与44的DCO时钟有所不同,各位如要引用DS18B20程序时请加于注意操作时序。
 //引用时可能出现过复位不成功或读到全为FF...
 //这些大部分都是由于程序上的时序不能满足DS18B20所至。
 //以下关于14与4系列的DCO默认时钟:
 //4系列默认时钟  ACLK = LFXT1 = 32768Hz, MCLK = SMCLK = DCO = 32xACLK = 1048576Hz时钟周期为0.95us
 //14系列默认时钟 ACLK= n/a, MCLK= SMCLK= default DCO ~800k   时钟周期为1.25us
  
 


//MC430F14 DS18B20实验主程序
void main(void)
 {
#if  XF_MCU==0
  WDTCTL=WDTPW+WDTHOLD;         //停止WDT
  mcuinit();                  //MSP430F14初始化
#else
	LCM141_DIR_OUT;
#endif 
  while(1)
  {
   GetTemp();                                     //读取温度
  
   display_number(Temper);                      //数据变换
   ;
  } 
 }


//将温度值转换成可显示十进制值
//取数范围整数3位,小数点后3位.
void display_number(float f_data)
{ unsigned long value;
  float n;
  n=f_data *1000;
  value = (unsigned long int)n; 
  
  temp_display[1] = digit[value/100000];          //100位
  value = value%100000;
  
  temp_display[2] = digit[value/10000];           //10位
  value = value%10000;   
  
  temp_display[3] = digit[value/1000];            //1位
  value = value%1000; 
  
  temp_display[5] = digit[value/100];             //0.1位
  value = value%100; 

  temp_display[6] = digit[value/10];              //0.01位
  value = value%10; 
  
  temp_display[7] = digit[value/1];               //0.001位
}
//--------------------------------------------------------------------


//---------------------------------------------------------------------

//MSP430F14初始化
void mcuinit(void)
 {
   DQIO_OUT;                                  //设为输出
   DQ1;                                       //输出高电平;
 }

//---------------------------------------------------------------------

⌨️ 快捷键说明

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