蓝桥杯单片机----DS1302的基本应用

        DS1302 是 DALLAS 公司推出的涓流充电时钟芯片内含有一个实时时钟/日历和 31 字节静态 RAM可通过简单的串行接口与单片机进行通信。

可提供:

        1.秒分时日日期月年的信息;
        2.每月的天数和闰年的天数可自动调整;
        3.可通过 AM/PM 指示决定采用 24 或 12 小时格式;
        4.保持数据和时钟信息时功率小于 1mW。

设计内容:

        1.设备初始化时钟为 23 时 59 分 50 秒,闹钟提醒时间 0 时 0 分 0 秒;

        2.指示灯L1以0.2秒闪烁,5秒后关闭,代表闹钟提醒功能。

        考试的时候官方是会提供驱动给我们的,不太清楚的同学可以参考蓝桥杯大赛——驱动程序,官方给我们提供了这部分程序,对我们的代码编写工作量来说确实减少了很多,但这个驱动并不是可以直接拿来用的,我们还需要再写一部分程序才能真正利用到这部分代码,下面咱们就用官方提供的驱动来编程吧。

#include<stc15f2k60s2.h>
#include <intrins.h>
	
#define uchar unsigned char   //定义无符号字符类型uchar
#define uint unsigned int     //定义无符号整型类型uint
	
sbit SCK=P1^7;		
sbit SDA=P2^3;		
sbit RST = P1^3;   // DS1302复位	

uchar shijian[]={50,59,23,0,0,0,0};
uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};//数字0~9,“-”,“关”
uchar yi,er,san,si,wu,liu,qi,ba;   //定义字符型变量yi,er,san,si,wu,liu,qi,ba,当作数码管显示控制变量

uchar Naozhong[]={0,0,0};

uint L1_shan_tt=0,L1_guan_tt=0;
bit fla=0,L1=0;

void delayms(int ms);          //延时函数
void allinit();                //初始化函数
void display1(uchar yi,uchar er);   //第一、二段数码管函数
void display2(uchar san,uchar si);  //第三、四段数码管函数
void display3(uchar wu,uchar liu);  //第五、六段数码管函数
void display4(uchar qi,uchar ba);   //第七、八段数码管函数

void Write_Ds1302_Byte(unsigned char temp);
void Write_Ds1302(unsigned char address,unsigned char dat) ;
unsigned char Read_Ds1302(unsigned char address);
void DS_init();
void DS_get();
void Timer0Init(void);		//1毫秒@12.000MHz
	
void main()//主函数
{
	allinit();                  //初始化函数
	DS_init();
	Timer0Init();
	while(1)
	{
		DS_get();
		yi=shijian[2]/10;er=shijian[2]%10;san=10;
		si=shijian[1]/10;wu=shijian[1]%10;liu=10;
		qi=shijian[0]/10;ba=shijian[0]%10;
		if((shijian[2]==Naozhong[2])&&(shijian[1]==Naozhong[1])&&(shijian[0]==Naozhong[0]))
		{
			L1=1;EA=1;ET0=1;
		}
		display1(yi,er);          //第一、二段数码管函数
		display2(san,si);         //第三、四段数码管函数
		display3(wu,liu);         //第五、六段数码管函数
		display4(qi,ba);          //第七、八段数码管函数
	}
}
void Timer0Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x20;		//设置定时初值
	TH0 = 0xD1;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
}
void time0() interrupt 1
{
	if((++L1_shan_tt==200)&&(L1==1))
	{
		L1_shan_tt=0;
		if(fla==0){fla=1;P2=0X80;P0=0XFE;}
		else if(fla==1){fla=0;P2=0X80;P0=0XFF;}
	}
	if(++L1_guan_tt==5000)
	{
		EA=1;ET0=1;L1=0;P2=0X80;P0=0XFF;L1_shan_tt=0;L1_guan_tt=0;
	}
}
void delayms(int ms)//延时函数
{
	uint i,j;
	for(i=ms;i>0;i--)
		for(j=845;j>0;j--);
}
void allinit()//初始化函数
{
	P2=0XA0;P0=0X00;      //关闭蜂鸣器继电器
	P2=0X80;P0=0XFF;      //关闭所有LED灯
	
	P2=0XC0;P0=0XFF;      //选中所有数码管段选
	P2=0XFF;P0=0XFF;      //关闭所有数码管
}
void display1(uchar yi,uchar er)//第一、二段数码管函数
{
	P2=0XC0;P0=0X01;               //选中第一个数码管段选
	P2=0XFF;P0=tab[yi];            //让第一个数码管显示yi指向的值
	delayms(1);                    //延时1ms
	
	P2=0XC0;P0=0X02;               //选中第二个数码管段选
	P2=0XFF;P0=tab[er];            //让第一个数码管显示er指向的值
	delayms(1);	                   //延时1ms
}
void display2(uchar san,uchar si)//第三、四段数码管函数
{
	P2=0XC0;P0=0X04;               //选中第s三个数码管段选
	P2=0XFF;P0=tab[san];           //让第一个数码管显示san指向的值
	delayms(1);                    //延时1ms
	
	P2=0XC0;P0=0X08;               //选中第四个数码管段选
	P2=0XFF;P0=tab[si];            //让第一个数码管显示si指向的值
	delayms(1);	                   //延时1ms
}
void display3(uchar wu,uchar liu)//第五、六段数码管函数
{
	P2=0XC0;P0=0X10;               //选中第五个数码管段选
	P2=0XFF;P0=tab[wu];            //让第一个数码管显示wu指向的值
	delayms(1);                    //延时1ms
	
	P2=0XC0;P0=0X20;               //选中第六个数码管段选
	P2=0XFF;P0=tab[liu];           //让第一个数码管显示liu指向的值
	delayms(1);	                   //延时1ms
}
void display4(uchar qi,uchar ba)//第七、八段数码管函数
{
	P2=0XC0;P0=0X40;               //选中第七个数码管段选
	P2=0XFF;P0=tab[qi];            //让第一个数码管显示qi指向的值
	delayms(1);                    //延时1ms
	
	P2=0XC0;P0=0X80;               //选中第八个数码管段选
	P2=0XFF;P0=tab[ba];            //让第一个数码管显示ba指向的值
	delayms(1);                    //延时1ms
}

/*******************DS1302驱动代码************************/									

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

void Write_Ds1302(unsigned char address,unsigned char dat)     
{
 	RST=0;
	_nop_();
 	SCK=0;
	_nop_();
 	RST=1;	
  _nop_();
 	Write_Ds1302_Byte(address);	
 	Write_Ds1302_Byte((dat/10<<4)|(dat%10));		
 	RST=0; 
}

unsigned char Read_Ds1302(unsigned char address)
{
 	unsigned char i,temp=0x00,dat1,dat2;
 	RST=0;
	_nop_();
 	SCK=0;
	_nop_();
 	RST=1;
	_nop_();
 	Write_Ds1302_Byte(address);
 	for (i=0;i<8;i++) 	
 	{		
		SCK=0;
		temp>>=1;	
 		if(SDA)
 		temp|=0x80;	
 		SCK=1;
	} 
 	RST=0;
	_nop_();
 	RST=0;
	SCK=0;
	_nop_();
	SCK=1;
	_nop_();
	SDA=0;
	_nop_();
	SDA=1;
	_nop_();
	
	dat1=temp/16;
	dat2=temp%16;
	temp=dat1*10+dat2;
	
	return (temp);			
}

void DS_init()
{
	unsigned char add,i;
	add=0x80;
	Write_Ds1302(0x8e,0x00);
	for(i=0;i<7;i++)
	{
		Write_Ds1302(add,shijian[i]);
		add=add+2;
	}
	Write_Ds1302(0x8e,0x80);
}

void DS_get()
{
	unsigned char add,i;
	add=0x81;
	Write_Ds1302(0x8e,0x00);
	for(i=0;i<7;i++)
	{
		shijian[i]=Read_Ds1302(add);
		add=add+2;
	}
	Write_Ds1302(0x8e,0x80);
}

 

Guess you like

Origin blog.csdn.net/qq_45385706/article/details/115527883