天天看點

【單片機學習筆記】(八)———DS18B20、DS1302

一、原理圖

DS18B20

【單片機學習筆記】(八)———DS18B20、DS1302
【單片機學習筆記】(八)———DS18B20、DS1302
【單片機學習筆記】(八)———DS18B20、DS1302

LS BYTE 包括小數部分和整數部分低四位

MS BYTE 包括整數部分高四位,有一位是符号位

DS18B20讀取溫度的步驟:

【單片機學習筆記】(八)———DS18B20、DS1302

DS1302

時鐘晶片,存放年月日時分秒星期,七個寄存器,基本計時機關是秒。

時間的存儲方式采用BCD碼。

寫保護寄存器:1是打開寫保護,0是關閉寫保護。

【單片機學習筆記】(八)———DS18B20、DS1302

寄存器 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;
	}
}
           

繼續閱讀