蓝桥杯单片机——DS1302实时时钟(12)

一、原理分析

DS1302是由美国DALLAS公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。它可以对年、月、日、周、时、分、秒进行计时,并且具有闰年补偿等多种功能。

1、DS1302控制字格式:

 2、DS1302 相关的寄存器:(数据格式:BCD码)

 二、程序编写

 

将官方提供的资源包里的底层驱动代码拷贝到工程路径下:

ds1302.c 

/*
  程序说明: DS1302驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT107单片机综合实训平台 8051,12MHz
  日    期: 2011-8-9
*/

#include <reg52.h>
#include <intrins.h>

sbit SCK=P1^7;		
sbit SDA=P2^3;		
sbit RST = P1^3;   // DS1302复位												

void Write_Ds1302(unsigned  char temp) 
{
	unsigned char i;
	for (i=0;i<8;i++)     	
	{ 
		SCK=0;
		SDA=temp&0x01;
		temp>>=1; 
		SCK=1;
	}
}   

void Write_Ds1302_Byte( unsigned char address,unsigned char dat )     
{
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
 	RST=1; 	_nop_();  
 	Write_Ds1302(address);	
 	Write_Ds1302(dat);		
 	RST=0; 
}

unsigned char Read_Ds1302_Byte ( unsigned char address )
{
 	unsigned char i,temp=0x00;
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
 	RST=1;	_nop_();
 	Write_Ds1302(address);
 	for (i=0;i<8;i++) 	
 	{		
		SCK=0;
		temp>>=1;	
 		if(SDA)
 		temp|=0x80;	
 		SCK=1;
	} 
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
	SCK=1;	_nop_();
	SDA=0;	_nop_();
	SDA=1;	_nop_();
	return (temp);			
}

 ds1302.h

#ifndef __DS1302_H
#define __DS1302_H

void Write_Ds1302(unsigned char temp);
void Write_Ds1302_Byte( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302_Byte( unsigned char address );
#endif

main.c

#include <reg52.h>
#include <ds1302.h>
//定义ds1302读操作的日历时钟存储器地址
unsigned char write_ds1302_add[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
//定义ds1302写操作的日历时钟存储器地址
unsigned char read_ds1302_add[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
//设置初始时间:2022年3月7日,周一,23点59分51秒(BCD码)
unsigned char  time[7]={0x51,0x59,0x23,0x07,0x03,0x01,0x22};
unsigned char  smg_nodot[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char  smg_dot[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
void ds1302_init()//ds1302初始化
{
	char i;
	Write_Ds1302_Byte(0x8e,0x00);//写保护位wp置0,可进行写操作
	for(i=0;i<7;i++)
	{
		Write_Ds1302_Byte(write_ds1302_add[i],time[i]);	
	}
  	Write_Ds1302_Byte(0x8e,0x80);//写保护位wp置1,禁止写操作
}
void read_ds1302_time()//读时间
{
 	char i;
	for(i=0;i<7;i++)
	{
	 time[i]=Read_Ds1302_Byte(read_ds1302_add[i]);
	}
}
//数码管显示模块
void Delay_SMG(unsigned int t)
{
	while(t--);
}
void DisplaySMG_Bit(unsigned char pos,unsigned char dat)
{
  P2=0xE0;P0=0xff;//先全部关掉数码管,避免显示不正常
  P2=0xC0;P0=0x01<<pos;
  P2=0xE0;P0=dat;	
}
void display_1302()
{
  DisplaySMG_Bit(0,smg_nodot[time[2]/16]);
  Delay_SMG(100);
  DisplaySMG_Bit(1,smg_nodot[time[2]%16]);
  Delay_SMG(100);//时

  DisplaySMG_Bit(2,0xbf); //分隔符—
  Delay_SMG(100);

  DisplaySMG_Bit(3,smg_nodot[time[1]/16]);
  Delay_SMG(100);
  DisplaySMG_Bit(4,smg_nodot[time[1]%16]);
  Delay_SMG(100);//分

  DisplaySMG_Bit(5,0xbf);//分隔符—
  Delay_SMG(100);

  DisplaySMG_Bit(6,smg_nodot[time[0]/16]);
  Delay_SMG(100);
  DisplaySMG_Bit(7,smg_nodot[time[0]%16]);
  Delay_SMG(100);//秒

  P2=0xC0;P0=0xff;//关闭全部数码管,避免最右的数码管显示特别亮
  P2=0xE0;P0=0xff;	
}
void main()
{
  P2=0x80;P0=0xff;//关闭LED灯
  ds1302_init();
  while(1)
  {
  	  read_ds1302_time();
	  display_1302();
  }

}

猜你喜欢

转载自blog.csdn.net/m0_57263863/article/details/123357980