c51单片机ds18b20温度传感器完整代码及注释
时间: 2023-09-12 18:07:08 浏览: 283
下面是基于C51单片机的DS18B20温度传感器完整代码及注释:
```c
#include<reg52.h> // 引入51单片机头文件
#include<intrins.h>
typedef unsigned char uchar;
typedef unsigned int uint;
sbit DQ=P2^0; // DS18B20温度传感器数据线连接的单片机IO口
uchar code table[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67, // 共阴极数码管显示0~9
0x77,0x7c,0x39,0x5e,0x79,0x71
};
// 数码管显示字符的编码
void delay_us(uint i) // 延时us
{
while(i--);
}
void delay_ms(uint i) // 延时ms
{
uchar j;
while(i--)
{
for(j=0;j<110;j++);
}
}
uchar ds18b20_init() // 初始化DS18B20
{
uchar i;
DQ=1;
delay_us(15);
DQ=0;
delay_us(500);
DQ=1;
delay_us(30);
i=DQ; // 判断DS18B20是否存在
delay_us(500);
return i;
}
void ds18b20_write_byte(uchar dat) // 向DS18B20写入一个字节
{
uchar i,j;
for(j=0;j<8;j++)
{
i=dat&0x01;
dat>>=1;
if(i) DQ=1;
else DQ=0;
delay_us(15);
DQ=1;
_nop_();
_nop_();
}
}
uchar ds18b20_read_byte() // 从DS18B20读取一个字节
{
uchar i,j,dat=0;
for(j=0;j<8;j++)
{
DQ=0;
_nop_();
_nop_();
i=DQ;
delay_us(15);
dat=(dat>>1)|(i<<7);
DQ=1;
}
return dat;
}
void ds18b20_changtemp() // 让DS18B20开始转换温度
{
ds18b20_init();
ds18b20_write_byte(0xcc);
ds18b20_write_byte(0x44);
}
void ds18b20_readtemp(uchar *temp) // 读取DS18B20转换后的温度值
{
uchar a,b;
ds18b20_init();
ds18b20_write_byte(0xcc);
ds18b20_write_byte(0xbe);
a=ds18b20_read_byte();
b=ds18b20_read_byte();
*temp=b;
*temp<<=8;
*temp=*temp|a;
}
void main()
{
uchar temp; // 存储温度值
uchar shi,ge; // 存储温度值的十位和个位
while(1)
{
ds18b20_changtemp(); // 开始转换温度
delay_ms(500); // 等待转换完成
ds18b20_readtemp(&temp); // 读取温度值
shi=temp/10; // 计算十位
ge=temp%10; // 计算个位
P1=table[shi]; // 在数码管上显示十位
P0=table[ge]; // 在数码管上显示个位
}
}
```
代码注释:
```c
#include<reg52.h> // 引入51单片机头文件
#include<intrins.h>
typedef unsigned char uchar; // 定义无符号字符型变量
typedef unsigned int uint; // 定义无符号整型变量
sbit DQ=P2^0; // DS18B20温度传感器数据线连接的单片机IO口
uchar code table[]={ // 数码管显示字符的编码,共阴极数码管显示0~9
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67,
0x77,0x7c,0x39,0x5e,0x79,0x71
};
void delay_us(uint i) // 延时us
{
while(i--);
}
void delay_ms(uint i) // 延时ms
{
uchar j;
while(i--)
{
for(j=0;j<110;j++);
}
}
uchar ds18b20_init() // 初始化DS18B20
{
uchar i;
DQ=1; // 数据线置高
delay_us(15);
DQ=0; // 拉低数据线
delay_us(500); // 延时,保持低电平
DQ=1; // 释放数据线
delay_us(30);
i=DQ; // 判断DS18B20是否存在
delay_us(500);
return i;
}
void ds18b20_write_byte(uchar dat) // 向DS18B20写入一个字节
{
uchar i,j;
for(j=0;j<8;j++)
{
i=dat&0x01; // 取最低位
dat>>=1; // 依次取下一位
if(i) DQ=1; // 写1
else DQ=0; // 写0
delay_us(15); // 等待15us
DQ=1; // 释放数据线
_nop_(); // 空操作,延时1us
_nop_();
}
}
uchar ds18b20_read_byte() // 从DS18B20读取一个字节
{
uchar i,j,dat=0;
for(j=0;j<8;j++)
{
DQ=0; // 拉低数据线
_nop_();
_nop_();
i=DQ; // 读取数据
delay_us(15); // 等待15us
dat=(dat>>1)|(i<<7); // 将读取到的数据存入dat
DQ=1; // 释放数据线
}
return dat;
}
void ds18b20_changtemp() // 让DS18B20开始转换温度
{
ds18b20_init(); // 初始化DS18B20
ds18b20_write_byte(0xcc); // 跳过ROM操作,直接向DS18B20写指令
ds18b20_write_byte(0x44); // 写转换指令
}
void ds18b20_readtemp(uchar *temp) // 读取DS18B20转换后的温度值
{
uchar a,b;
ds18b20_init(); // 初始化DS18B20
ds18b20_write_byte(0xcc); // 跳过ROM操作,直接向DS18B20写指令
ds18b20_write_byte(0xbe); // 读取温度指令
a=ds18b20_read_byte(); // 读取温度低8位
b=ds18b20_read_byte(); // 读取温度高8位
*temp=b; // 将温度高8位存入temp
*temp<<=8; // 左移8位
*temp=*temp|a; // 将温度低8位存入temp
}
void main()
{
uchar temp; // 存储温度值
uchar shi,ge; // 存储温度值的十位和个位
while(1)
{
ds18b20_changtemp(); // 开始转换温度
delay_ms(500); // 等待转换完成
ds18b20_readtemp(&temp); // 读取温度值
shi=temp/10; // 计算十位
ge=temp%10; // 计算个位
P1=table[shi]; // 在数码管上显示十位
P0=table[ge]; // 在数码管上显示个位
}
}
```
以上代码实现了DS18B20温度传感器的读取和数码管的显示。在使用之前,需要将DS18B20连接到单片机的IO口,并在代码中修改对应的IO口。同时,需要根据实际情况调整代码中的延时参数,以保证DS18B20的正常工作。
阅读全文