[51单片机]18B20驱动函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/**********DS18B20.h**********/
#include "REG52.H"
#include "INTRINS.H"
sbit DQ = P3^3; //DS18B20的数据口位P3.3
extern unsigned char TPH;//    温度高位
extern unsigned char TPL;//    温度低位
extern unsigned char * DS18B20_GetTP();// 刷新温度值(2xx为-xx)
  
 
  
 
/**********DS18B20.c**********/
#include <DS18B20.h>
typedef unsigned char BYTE;
  
BYTE TPH;                           //存放温度值的高字节
BYTE TPL;                           //存放温度值的低字节
  
void DelayXus(BYTE n);
void DS18B20_Reset();
void DS18B20_WriteByte(BYTE dat);
BYTE DS18B20_ReadByte();
  
BYTE* DS18B20_GetTP()
{
    BYTE TEMP[]="000C\n";
    unsigned int temp;
    signed int t;
    BYTE bai,shi,ge,shifen;
    DS18B20_Reset();                //设备复位
    DS18B20_WriteByte(0xCC);        //跳过ROM命令
    DS18B20_WriteByte(0x44);        //开始转换命令
    while (!DQ);                    //等待转换完成
  
    DS18B20_Reset();                //设备复位
    DS18B20_WriteByte(0xCC);        //跳过ROM命令
    DS18B20_WriteByte(0xBE);        //读暂存存储器命令
    TPL = DS18B20_ReadByte();       //读温度低字节
    TPH = DS18B20_ReadByte();       //读温度高字节     
         
    t=TPH<<8;
    t=t|TPL;
    if(t<0) temp=(~t+1)*0.0625*10+0.5; //负温度时,取反加1再乘以0.0625得实际温度,乘10+0.5显示小数点一位,且四舍五入
        else temp=t*0.0625*10+0.5;     //正温度
    if(t<0) bai='-'-48;                //负温度时百位显示负号
        else bai=(const) temp/1000;
    if(bai) TEMP[0]=bai+48; else TEMP[0]=' ';        //百位
    shi=((const) temp%1000)/100; TEMP[1]=shi+48;    //十位
    ge=((const) temp%1000)%100/10; TEMP[2]=ge+48;   //个位
    shifen=((const) temp%1000)%100%10;              //十分位  
         
    return  TEMP;
}
  
/**************************************
延时X*10微秒(STC90C52RC@12M)
不同的工作环境,需要调整此函数
当改用1T的MCU时,请调整此延时函数
**************************************/
void DelayX0us(BYTE n)
{
    while (n--)
    {
        _nop_();
        _nop_();
    }
}
  
/**************************************
复位DS18B20,并检测设备是否存在
**************************************/
void DS18B20_Reset()
{
    CY = 1;
    while (CY)
    {
        DQ = 0;                     //送出低电平复位信号
        DelayX0us(48);              //延时至少480us
        DQ = 1;                     //释放数据线
        DelayX0us(6);               //等待60us
        CY = DQ;                    //检测存在脉冲
        DelayX0us(42);              //等待设备释放数据线
    }
}
  
/**************************************
从DS18B20读1字节数据
**************************************/
BYTE DS18B20_ReadByte()
{
    BYTE i;
    BYTE dat = 0;
  
    for (i=0; i<8; i++)             //8位计数器
    {
        dat >>= 1;
        DQ = 0;                     //开始时间片
        _nop_();                    //延时等待
        _nop_();
        DQ = 1;                     //准备接收
        _nop_();                    //接收延时
        _nop_();
        if (DQ) dat |= 0x80;        //读取数据
        DelayX0us(6);               //等待时间片结束
    }
  
    return dat;
}
  
/**************************************
向DS18B20写1字节数据
**************************************/
void DS18B20_WriteByte(BYTE dat)
{
    char i;
  
    for (i=0; i<8; i++)             //8位计数器
    {
        DQ = 0;                     //开始时间片
        _nop_();                    //延时等待
        _nop_();
        dat >>= 1;                  //送出数据
        DQ = CY;
        DelayX0us(6);               //等待时间片结束
        DQ = 1;                     //恢复数据线
    }
}

  

posted @   honkly  阅读(1210)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示