at89c51与ds18b20通信方式
时间: 2024-05-25 21:12:51 浏览: 32
AT89C51是一款8位单片机,而DS18B20是一种数字温度传感器。它们之间可以通过1-Wire总线进行通信。
下面是AT89C51与DS18B20通信的基本步骤:
1. 设置1-Wire总线引脚为输出模式,发送复位脉冲。复位脉冲持续时间应大于480us。
2. 发送读写命令,包括DS18B20的ROM码和功能字节。
3. DS18B20将温度数据转换成二进制数,并将其存储在3个字节的寄存器中。
4. AT89C51发送读寄存器命令,读取DS18B20的温度数据。
5. AT89C51将读取的数据转换为温度值,然后进行相应的处理和控制。
需要注意的是,1-Wire总线的通信需要遵循一定的协议,具体的通信细节可以参考DS18B20的数据手册。
相关问题
用AT89C51和DS18B20采集温度,在UG-2864HSWEG01上显示代码
以下是基于AT89C51和DS18B20采集温度,并在UG-2864HSWEG01上显示的示例代码:
```
#include <reg51.h>
#include <intrins.h>
#include <stdio.h>
#define DS18B20_DQ P3_7
#define UG_EN P2_3
#define UG_RW P2_2
#define UG_RS P2_1
#define UG_E P2_0
#define DS18B20_SKIP_ROM 0xCC
#define DS18B20_CONVERT_T 0x44
#define DS18B20_READ_SCRATCHPAD 0xBE
sbit SDA = P1^3;
sbit SCL = P1^2;
unsigned char code g_LcdInitCmd[] = {0x38, 0x0c, 0x06, 0x01, 0x02, 0x80};
unsigned char code g_LcdClearCmd[] = {0x01};
void delay_us(unsigned int us)
{
while (us--)
{
_nop_();
}
}
void delay_ms(unsigned int ms)
{
while (ms--)
{
delay_us(1000);
}
}
void DS18B20_Write_Byte(unsigned char dat)
{
unsigned char i;
for (i = 0; i < 8; i++)
{
DS18B20_DQ = 0;
_nop_();
_nop_();
DS18B20_DQ = dat & 0x01;
_nop_();
_nop_();
DS18B20_DQ = 1;
dat >>= 1;
}
}
unsigned char DS18B20_Read_Byte()
{
unsigned char i, dat = 0;
for (i = 0; i < 8; i++)
{
DS18B20_DQ = 0;
_nop_();
_nop_();
dat >>= 1;
if (DS18B20_DQ)
{
dat |= 0x80;
}
_nop_();
_nop_();
DS18B20_DQ = 1;
}
return dat;
}
void UG_Write_Cmd(unsigned char cmd)
{
UG_EN = 0;
UG_RW = 0;
UG_RS = 0;
P0 = cmd;
UG_EN = 1;
delay_us(1);
UG_EN = 0;
delay_ms(2);
}
void UG_Write_Data(unsigned char dat)
{
UG_EN = 0;
UG_RW = 0;
UG_RS = 1;
P0 = dat;
UG_EN = 1;
delay_us(1);
UG_EN = 0;
delay_ms(2);
}
void UG_Init()
{
unsigned char i;
UG_Write_Cmd(0x38);
UG_Write_Cmd(0x0c);
UG_Write_Cmd(0x06);
UG_Write_Cmd(0x01);
UG_Write_Cmd(0x02);
UG_Write_Cmd(0x80);
}
void UG_Clear()
{
UG_Write_Cmd(0x01);
}
void UG_Puts(unsigned char x, unsigned char y, unsigned char *str)
{
unsigned char i = 0;
if (y == 1)
{
UG_Write_Cmd(0x80 + x);
}
else
{
UG_Write_Cmd(0xc0 + x);
}
while (str[i] != '\0')
{
UG_Write_Data(str[i]);
i++;
}
}
void UG_Putc(unsigned char x, unsigned char y, unsigned char c)
{
if (y == 1)
{
UG_Write_Cmd(0x80 + x);
}
else
{
UG_Write_Cmd(0xc0 + x);
}
UG_Write_Data(c);
}
void UG_Display_Temperature(float temperature)
{
char str[17];
sprintf(str, "Temperature: %.1f C", temperature);
UG_Clear();
UG_Puts(0, 0, "AT89C51+DS18B20");
UG_Puts(0, 1, str);
}
void DS18B20_Start_Convert()
{
DS18B20_Write_Byte(DS18B20_SKIP_ROM);
DS18B20_Write_Byte(DS18B20_CONVERT_T);
}
unsigned int DS18B20_Read_Temperature()
{
unsigned char temp_l, temp_h;
unsigned int temp;
DS18B20_Write_Byte(DS18B20_SKIP_ROM);
DS18B20_Write_Byte(DS18B20_READ_SCRATCHPAD);
temp_l = DS18B20_Read_Byte();
temp_h = DS18B20_Read_Byte();
temp = temp_h;
temp <<= 8;
temp |= temp_l;
return temp;
}
void main()
{
float temperature;
unsigned int temp;
UG_Init();
UG_Clear();
UG_Puts(0, 0, "AT89C51+DS18B20");
while (1)
{
DS18B20_Start_Convert();
delay_ms(750);
temp = DS18B20_Read_Temperature();
temperature = (float)temp / 16.0;
UG_Display_Temperature(temperature);
delay_ms(2000);
}
}
```
需要注意的是,这个示例代码是基于AT89C51的,如果你使用的是其他型号的单片机,需要对代码进行相应的修改。同时,UG-2864HSWEG01显示屏需要通过SPI通信方式进行控制,如有需要也需要对代码进行修改。
利用数字温度传感器DS18B20与单片机结合来测量温度。利用数字温度传感器DS18B20测量温度信号,计算后在LED数码管上显示相应的温度值。其温度测量范围为-55℃~125℃,精确到0.5℃。数字温度计所测量的温度采用数字显示,控制器使用单片机AT89C51,测温传感器使用DS18B20,共阴极LED数码管以SEG和LOC串口传送数据实现温度显示的keil代码
以下是基于AT89C51单片机的DS18B20数字温度传感器测量温度并在LED数码管上显示的Keil代码:
```
#include <reg51.h>
#define DQ P3_2 // 定义DS18B20的数据口
typedef unsigned char uchar;
typedef unsigned int uint;
void Delay10us() // 延时函数,用于DS18B20通信
{
uchar i;
for (i = 0; i < 2; i++);
}
uchar Init_DS18B20() // 初始化DS18B20,返回0表示初始化失败,返回1表示初始化成功
{
uchar flag;
DQ = 1; // DQ为高电平
Delay10us();
DQ = 0; // DQ为低电平
Delay10us();
DQ = 1; // DQ为高电平
Delay10us();
flag = DQ; // 判断DS18B20设备是否存在
Delay10us();
return flag;
}
void Write_DS18B20(uchar dat) // 向DS18B20写入一个字节的数据
{
uchar i;
for (i = 0; i < 8; i++)
{
DQ = 0; // DQ为低电平
Delay10us();
DQ = dat & 0x01; // 写入数据的最低位
Delay10us();
DQ = 1; // DQ为高电平
dat >>= 1; // 写入数据的下一位
Delay10us();
}
}
uchar Read_DS18B20() // 从DS18B20读取一个字节的数据
{
uchar i, dat = 0;
for (i = 0; i < 8; i++)
{
DQ = 0; // DQ为低电平
Delay10us();
DQ = 1; // DQ为高电平
Delay10us();
dat >>= 1; // 读取数据的下一位
if (DQ) dat |= 0x80; // 读取数据的最高位
Delay10us();
}
return dat;
}
void Convert() // DS18B20温度转换
{
Init_DS18B20(); // 初始化DS18B20
Write_DS18B20(0xcc); // 跳过ROM操作
Write_DS18B20(0x44); // 温度转换指令
}
void Read_Temp(uchar *temp) // 从DS18B20读取温度值
{
uchar th, tl;
Init_DS18B20(); // 初始化DS18B20
Write_DS18B20(0xcc); // 跳过ROM操作
Write_DS18B20(0xbe); // 发送读温度指令
tl = Read_DS18B20(); // 读取温度低八位
th = Read_DS18B20(); // 读取温度高八位
*temp = th; // 将温度值存入指针所指向的地址
*(temp + 1) = tl;
}
void Display_Temp(uchar *temp) // 将温度值显示在LED数码管上
{
uchar i;
uchar code table[] = { // 数码管显示表,共阴极LED数码管
0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71
};
uchar temp_h, temp_l;
temp_h = *temp; // 获取温度高八位
temp_l = *(temp + 1); // 获取温度低八位
if (temp_h & 0x80) // 判断温度是否为负数
{
P2 &= ~0x01; // 第一个LED数码管点亮
P0 = 0x40; // 数码管显示“-”
temp_h = ~(temp_h - 1); // 取反加一,得到温度的绝对值
temp_l = ~temp_l + 1;
}
else // 温度为正数
{
P2 &= ~0x01; // 第一个LED数码管点亮
P0 = table[temp_h / 10]; // 数码管显示温度的十位
Delay10us();
P2 &= ~0x02; // 第二个LED数码管点亮
P0 = table[temp_h % 10]; // 数码管显示温度的个位
Delay10us();
}
P2 &= ~0x04; // 第三个LED数码管点亮
P0 = table[temp_l / 10]; // 数码管显示温度的小数点前一位
Delay10us();
P2 &= ~0x08; // 第四个LED数码管点亮
P0 = table[temp_l % 10]; // 数码管显示温度的小数点后一位
Delay10us();
}
void main()
{
uchar temp[2]; // 用于存储温度值的数组
while (1)
{
Convert(); // DS18B20温度转换
Read_Temp(temp); // 从DS18B20读取温度值
Display_Temp(temp); // 将温度值显示在LED数码管上
}
}
```
该代码实现了DS18B20数字温度传感器的初始化、温度转换、温度读取和温度显示等功能,可用于测量范围为-55℃~125℃,精确到0.5℃的温度。其中,Init_DS18B20()函数用于初始化DS18B20,Write_DS18B20()函数用于向DS18B20写入一个字节的数据,Read_DS18B20()函数用于从DS18B20读取一个字节的数据,Convert()函数用于DS18B20温度转换,Read_Temp()函数用于从DS18B20读取温度值,Display_Temp()函数用于将温度值显示在LED数码管上。
相关推荐
![doc](https://img-home.csdnimg.cn/images/20210720083327.png)
![doc](https://img-home.csdnimg.cn/images/20210720083327.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![application/x-zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![doc](https://img-home.csdnimg.cn/images/20210720083327.png)