我是靠谱客的博主 标致滑板,最近开发中收集的这篇文章主要介绍STM8单片机读取18B20温度传感器,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

  ds18b20是最常用的数字温度传感器,只需要通过一根线就可取读取温度值,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。温度测量范围 -55°C 到 +125°C。

引脚排列如下

image.png

  1. GND为电源地;

  2. DQ为数字信号输入/输出端;

  3. VDD为外接供电电源输入端(在寄生电源接线方式时接地)

内部结构如下:

image.png

通过DQ端口按照一定的格式就可以将温度值读取出来。

转换成功后的温度值在寄存器中存放

image.png

S为符号位,bit0—bit3为存放小数部分,bit4—bit10存放整数部分。

image.png

初始化时序

image.png

  主机首先发出一个480-960微秒的低电平脉冲,然后释放总线变为高电平,并在随后的480微秒时间内对总线进行检测,如果有低电平出现说明总线上有器件已做出应答。若无低电平出现一直都是高电平说明总线上无器件应答。

  从器件的DS18B20在一上电后就一直在检测总线上是否有480-960微秒的低电平出现,如果有,在总线转为高电平后等待15-60微秒后将总线电平拉低60-240微秒做出响应存在脉冲,告诉主机本器件已做好准备。若没有检测到就一直在检测等待。

读写时序

image.png

  所有的写时隙必须有最少60us的持续时间,相邻两个写时隙必须要有最少1us的恢复时间。写时序分为写0和写1两种。

写”0”时,在拉低总线后主机必须继续拉低总线以满足时隙持续时间的要求(至少60μs),然后释放总线直到写周期结束。

写1时,在拉低总线后主机必须在15μs内释放总线。在总线被释放后,由于上拉电阻将总线恢复为高电平。

所有的写操作必须至少有60us的持续时间,最长不超过120us。相邻两个写时隙必须要有最少1us的恢复时间。所有的写操作(写0和写1)都由拉低总线产生。

  当总线控制器把数据线从高电平拉到低电平时,读时序开始,数据线必须至少保持1us,然后总线被释放。然后在包括前面的拉低总线电平1微秒在内的15微秒时间内完成对总线进行采样检测,采样期内总线为低电平则确认为0。采样期内总线为高电平则确认为1。
完成一个读时序过程,至少需要60us才能完成,两个读周期间至少1us的恢复时间。

读写时序是分时完成的,所以在对总线读写时,要阉割按照时序来进行。
对ds18b20进行温度转换必须经过以下 3个步骤 :

(1)每次读写前对ds18b20进行复位初始化。复位要求主 CPU 将数据线下拉 500us ,然后释放, DS18B20 收到信号后等待16us ~ 60us 左右,然后发出60us~240us 的存在低脉冲,主 CPU 收到此信号后表示复位成功。

(2)发送一条 ROM 指令

9.jpg

(3)发送存储器指令

10.jpg

比如官方手册中给出了一个操作例子

image.png

这个例子是总线上有多个设备,每次操作前都要进行身份对比,如果只有一个设备,那么就可以跳过ROM地址的识别。

image.png

  接下来就可以用代码操作传感器了:

#include "ds18b20.h"
#include "stm8s103f.h"
#include "delay.h"

#define DS18B20_DQ_OUT          PA_DDR |= 0x08   //输出
#define DS18B20_DQ_IN           PA_DDR &= 0xf7   //输入
#define DS18B20_DQ_HIGH         PA_ODR |= 0x08   //拉高
#define DS18B20_DQ_LOW          PA_ODR &= 0xf7   //拉低
#define DS18B20_DQ_PULL_UP      PA_CR1 |= 0x08   //上拉输入
#define DS18B20_DQ_FLOATING     PA_CR1 &= 0xf7    //浮空输入
#define DS18B20_DQ_PUSH_PULL    PA_CR1 |= 0x08   //推挽输出
#define DS18B20_DQ_OPEN_DRAIN   PA_CR1 &= 0xf7    //开漏输出
#define DS18B20_DQ_VALUE        PA_IDR &0x08       //DQ值

void DS18B20_Init( void )
{
	DS18B20_DQ_OUT;
	DS18B20_DQ_PUSH_PULL;
	DS18B20_DQ_HIGH;
	delay_us( 10 );
	DS18B20_DQ_LOW;
	delay_us( 600 ); /*复位脉冲 */

	DS18B20_DQ_IN;
	DS18B20_DQ_PULL_UP;
	delay_us( 60 );
	while ( DS18B20_DQ_VALUE == 1 )
		;
	delay_us( 400 );
}
void DS18B20_WriteByte(unsigned char _data)
{
	unsigned char i = 0;
	DS18B20_DQ_OUT;
	for ( i = 0; i < 8; i++ )
	{
		DS18B20_DQ_LOW;
		delay_us( 2 );
		if ( _data & 0x01 )
		{
			DS18B20_DQ_HIGH;
		}
		_data >>= 1;
		delay_us( 60 );
		DS18B20_DQ_HIGH;
	}
}
unsigned char DS18B20_ReadByte(void)
{
	unsigned char i = 0, _data = 0;
	for ( i = 0; i < 8; i++ )
	{
		DS18B20_DQ_OUT;
		DS18B20_DQ_LOW;
		delay_us( 5 );
		_data >>= 1;
		DS18B20_DQ_HIGH;
		DS18B20_DQ_IN;
		if ( DS18B20_DQ_VALUE )
		{
			_data |= 0x80;
		}
		DS18B20_DQ_OUT;
		DS18B20_DQ_HIGH;
		delay_us( 60 );
	}

	return(_data);
}

float DS18B20_ReadTemperature(void)
{
	unsigned char  temp = 0;
	float t= 0;
	DS18B20_Init();
	DS18B20_WriteByte( 0xcc );
	DS18B20_WriteByte( 0x44 );

	DS18B20_Init();
	DS18B20_WriteByte( 0xcc );
	DS18B20_WriteByte( 0xbe );

	temp = DS18B20_ReadByte();
	t = ( ( (temp & 0xf0) >> 4) + (temp & 0x07) * 0.125);
	temp = DS18B20_ReadByte();
	t += ( (temp & 0x0f) << 4);

	return(t);
}

  读取温度时,直接在主函数中调用

#include "stm8s103f.h"
#include "ds18b20.h"
#include "delay.h"
/*系统时钟初始化*/
void SysClkInit(void)
{                           //默认值为16M 8分频
	CLK_SWR=0xe1;      //HSI为主时钟源  16MHz CPU时钟频率
	CLK_CKDIVR=0x00;   //CPU时钟0分频,系统时钟0分频 16M 
}
main()
{
    float tem;
    SysClkInit();
    delay_init(16);
    tem=DS18B20_ReadTemperature();
	while (1);
}

在使用ds18b20的时候,关键是要保证时序的正确性,如果编写的代码不能正确读出温度值,就需要通过示波器来分析总线上的波形,看看总线上的时序是否和芯片手册中要求的一样。

最后

以上就是标致滑板为你收集整理的STM8单片机读取18B20温度传感器的全部内容,希望文章能够帮你解决STM8单片机读取18B20温度传感器所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(53)

评论列表共有 0 条评论

立即
投稿
返回
顶部