【Proteus仿真】51单片机 + LM35多路温度采集+ADC0832+DS18B20环境报警监测

【Proteus仿真】51单片机 + LM35多路温度采集+ADC0832+DS18B20环境报警监测


  • 📺Proteus仿真

在这里插入图片描述

📝主程序代码

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
#include "LCD1602.H"
#include "DS18B20.h"
#include "ADC0832.h"

extern unsigned char ReadAdc0832(unsigned char channel);
extern void DelayMs(unsigned char t);
unsigned int Temp[5];//5路温度值温度放大10倍
int DS18B20DATA[3];//DS18B20读到的16位数据
code unsigned char DecimalNum[16]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};//DS18B20小数部分对应的数
unsigned char code DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
sbit LED=P3^1;
sbit BEEP=P3^2;
sbit LE=P3^0;
sbit Key=P1^0;
unsigned char CurID;
// 显示段码值01234567
unsigned char LCDbuf[16];
void LM35Read(void)
{
Temp[0]=ReadAdc0832(0)\*10;
DelayMs(10);
Temp[1]=ReadAdc0832(1)\*10;
DelayMs(10);
}
void DS18B20Read()
{
gettemp(DS18B20DATA);
Temp[2]=(DS18B20DATA[0]>>4)\*10+DecimalNum[DS18B20DATA[0]&0x0f];
Temp[3]=(DS18B20DATA[1]>>4)\*10+DecimalNum[DS18B20DATA[1]&0x0f];
Temp[4]=(DS18B20DATA[2]>>4)\*10+DecimalNum[DS18B20DATA[2]&0x0f];//环境温度
}

//格式化数据
void ForamtData(int Data,unsigned char \*Str)
{
unsigned char t;
t=Data/10;
if(t>99)
{
\*Str++='1';
\*Str++=(t%100)/10+0x30;
\*Str++=(t%10)+0x30;
\*Str++='.';
\*Str++=Data%10+0x30;
}
if((t>9)&&(t<100))
{
\*Str++=' ';
\*Str++=t/10+0x30;
\*Str++=(t%10)+0x30;
\*Str++='.';
\*Str++=Data%10+0x30;
}
if((t<10)&&(t>0))
{
\*Str++=' ';
\*Str++=' ';
\*Str++=(t%10)+0x30;
\*Str++='.';
\*Str++=Data%10+0x30;
}
if(t==0)
{
\*Str++=' ';
\*Str++=' ';
\*Str++=' ';
\*Str++='.';
\*Str++=Data%10+0x30;
}
\*Str=0;
}
//报警
void Warning(void)
{
unsigned char flag;//,//i;
static unsigned int a,b;
flag=0;
a=Temp[4]+50;
b=Temp[4]-50;
//for(i=0;i<5;i++)
//{
flag=(Temp[CurID]>(a));
flag=(Temp[CurID]<b)||flag;
BEEP=!flag;
LED=!flag;
//}

}
void main(void)
{
LE=1;

P0=DuanMa[CurID+1];
LE=0;
LCD\_Init();
LCD\_Write\_String(0,0,"Envir: C");
LCD\_Write\_String(5,1,"C ");
LED=0;
CurID=3;
while(1)
{
LM35Read();
DS18B20Read();
LE=1;
P0=DuanMa[CurID+1];
LE=0;
ForamtData(Temp[4],LCDbuf);
LCD\_Write\_String(6,0,LCDbuf);
ForamtData(Temp[CurID],LCDbuf);
LCD\_Write\_String(0,1,LCDbuf);
Warning();
if(Key==0)
{
DelayMs(10);
if(Key==0)
CurID=(CurID+1)%4;
while(Key==0);
}
// DelayMs(100);
}
}

📝ADC0832驱动代码

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
#include "ADC0832.h"

/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\*\* 函数名 :ADC0832读数据程序
\*\* 入口 :需转换通道channel [0:1]
\*\* 返回 : 无符号字符型 uchar
\*\* 例子 : Data\_adc = ReadAdc0832( 0 ); //读取adc0832芯片的0通道模拟电压
\*\* 说明 : 使用时请在芯片加上精准电压源, 建议用专用芯片
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
//工作时序
//当cs由高变低时,选中ADC0832。在时钟的上升沿,DI端的数据移入ADC0832内部的多路地址移位寄存器。
//在第一个时钟期间,Dl为高,表示启动位,紧接着输入两位配置位。当输入启动位和配置位后,选通输入模拟通道,转换开始。
//转换开始后,经过一个时钟周期延迟,以使选定的通道稳定。ADC0832接着在第4个时钟下降沿输出转换数据。
//数据输出时先输出最高位(D7~DO);输出完转换结果后,又以最低位开始重新输出一遍数据(D7~DO),两次发送的最低位共用。当片选cS
//为高时,内部所有寄存器清0,输出变为高阻态。如果要再进行一次模傲转换,片选cs必须再次从高向低跳变,后面再输入启动位和配置位
//adc0832读数据
unsigned char ReadAdc0832(unsigned char channel)
{
unsigned char i = 0;
unsigned char outdata = 0;
//初始化: 选通 数据口保持高电平
//当cs由高变低时,选中ADC0832。在时钟的上升沿,DI端的数据移入ADC0832内部的多路地址移位寄存器
ADC0832_CS_L; // 使能
ADC0832_DIDO_H; //
ADC0832_SCK_L; //第一次触发
\_nop\_();
\_nop\_();
ADC0832_SCK_H; //
\_nop\_();
\_nop\_();

//模拟通道的选择及单端输入和差分输入的选择
ADC0832_DIDO_H;
ADC0832_SCK_L; //第二次触发
\_nop\_();
\_nop\_();
ADC0832_SCK_H;
\_nop\_();
\_nop\_();

if(channel==1)
{
ADC0832_DIDO_H;
}

else
{
ADC0832_DIDO_L;
}
ADC0832_SCK_L; //第三次触发
\_nop\_();
\_nop\_();
ADC0832_SCK_H;
\_nop\_();
\_nop\_();


ADC0832_SCK_L;
\_nop\_();
\_nop\_();
ADC0832_DIDO_H; //置为输入准备读数据
ADC0832_SCK_H;
\_nop\_();
\_nop\_();
outdata = 0; //初始化

//读数据D7~D0
for( i = 1; i <= 8; i++ )
{
if( ADC0832_DIDO == 1 )
{
outdata |= 0x01;
}
ADC0832_SCK_H;
ADC0832_SCK_L;
outdata = outdata << 1; //左移一位
}
//此函数不再读数据D0~D7 (注意D0位重叠)
ADC0832_CS_H; //禁止
return outdata;
}

📚程序源码和仿真资源(更新日期:2023-4-13)

1
2
3
4

链接: https://pan.baidu.com/s/1EjbGzIMwJ4\_JSKvqzK51YA
提取码: 2ag2