一、原理图
DS18B20
LS BYTE 包括小数部分和整数部分低四位
MS BYTE 包括整数部分高四位,有一位是符号位
DS18B20读取温度的步骤:
DS1302
时钟芯片,存放年月日时分秒星期,七个寄存器,基本计时单位是秒。
时间的存储方式采用BCD码。
写保护寄存器:1是打开写保护,0是关闭写保护。
寄存器 0:最高位 CH 是一个时钟停止标志位。如果时钟电路有备用电源,上电后,我们要先检测一下这一位,如果这一位是0,那说明时钟芯片在系统掉电后,由于备用电源的供给,时钟是持续正常运行的;如果这一位是 1,那么说明时钟芯片在系统掉电后,时钟部分不工作了。剩下的7 位高 3 位是秒的十位,低 4 位是秒的个位。
寄存器 1:最高位未使用(0),剩下的 7 位中高 3 位是分钟的十位,低 4 位是分钟的个位。
寄存器 2:bit7 是 1 的话代表是 12 小时制,0 代表是 24 小时制;bit6 固定是 0,bit5 在12 小时制下 0 代表的是上午,1 代表的是下午,在 24 小时制下和 bit4 一起代表了小时的十位,低 4 位代表的是小时的个位。
寄存器 3:高 2 位固定是 0,bit5 和 bit4 是日期的十位,低 4 位是日期的个位。
寄存器 4:高 3 位固定是 0,bit4 是月的十位,低 4 位是月的个位。
寄存器 5:高 5 位固定是 0,低 3 位代表了星期。
寄存器 6:高 4 位代表了年的十位,低 4 位代表了年的个位。请特别注意,这里的 00~99 指的是 2000 年~2099 年。
寄存器 7:最高位一个写保护位,如果这一位是 1,那么是禁止给任何其它寄存器或者那 31 个字节的 RAM 写数据的。因此在写数据之前,这一位必须先写成 0。
二、代码实现
DS18B20读取温度代码部分 整数
#include <STC15F2K60S2.h>
#include <intrins.h>
#include <onewire.h>
void Timer0Init(void);
void display();
code unsigned char tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xc6};
unsigned char dspbuf[10]={10,10,10,10,10,0,0,0};
unsigned char dspcom=0;
unsigned char intr;
bit temper_flag=0;//温度读取标志
void main()
{
unsigned char temperature;
unsigned char low;
unsigned char high;
Timer0Init();
EA=1;//打开总中断
ET0=1;//打开定时器0中断
while (1)
{
if (temper_flag)
{
temper_flag=0;
init_ds18b20();
Write_DS18B20(0xCC);//忽略ROM指令
Write_DS18B20(0x44);//启动温度转换指令
while(!DQ);
init_ds18b20();
Write_DS18B20(0xCC);//忽略ROM指令
Write_DS18B20(0xBE);//读取寄存器指令
low=Read_DS18B20();
high=Read_DS18B20();
temperature=low>>4;
temperature=temperature|(high<<4);
//刷新显示缓冲区
dspbuf[5]=temperature/10;
dspbuf[6]=temperature%10;
dspbuf[7]=11;//显示度数的符号
}
}
}
void Timer0Init(void) //1毫秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xCD; //设置定时初值
TH0 = 0xD4; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
//定时器中断服务函数
void isr_timer_0(void) interrupt 1
{
display();
if (++intr==200)
{
intr=0;
temper_flag=1;
}
}
//显示函数
void display()
{
//消隐
P2=((P2&0x1f)|0xe0);
P0=0xff;
P2&=0x1f;
//位选
P2=((P2&0x1f)|0xc0);
P0=(1<<dspcom);
P2&=0x1f;
//段选
P2=((P2&0x1f)|0xe0);
P0=tab[dspbuf[dspcom]];
P2&=0x1f;
if (++dspcom==8)
dspcom=0;
}
DS1302代码示例
#include <STC15F2K60S2.h>
#include <ds1302.h>
void display();
void DS1302_Readtime();
void DS1302_Writepro(bit pro);
void DS1302_Settime(unsigned char shi,fen,miao);
void Timer0Init(void);
code unsigned char tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};
unsigned char dspbuf[8]={11,11,11,11,11,11,11,11};
unsigned char now[7]={0};
unsigned char dspcom=0;
unsigned char intr;
bit flag_200=0;
void main()
{
Timer0Init();
EA=1;
ET0=1;
DS1302_Writepro(0);
DS1302_Settime(0x13,0x14,0x00);
DS1302_Writepro(1);
while(1)
{
if (flag_200)
{
flag_200=0;
DS1302_Readtime();
}
}
}
void DS1302_Writepro(bit pro)
{
if (pro==1)
{
Write_Ds1302_Byte(0x8e,0x80);
}
else
{
Write_Ds1302_Byte(0x8e,0x00);
}
}
void DS1302_Settime(unsigned char shi,fen,miao)
{
Write_Ds1302_Byte(0x80,miao);
Write_Ds1302_Byte(0x82,fen);
Write_Ds1302_Byte(0x84,shi);
}
void DS1302_Readtime()
{
now[0]=Read_Ds1302_Byte(0x85);
now[1]=Read_Ds1302_Byte(0x83);
now[2]=Read_Ds1302_Byte(0x81);
dspbuf[0]=now[0]/16;
dspbuf[1]=now[0]%16;
dspbuf[2]=11;
dspbuf[3]=now[1]/16;
dspbuf[4]=now[1]%16;
dspbuf[5]=11;
dspbuf[6]=now[2]/16;
dspbuf[7]=now[2]%16;
}
//显示函数
void display()
{
//消隐
P2=((P2&0x1f)|0xe0);
P0=0xff;
P2&=0x1f;
//位选
P2=((P2&0x1f)|0xc0);
P0=(1<<dspcom);
P2&=0x1f;
//段选
P2=((P2&0x1f)|0xe0);
P0=tab[dspbuf[dspcom]];
P2&=0x1f;
if (++dspcom==8)
dspcom=0;
}
void Timer0Init(void) //1毫秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xCD; //设置定时初值
TH0 = 0xD4; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
//定时器中断服务函数
void isr_timer_0(void) interrupt 1
{
display();
if (++intr==200)
{
intr=0;
flag_200=1;
}
}