天天看点

【单片机学习笔记】(八)———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;
	}
}
           

继续阅读