锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

STM8单片机读取18B20温度传感器

时间:2022-08-26 18:00:00 8f8h传感器然后外接传感器等一些器件05t温度传感器2线数字温度传感器s5851astm8外接传感器240f传感器

??ds18b20是最常用的数字温度传感器,温度值只能通过一根线读取,体积小,硬件成本低,抗干扰能力强,精度高。温度测量范围 -55°C 到 125°C。

引脚排列如下

image.png

  1. GND为电源地;

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

  3. VDD外部供电电源输入端(寄生电源接接地)

内部结构如下:

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

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

S为符号位,bit0—bit三是存放小数部分,bit4—bit10存储整数部分。

初始化时序

??主机首先发出480-960微秒的低电平脉冲,然后将总线释放为高电平,并在接下来的480微秒内检测总线。如果有低电平,则表明总线上的设备已响应。如果没有低电平,则总线上没有设备响应。

??从器件的DS18B20一上电,就一直在检测总线上是否有480-960微秒的低电平。如果是这样,在总线转换为高电平后,等待15-60微秒,然后将总线电平降低60-240微秒,以响应脉冲,并告诉主机本设备已准备好。如果没有检测到,就一直在等待检测。

读写时序

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

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

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

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

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

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

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

(2)发送一个 ROM 指令

(3)发送存储指令

\

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

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

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

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

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章