一、原理圖
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;
}
}