51单片机+DS18B20+数码管显示+串口通讯+Proteus仿真

51单片机+DS18B20+数码管显示+串口通讯+Proteus仿真


✨本实验通过51单片机读取DS18B20温度传感器的温度,然后通过数码管显示,并通过串口,将读取到的温度数据发送出去。

  • 📺Proteus演示
    在这里插入图片描述
✨注意不要使用Proteus 8 Professional 8.13版本串口通信会出错。
  • 🔨本案例需要使用到虚拟串口工具,事先创建好2个虚拟串口。(Virtual Serial Port Driver
    在这里插入图片描述
  • 🔖软件界面配置好后,在电脑设备管理器里面可以看到2个虚拟端口号
    在这里插入图片描述

⛳Proteus设置注意事项

  1. 设置AT89C52的晶振频率为11.0582MHz,默认是12MHz,如果是12MHz,虚拟串口打印的数据会是乱码。
  2. 设置虚拟串口监视器的波特率为9600,两个都是。
  3. COMPIM元器件的设置也是同样,波特率为9600,配置好串口端口号
    在这里插入图片描述
  • 串口工具界面设置
    在这里插入图片描述

📝实例代码

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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*例程\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\* 平台:AT89C52RC + Keil U5
\* 名称:18b20温度显示(数码管)实验
\* 晶振:11.0592MHZ
\* 实验效果:接上18B20温度传感器数码管显示出当前温度
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
#include <reg52.h>
#include<stdio.h>

#define uchar unsigned char
#define uint unsigned int
#define dula P0 //段选信号的锁存器控制
sbit wei1=P2^4;
sbit wei2=P2^5;
sbit wei3=P2^6;
sbit wei4=P2^7;
sbit DS=P2^2; //define interface
uint temp; // variable of temperature

unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
unsigned char code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,
0x87,0xff,0xef};

void delay(uint count) //delay
{
uint i;
while(count)
{
i=200;
while(i>0)
i--;
count--;
}
}


void dsreset(void) //send reset and initialization command
{
uint i;
DS=0;
i=103; //将总线拉低480us~960us
while(i>0)i--;
DS=1; //然后拉高总线,若DS18B20做出反应会将在15us~60us后将总线拉低
i=4; //15us~60us等待
while(i>0)i--;
//while(DS);
}

bit tmpreadbit(void) //read a bit
{
uint i;
bit dat;
DS=0;i++; //i++ for delay
DS=1;i++;i++;
dat=DS;
i=8;while(i>0)i--;
return (dat);
}

uchar tmpread(void) //read a byte date
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tmpreadbit();
dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里
}
return(dat);
}

void tmpwritebyte(uchar dat) //write a byte to ds18b20
{
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) //write 1
{
DS=0;
i++;i++;
DS=1;
i=8;while(i>0)i--;
}
else
{
DS=0; //write 0
i=8;while(i>0)i--;
DS=1;
i++;i++;
}

}
}

void tmpchange(void) //DS18B20 begin change
{
dsreset();
delay(1);
tmpwritebyte(0xcc); // address all drivers on bus
tmpwritebyte(0x44); // initiates a single temperature conversion
//delay(100);
}

uint tmp() //get the temperature
{
float tt;
uchar a,b;
dsreset();
delay(1);
tmpwritebyte(0xcc);
tmpwritebyte(0xbe);
a=tmpread();//低八位
b=tmpread();//高八位
temp=b;
temp<<=8; //two byte compose a int variable
temp=temp|a;
tt=temp\*0.0625; //算出来的是测到的温度,数值可到小数点后两位
temp=tt\*10+0.5; //为了显示温度后的小数点后一位并作出四舍五入,因为取值运算不能取小数点后的数
return temp;
}

void display(uint temp) //显示程序
{
uchar bai,shi1,shi0,ge;
bai=temp/100;//温度数值上为十位
shi0=temp%100;//温度数值上为几点几
shi1=shi0/10;//温度上为个位,并且显示时需要加小数点
ge=shi0%10;//温度上为小数位,并已经四舍五入

wei1=0; //显示百位
wei2=1;
wei3=1;
wei4=1;
P0=table[bai];
delay(2);

wei1=1; //显示十位
wei2=0;
wei3=1;
wei4=1;
P0=table1[shi1];
delay(2);

wei1=1; //显示个位
wei2=1;
wei3=0;
wei4=1;
P0=table[ge];
delay(2);
P0=0x00;//清屏,消隐作用
}

/\*------------------------------------------------
串口初始化函数
------------------------------------------------\*/
void init\_com(void)
{
TMOD=0x20; //设T0为方式1,GATE=1;
SCON=0x50;//开启串口
TH1=0xFD;//波特率是9600bps
TL1=0xFD;
TR1=1; //开启定时器
TI=1;
EA=1; //开启总中断
}
void main()
{
// uchar a;
uint temp = 0; //温度
float ftemp = 0.0f;
init\_com();
do
{
tmpchange();//让18b20开始转换温度
temp = tmp();
// for(a=100;a>0;a--)
// {
// display(temp);
// }
display(temp);
ftemp = temp/10.0f;
printf("$51,TMS%3.1f#", ftemp);
}while(1);
}



📚源码资源

1
2
3
链接:https://pan.baidu.com/s/1-zG6h71ChJa-JQY5Caxnsg 
提取码:sicm