概述
ds18b20是最常用的数字温度传感器,只需要通过一根线就可取读取温度值,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。温度测量范围 -55°C 到 +125°C。
引脚排列如下
-
GND为电源地;
-
DQ为数字信号输入/输出端;
-
VDD为外接供电电源输入端(在寄生电源接线方式时接地)
内部结构如下:
通过DQ端口按照一定的格式就可以将温度值读取出来。
转换成功后的温度值在寄存器中存放
S为符号位,bit0—bit3为存放小数部分,bit4—bit10存放整数部分。
初始化时序
主机首先发出一个480-960微秒的低电平脉冲,然后释放总线变为高电平,并在随后的480微秒时间内对总线进行检测,如果有低电平出现说明总线上有器件已做出应答。若无低电平出现一直都是高电平说明总线上无器件应答。
从器件的DS18B20在一上电后就一直在检测总线上是否有480-960微秒的低电平出现,如果有,在总线转为高电平后等待15-60微秒后将总线电平拉低60-240微秒做出响应存在脉冲,告诉主机本器件已做好准备。若没有检测到就一直在检测等待。
读写时序
所有的写时隙必须有最少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 指令
(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的时候,关键是要保证时序的正确性,如果编写的代码不能正确读出温度值,就需要通过示波器来分析总线上的波形,看看总线上的时序是否和芯片手册中要求的一样。
最后
以上就是标致滑板为你收集整理的STM8单片机读取18B20温度传感器的全部内容,希望文章能够帮你解决STM8单片机读取18B20温度传感器所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复