11.0592MHz的51单片机和DS18B20和ADC1602,实现温度采集显示,显示格式为WD:温度值带摄氏度单位,编写代码并详细注释
时间: 2023-12-20 22:06:33 浏览: 83
好的,以下是代码和注释:
```c
#include<reg51.h> // 引入51单片机寄存器定义
#define DQ P3_4 // 定义DS18B20数据线引脚
#define RS P0_0 // 定义LCD1602数据线引脚
#define RW P0_1
#define EN P0_2
typedef unsigned char uchar; // 定义无符号字符类型
sbit ADC_CS = P1^0; // 定义ADC1602转换片选引脚
// 函数声明
void Delay1ms();
void Delay(unsigned int t);
uchar DS18B20Init();
void DS18B20WriteByte(uchar dat);
uchar DS18B20ReadByte();
void DispString(uchar x, uchar y, uchar *s);
void DispTemp(uchar x, uchar y, uchar temp);
void ADCInit();
uchar ADCRead(uchar ch);
void main()
{
uchar temp;
uchar str[6]; // 定义字符数组,用于存放温度值和单位字符
ADCInit(); // 初始化ADC1602
while(1)
{
if(DS18B20Init()) // 如果DS18B20初始化成功
{
DS18B20WriteByte(0xcc); // 发送跳过ROM操作命令
DS18B20WriteByte(0x44); // 发送温度转换命令
Delay(500); // 等待转换完成
DS18B20Init(); // 再次初始化DS18B20,准备读取温度
DS18B20WriteByte(0xcc); // 发送跳过ROM操作命令
DS18B20WriteByte(0xbe); // 发送读取温度命令
temp = DS18B20ReadByte(); // 读取温度值
sprintf(str, "WD:%dC", temp); // 将温度值和单位字符存放到字符数组中
DispString(0, 0, str); // 在LCD1602第一行显示温度值
temp = ADCRead(0); // 读取ADC1602的电位器值作为亮度值
Delay(10); // 延时
}
}
}
// DS18B20初始化函数
uchar DS18B20Init()
{
uchar i;
DQ = 1; // 先将数据线拉高
Delay1ms();
DQ = 0; // 拉低数据线
Delay(500); // 延时480us~960us
DQ = 1; // 再次拉高数据线
Delay1ms();
i = DQ; // 读取DS18B20的应答信号
Delay(500); // 延时480us~960us
return i; // 返回应答信号,1表示初始化成功,0表示失败
}
// DS18B20写入一个字节数据函数
void DS18B20WriteByte(uchar dat)
{
uchar i;
for(i = 0; i < 8; i++)
{
DQ = 0; // 先将数据线拉低
Delay1ms();
DQ = dat & 0x01; // 发送数据位
Delay(60); // 延时60us
DQ = 1; // 拉高数据线
dat >>= 1; // 准备发送下一位数据
}
}
// DS18B20读取一个字节数据函数
uchar DS18B20ReadByte()
{
uchar i, dat = 0;
for(i = 0; i < 8; i++)
{
dat >>= 1; // 先右移一位
DQ = 0; // 拉低数据线
Delay1ms();
DQ = 1; // 再次拉高数据线
Delay(5); // 延时5us
if(DQ) // 判断是否接收到了数据位
dat |= 0x80; // 接收到了数据位,将最高位设为1
Delay(60); // 延时60us
}
return dat; // 返回读取到的字节数据
}
// 在LCD1602指定位置显示字符串函数
void DispString(uchar x, uchar y, uchar *s)
{
uchar i;
if(y == 0)
RS = 0;
else
RS = 1;
RW = 0;
EN = 1; // 使能LCD1602
P2 = 0x80 + x + y * 0x40; // 设置显示的位置
Delay1ms();
EN = 0; // 禁止LCD1602
Delay1ms();
for(i = 0; s[i] != '\0'; i++) // 逐个显示字符
{
if(y == 0)
RS = 1;
else
RS = 0;
RW = 0;
EN = 1; // 使能LCD1602
P2 = s[i]; // 设置显示的字符
Delay1ms();
EN = 0; // 禁止LCD1602
Delay1ms();
}
}
// 在LCD1602指定位置显示温度值函数
void DispTemp(uchar x, uchar y, uchar temp)
{
uchar str[6];
sprintf(str, "WD:%dC", temp); // 将温度值和单位字符存放到字符数组中
DispString(x, y, str); // 在LCD1602指定位置显示温度值
}
// ADC1602初始化函数
void ADCInit()
{
ADC_CS = 1; // 先将片选引脚拉高
}
// 读取ADC1602电位器值函数
uchar ADCRead(uchar ch)
{
uchar dat;
ADC_CS = 0; // 先将片选引脚拉低
P1 = 0x84 | (ch << 4); // 发送读取电位器值的命令
Delay(1); // 延时
dat = P1; // 读取电位器值
ADC_CS = 1; // 将片选引脚拉高
return dat; // 返回电位器值
}
// 1毫秒延时函数
void Delay1ms()
{
uchar i, j;
for(i = 4; i > 0; i--)
for(j = 110; j > 0; j--);
}
// 延时函数
void Delay(unsigned int t)
{
while(t--);
}
```
阅读全文