【STC15F2K60S2学习笔记】六.单总线协议和DS18B20

本文详细介绍了如何在蓝桥杯比赛中使用DS18B20温度传感器进行单总线通信,包括初始化、读写数据操作和温度读取函数。还展示了如何在提供的onewire.c模板基础上添加必要的硬件配置和延时处理。
摘要由CSDN通过智能技术生成

写在前面

        本次学习将分为两个部分解释说明如何使用DS18B20以及编写Onewire.c的文件,第一部分是解释编写Onewire.c的原理,第二部分会针对如何在蓝桥杯比赛时快速建立底层作说明。

设计思路

一、单总线初始化

Delay_onewire
void Delay_onewire(unsigned int t)//延时函数1~2us
{
	unsigned char i;
	while(t--)
	{
		for(i=0;i=12;i++);
	}
}
Init_DS18B20
bit Init_DS18B20(void)//初始化
{
	bit Initflag = 0;
	
	DQ = 1;//单总线复位
	Delay_onewire(12);
	DQ = 0;//拉低单总线
	Delay_onewire(80);
	DQ = 1;//拉高单总线
	Delay_onewire(10);
	Initflag = DQ;//返回单总线状态
	Delay_onewire(5);
	
	return Initflag;
}

 二、单总线读写数据

 Read_DS18B20
unsigned char Read_DS13B20(void)//读
{
	unsigned char i;
	unsigned char dat;
	
	for (i=0;i<8;i++)
	{
		DQ = 0;
		dat>>=1;
		DQ = 1;
		if(DQ)
		{
			dat|=0x80;
		}
	}
	return dat;
}
Write_DS18B20
void Write_DS18B20(unsigned char dat)//写
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		DQ = 0;
		DQ = dat&0x01;
		Delay_OneWire(5);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(5);
}

三、DS18B20温度读取

查阅DS18B20的手册(详见附件)

跳过 ROM [CCh]指令允许主设备在不发送任何 ROM 代码信息的情况下同时寻址总线上的所有设备。例如,主设备可以通过发出跳过 ROM 指令后跟一个转换温度 [44h] 指令来使总线上的所有 DS18B20 同时执行温度转换。

需要注意的是,仅当总线上只有一个从设备时,才能在跳过 ROM 指令后跟随读取 Scratchpad [BEh] 指令。在这种情况下,通过允许主设备从从设备读取数据而不发送设备的 64 位 ROM 代码,节省了时间。但是,如果总线上有多个从设备,则跳过 ROM 指令后跟一个读取 Scratchpad 指令将导致总线上的数据冲突,因为多个设备将尝试同时传输数据。

 转换温度 [44h] 指令启动单次温度转换。在转换完成后,生成的热数据存储在scratchpad存储器中的2字节温度寄存器中,然后DS18B20返回到其低功耗空闲状态。如果设备正在使用寄生功率模式,在发出此命令后的10µs(最大)内,主设备必须在转换期间(tCONV)在1-Wire总线上启用强拉电阻,如“为DS18B20供电”部分所述。如果DS18B20由外部供电,则主设备可以在转换T命令后发出读取时间槽,并且DS18B20将在温度转换进行中发送一个0,转换完成时发送一个1作为响应。在寄生功率模式下,由于总线被高拉电阻拉高,因此无法使用此通知技术。

 读取内容[BEh]。数据传输从第一个字节的最低有效位开始,一直延续到第九个字节(第八个字节是CRC)。如果只需要部分刮板数据,主设备可以随时发送复位命令来终止读取。

SKIP ROM        //0xcc

CONVENT T        //0x44

READ SCRATCHPAD        //0xbe

 Read_temp
float Read_temp()//温度读取
{
	unsigned char low,high;
	Init_DS18B20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	Init_DS18B20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);	
	low = Read_DS18B20();
	high = Read_DS18B20();
	return ((high<<8) | low) / 16.0;
}

 快速建立底层

基本原理掌握了以后,下面我们来了解一下如何在蓝桥杯比赛时快速建立模板

首先比赛时会提供一部分底层文件,包括ds1302.c,onewire.c,iic.c,在2023年以后这三个文件都需要经过自己加上一些代码,这里只说明onewire.c如何改编。

一、onewire.c

下面是比赛官方给的onewire.c文件

/*	# 	单总线代码片段说明
	1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
	2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
		中对单片机时钟频率的要求,进行代码调试和修改。
*/

//
void Delay_OneWire(unsigned int t)  
{
	unsigned char i;
	while(t--){
		for(i=0;i<12;i++);
	}
}

//
void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		DQ = 0;
		DQ = dat&0x01;
		Delay_OneWire(5);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(5);
}

//
unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;
  
	for(i=0;i<8;i++)
	{
		DQ = 0;
		dat >>= 1;
		DQ = 1;
		if(DQ)
		{
			dat |= 0x80;
		}	    
		Delay_OneWire(5);
	}
	return dat;
}

//
bit init_ds18b20(void)
{
  	bit initflag = 0;
  	
  	DQ = 1;
  	Delay_OneWire(12);
  	DQ = 0;
  	Delay_OneWire(80);
  	DQ = 1;
  	Delay_OneWire(10); 
    initflag = DQ;     
  	Delay_OneWire(5);
  
  	return initflag;
}

如果我们直接对其进行编译,keil会报错,这是因为没有定义DQ引脚和引入头文件,我们需要做的就是在这段代码之前加上这两个步骤,并且写一个读取温度的函数Read_temp

#include "onewire.h"
#include "reg52.h"

sbit DQ = P1^4;  

//单总线内部延时函数
void Delay_OneWire(unsigned int t)  
{
	t *= 12;
	while(t--);
}

//单总线写操作
void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		DQ = 0;
		DQ = dat&0x01;
		Delay_OneWire(5);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(5);
}

//单总线读操作
unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;
  
	for(i=0;i<8;i++)
	{
		DQ = 0;
		dat >>= 1;
		DQ = 1;
		if(DQ)
		{
			dat |= 0x80;
		}	    
		Delay_OneWire(5);
	}
	return dat;
}

//DS18B20初始化
bit init_ds18b20(void)
{
  	bit initflag = 0;
  	
  	DQ = 1;
  	Delay_OneWire(12);
  	DQ = 0;
  	Delay_OneWire(80);
  	DQ = 1;
  	Delay_OneWire(10); 
    initflag = DQ;     
  	Delay_OneWire(5);
  
  	return initflag;
}


float Read_temp()//读温度
{
	unsigned char low,high;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);	
	low = Read_DS18B20();
	high = Read_DS18B20();
	return ((high<<8) | low) / 16.0;
}

二、onewire.h

float Read_temp()

到这里单总线通信以及DS18B20温度读取就写完了,具体如何使用我们后面再来说明。

无限进步

  • 12
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

这里是扁芒吖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值