简介
DS18B20是单线接口数字温度传感器,测量单位位:-55°C~+125°C,-10°C~+85°C测量范围内精度是±0.5°C,测量分辨率位9~12位(复位值为 12 位,最大转换时间为 750ms)。
DS18B20 的暂存器如表 所示
DS18B20 的操作步骤分为3步:复位、ROM指令、功能指令。其ROM 命令和功能命令分别如表:
国信长天单片机竞赛实训平台的 DS18B20 电路图如下图所示:
在竞赛的时候,官方会给选手赛点资源数据包的压缩包,解压后将,找到其中的驱动文件添加进自己的工程文件夹中,最后在写代码的界面把.c从存在的文件中加进我们的工程组即可。
注意事项
在2019年的比赛中,组委会在onewire.h文件中没有将onewire.c函数中的所以函数都声明,所以我们需要自己在.h文件中将其声明。
此外,我们的onewire.c中并没有温度的读取程序,所以我们需要在.c文件中追加一个函数温度的读取函数,如下:
float rd_temperature_f(void)
{
unsigned int temp;
float temperature;
unsigned char low,high;
init_ds18b20();
Write_DS18B20(0xCC);
Write_DS18B20(0x44); //启动温度转换
while (!DQ); //等待转换完成
init_ds18b20();
Write_DS18B20(0xCC);
Write_DS18B20(0xBE); //读取寄存器
low = Read_DS18B20(); //低字节
high = Read_DS18B20(); //高字节
/** 精度为0.0625摄氏度 */
temp = (high&0x0f);
temp <<= 8;
temp |= low;
temperature = temp*0.0625;
return temperature;
}
程序实现
下面我们来写一个简单的读取周围环境温度的代码,数码管7、6、5现实温度,7号数码管显示小数温度(保留一位小数)
#include "STC15F2k60S2.h"
#include "Close.h"
#include "HC138.h"
#include "ds18b20.h"
//数字0~9的段码
unsigned char tab1[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xBF,0x7F};
unsigned char tab2[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
//数字加“.”的段码 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.
unsigned char dspbuf[]={10,10,10,10,10,0,0,0};
unsigned char dspcom=5;//数码管移位计数器
unsigned char n1; //定时器计数器
unsigned char TPH; //存放高低位
unsigned int temper; //存最后的温度
typedef unsigned char BYTE;
BYTE TPL;
bit temp_flag=0; //温度的读取标志
sbit DQ=P1^4; //特殊串口的定义
void Timer0Init(void) //2毫秒@12.000MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x40; //设置定时初始值
TH0 = 0xA2; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;
EA=1;
}
void display()
{
HC138(7); //这一步段码初始化是为了消影,免得有残影出现
P0=0xff;
P2&=0x1f;
HC138(6); //位选
P0=1<<dspcom;
P2&=0x1f;
HC138(7);
P0=tab1[dspbuf[dspcom]];
P2&=0x1f;
if(dspcom==6) //个位后要跟小数点,所以在个位时用加小数点的段码表,当然不止这一种方法加点
{
HC138(7);
P0=tab2[dspbuf[dspcom]];
}
if(++dspcom==8)
{
dspcom=5;
}
}
void Timer_Rountine() interrupt 1
{
display(); //因为选的定时器是自动重载的,所以不需要再初始化TH0、TL0
if(++n1==50)
{
n1=0;
temp_flag=1;
}
}
void main()
{
float temperature;
Close_Init();
Timer0Init();
while(1)
{
if(temp_flag)
{
temp_flag = 0;
temperature=rd_temperature_f();//将读取到的温度值给temperature
temper=temperature*10; //将得到的数据化为3位整型,后面好取出来
dspbuf[5] = temper/100; //取出十位
dspbuf[6] = (temper/10)%10;//取出个位
dspbuf[7] = temper%10; //取出小时部分
}
}
}
驱动代码
#include "STC15F2K60S2.H"
#include "intrins.h"
void HC138(unsigned char n)
{
switch(n)
{
case 4:P2=((P2&0x1f)|0x8F);break;
case 5:P2=((P2&0x1f)|0xA0);break;
case 6:P2=((P2&0x1f)|0xC0);break;
case 7:P2=((P2&0x1f)|0xE0);break;
}
}
#include "STC15F2K60S2.H"
#include "intrins.h"
void Close_Init()
{
P2=((P2 & 0x1F) | 0xA0);
P0 &=0xAF;
P2 = 0x1F;
}