📄 ds18b20.lst
字号:
C51 COMPILER V8.02 DS18B20 11/25/2008 22:06:04 PAGE 1
C51 COMPILER V8.02, COMPILATION OF MODULE DS18B20
OBJECT MODULE PLACED IN DS18B20.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE DS18B20.c BROWSE DEBUG OBJECTEXTEND
line level source
1 /*作者:史叔伍
2 完成日期:2008-10-16
3 程序实现功能:通过DS18B20读取温度(范围-55C~125C,精确到小数点后一位),通过4位数码管显示出来。
4 当温度为正且百位为零时,不显示,当温度为负时百位显负号。当温度百位和十位都为0时0都不显示。
5 */
6 #include<reg52.h>
7 #define uchar unsigned char
8 #define uint unsigned int
9 sbit DQ=P3^5; //数据口
10 uchar disdata[4];
11 uint tvalue; //温度值
12 uchar tflag; //温度正负标志
13 uchar code table[]=
14 {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, //0,1,2,3,4,5,6,7,8,9,
15 0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef //0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,
16 };
17
18 /* 延时t毫秒 */
19 void delay(uint t)
20 {
21 1 uint i;
22 1 while(t--)
23 1 {
24 2 /* 对于11.0592M时钟,约延时1ms */
25 2 for (i=0;i<125;i++)
26 2 {}
27 2 }
28 1 }
29
30 void display(uchar *disdata)
31 {
32 1 if(disdata[0]==0) //如果百位为0,不显示
33 1 {
34 2 if(tflag==1) //如果是负温度值,百位显负号
35 2 {
36 3 P1=0xf7;
37 3 P0=0x40;
38 3 delay(5);
39 3 }
40 2 else //温度为正,百位不显
41 2 {
42 3 P1=0xf7;
43 3 P0=0x00;
44 3 delay(5);
45 3 }
46 2 }
47 1 else
48 1 {
49 2 P1=0xf7;
50 2 P0=table[disdata[0]];
51 2 delay(5);
52 2 }
53 1 if(disdata[1]==0) //如果百位为0,十位为0也不显示
54 1 {
55 2 P1=0xfb;
C51 COMPILER V8.02 DS18B20 11/25/2008 22:06:04 PAGE 2
56 2 P0=0x00;
57 2 delay(5);
58 2 }
59 1 else
60 1 {
61 2 P1=0xfb;
62 2 P0=table[disdata[1]];
63 2 delay(5);
64 2 }
65 1 P1=0xfd;
66 1 P0=table[disdata[2]+10];
67 1 delay(5);
68 1 P1=0xfe;
69 1 P0=table[disdata[3]];
70 1 delay(5);
71 1
72 1 }
73
74 /* 产生复位脉冲初始化DS18B20 */
75 void TxReset(void)
76 {
77 1 uint i;
78 1 DQ = 0;
79 1
80 1 /* 拉低约900us */
81 1 i = 100;
82 1 while (i>0) i--;
83 1
84 1 DQ = 1; // 产生上升沿
85 1 i = 4;
86 1 while (i>0) i--;
87 1 }
88
89 /* 等待应答脉冲 */
90 void RxWait(void)
91 {
92 1 uint i;
93 1 while(DQ);
94 1 while(~DQ); // 检测到应答脉冲
95 1 i = 4;
96 1 while (i>0/*&DQ==0*/) i--;
97 1 }
98
99 /* 读取数据的一位,满足读时隙要求 */
100 bit RdBit(void)
101 {
102 1 uint i;
103 1 bit b;
104 1 DQ = 0;
105 1 i++;
106 1 DQ = 1;
107 1 i++;i++; // 延时15us以上,读时隙下降沿后15us,DS18B20输出数据才有效
108 1 b = DQ;
109 1 i = 8;
110 1 while(i>0) i--;
111 1 return (b);
112 1 }
113
114 /* 读取数据的一个字节 */
115 uchar RdByte(void)
116 {
117 1 uchar i,j,b;
C51 COMPILER V8.02 DS18B20 11/25/2008 22:06:04 PAGE 3
118 1 b = 0;
119 1 for (i=1;i<=8;i++)
120 1 {
121 2 j = RdBit();
122 2 b = (j<<7)|(b>>1); //从低位移向高位,一共16位,2个字节
123 2 }
124 1 return(b);
125 1 }
126
127 /* 写数据的一个字节,满足写1和写0的时隙要求 */
128 void WrByte(uchar b)
129 {
130 1 uint i;
131 1 uchar j;
132 1 bit btmp;
133 1 for(j=1;j<=8;j++)
134 1 {
135 2 btmp = b&0x01;
136 2 b = b>>1; // 取下一位(由低位向高位)
137 2 if (btmp)
138 2 {
139 3 /* 写1 */
140 3 DQ = 0;
141 3 i++;i++; // 延时,使得15us以内拉高
142 3 DQ = 1;
143 3 i = 8;
144 3 while(i>0) i--; // 整个写1时隙不低于60us
145 3 }
146 2 else
147 2 {
148 3 /* 写0 */
149 3 DQ = 0;
150 3 i = 8;
151 3 while(i>0) i--; // 保持低在60us到120us之间
152 3 DQ = 1;
153 3 i++;
154 3 i++;
155 3 }
156 2 }
157 1 }
158
159 /* 启动温度转换 */
160 void convert(void)
161 {
162 1 TxReset(); // 产生复位脉冲,初始化DS18B20
163 1 RxWait(); // 等待DS18B20给出应答脉冲
164 1 delay(1); // 延时
165 1 WrByte(0xcc); // skip rom 命令
166 1 WrByte(0x44); // convert T 命令
167 1 }
168
169 /* 读取温度值并转化 */
170 uchar RdTemp(void)
171 {
172 1 uchar tplsb,tpmsb; //温度值低位,高位字节
173 1 TxReset(); // 产生复位脉冲,初始化DS18B20
174 1 RxWait(); // 等待DS18B20给出应答脉冲
175 1 delay(1); // 延时
176 1 WrByte(0xcc); // skip rom 命令
177 1 WrByte(0xbe); // read scratchpad 命令
178 1 tplsb = RdByte(); // 温度值低8位字节(其中低4位为二进制的“小数”部分)
179 1 tpmsb = RdByte(); // 高位值高8位字节(其中高5位为符号位)
C51 COMPILER V8.02 DS18B20 11/25/2008 22:06:04 PAGE 4
180 1 tvalue=tpmsb;
181 1 tvalue<<=8;
182 1 tvalue=tvalue|tplsb;
183 1 if(tvalue<0x07ff)
184 1 tflag=0; //正温度
185 1 else
186 1 {
187 2 tvalue=~tvalue+1;
188 2 tflag=1; //负温度
189 2 }
190 1 tvalue=tvalue*(0.625); //温度值扩大10倍,精确到1位小数
191 1 return(tvalue);
192 1 }
193
194 /* 读取温度 */
195 void Pro()
196 {
197 1 disdata[0]=tvalue/1000;
198 1 disdata[1]=tvalue%1000/100;
199 1 disdata[2]=tvalue%100/10;
200 1 disdata[3]=tvalue%10;
201 1 }
202
203 /* 主程序,读取的温度值最终存放在tplsb和tpmsb变量中。
204 tplsb其中低4位为二进制的“小数”部分;tpmsb其中高
205 5位为符号位。真正通过数码管输出时,需要进行到十进
206 制有符号实数(包括小数部分)的转换。 */
207 void main(void)
208 {
209 1 do
210 1 {
211 2 uchar i;
212 2 delay(1); // 延时1ms
213 2 convert(); // 启动温度转换,需要750ms
214 2 for(i=0;i<50;i++) //循环显示防止数码管显示抖动
215 2 display(disdata);
216 2 RdTemp(); //读取温度值并转化
217 2 Pro(); // 读取温度
218 2 //display(disdata);
219 2 }
220 1 while(1);
221 1 }
222
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 607 ----
CONSTANT SIZE = 20 ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = 7 4
IDATA SIZE = ---- ----
BIT SIZE = ---- 2
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -