项目12—DS1302实时时钟

DS1302是一种串行接口的实时时钟,芯片内部具有可编程的日历时钟和31个字节的静态RAM。

仿真:

程序:

main.c

#include<reg51.h>
#include<ds1302.c>
unsigned int cp0,cp1;
unsigned char flash;
bit flag;
unsigned char smg[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
#include<display.c>
void timer0_isr(void) interrupt 1
{
	TH0 = (65536 - 1000) / 256;
	TL0 = (65536 - 1000) % 256;	
	cp0++;cp1++;		           
	if(cp0 >= 500)					  
	{get_ds1302();cp0 = 0;flash = ~flash;}   
	if(cp1>=2000)
	{
		cp1 = 0;
		flag = ~flag;
	}
	if(flag == 0)display0();	
	if(flag == 1)display1();			 
}
void timer0_init(void)
{
	TMOD = 0x01;	  
	TH0 = (65536 - 1000) / 256;	  
	TL0 = (65536 - 1000) % 256;
	EA = 1;			   
	ET0 = 1;		   
	TR0 = 1;		   
}
void main(void)
{
	timer0_init();		
	write_init_time();
	while(1)
	{				
	}
}

 DS1302.C

sbit CE = P3^5;
sbit SCLK = P3^6;
sbit IO = P3^7;
unsigned char sec = 30,min = 55,hour = 20,day = 21,month = 1, year = 21,week;
void ds1302_init()//初始化
{
	CE = 0;
	SCLK = 0;
	CE = 1;    //允许读写数据
}
/*对ds1302写一字节数据*/
void write_ds1302_onebyte(unsigned char dat)
{
	unsigned char i;
	for(i = 0;i < 8;i++)
	{
		SCLK = 0;
		IO = (bit)(dat & 0x01);  // 0001 & 0001 //把写入的数据取出来给DS1302
		SCLK = 1;
		dat = dat >> 1; //每取一次 移一位 
	}
}	
/*从DS1302里面读出一字节数据*/
unsigned char read_ds1302_onebyte()
{
	unsigned char i,j;
	for(i = 0;i<8;i++)
	{
		SCLK = 1;
		SCLK = 0;
		j = j >> 1; //移位
		if(IO)j = j | 0X80;  //一位一位的读取数据
	}
	return(j);//8421BCD码
}
/*对DS1302某一地址写数据*/
void write_ds1302_add_dat(unsigned char add,unsigned char dat)
{
	ds1302_init();
	write_ds1302_onebyte(add);
	write_ds1302_onebyte(dat);
	CE = 0; //关闭CE不再读写数据 IO SCLK 变为高阻态(断路)
}
/*从DS1302里面读出数据*/
unsigned char read_ds1302_add(unsigned char add)
{
	unsigned char dat_temp;
	ds1302_init();
	write_ds1302_onebyte(add);
	dat_temp = read_ds1302_onebyte();
	CE = 0;
	return(dat_temp);
}
/*8421BCD码转十进制*/
unsigned char BCD_DEC(unsigned char x)
{	
	unsigned char dec;
	dec = x & 0x0f; //取出低四位
	x = x >> 4; //挤出低四位,把高四位放到地位
	dec = x*10 + dec;
	return(dec);
}
/*十进制转8421BCD码*/
unsigned char DEC_BCD(unsigned char x)
{
	unsigned char bcd;
	bcd = x % 10;//取出十进制的个位
	x = x / 10;//取出十进制的十位
	x = x << 4;
	bcd = bcd | x;
	return(bcd);
}
/*单片机向DS1302里面写数据*/
void write_init_time()
{
	write_ds1302_add_dat(0x8e,0x00);//关闭保护
	write_ds1302_add_dat(0x80,DEC_BCD(sec));//写秒
	write_ds1302_add_dat(0x82,DEC_BCD(min));//写分
	write_ds1302_add_dat(0x84,DEC_BCD(hour));//写时
	write_ds1302_add_dat(0x86,DEC_BCD(day));//写日
	write_ds1302_add_dat(0x88,DEC_BCD(month));//写月
	write_ds1302_add_dat(0x8A,DEC_BCD(week));//写周
	write_ds1302_add_dat(0x8C,DEC_BCD(year));//写年
	write_ds1302_add_dat(0x8e,0x10);//打开保护
}
/*单片机从DS1302里面得到时间数据*/
void get_ds1302()
{
	unsigned char R;
	R = read_ds1302_add(0x81);//读秒
	sec = BCD_DEC(R);
	R = read_ds1302_add(0x83);//读分
	min = BCD_DEC(R);
	R = read_ds1302_add(0x85);//读时
	hour = BCD_DEC(R);
	R = read_ds1302_add(0x87);//读日
	day = BCD_DEC(R);
	R = read_ds1302_add(0x89);//读月
	month = BCD_DEC(R);
	R = read_ds1302_add(0x8B);//读周
	week = BCD_DEC(R);
	R = read_ds1302_add(0x8D);//读年
	year = BCD_DEC(R);
}

DISPLAY.C

char k;
void display0(void)	  		
{
	P0 = 0xff;
	switch(k)
	{
		case 0:P1 = 0x01;P0 = smg[sec % 10];break;
		case 1:P1 = 0x02;P0 = smg[sec / 10];break;
		case 2:P1 = 0x04;P0 = 0xbf | flash;break;
		case 3:P1 = 0x08;P0 = smg[min % 10];break;
		case 4:P1 = 0x10;P0 = smg[min / 10];break;
		case 5:P1 = 0x20;P0 = 0xbf | flash;break;
		case 6:P1 = 0x40;P0 = smg[hour % 10];break;
		case 7:P1 = 0x80;P0 = smg[hour / 10];break;
	}
	k++;
	if(k>=8)k = 0;
}
void display1(void)	 	  
{
	P0 = 0xff;
	switch(k)
	{
		case 0:P1 = 0x01;P0 = smg[day % 10];break;
		case 1:P1 = 0x02;P0 = smg[day / 10];break;
		case 2:P1 = 0x04;P0 = 0xbf;break;
		case 3:P1 = 0x08;P0 = smg[month % 10];break;
		case 4:P1 = 0x10;P0 = smg[month / 10];break;
		case 5:P1 = 0x20;P0 = 0xbf;break;
		case 6:P1 = 0x40;P0 = smg[year % 10];break;
		case 7:P1 = 0x80;P0 = smg[year / 10];break;
	}
	k++;
	if(k>=8)k = 0;
}

运行结果:

 

20:55:47为时间

21—01—21为 日期

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

单旦羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值