蓝桥杯 ds1302

  今年寒假在学校准备蓝桥杯,之前没有写过博客,想着乘着这次机会尝试一下,顺便加强一下蓝桥杯的练习。有什么我说的不对的地方,还请大家指正,谢谢了。
因为之前已经开始练习了蓝桥杯,所以就从ds1302开始,之前的流水灯,数码管,蜂鸣器已经继电器,就先不说。首先就是ds1302的驱动,这个不多说驱动网上都有,这里只是提供一个方便。(注意,向ds1302直接输入时分秒时不能直接写入,必须先把十进制的数据转化为BCD码,这时候写入才是有效的数据)

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


#include <intrins.h>


sbit SCK=P1^7;		
sbit SDA=P2^3;		
sbit RST = P1^3;   // 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);		
 	RST=0; 
}
unsigned char Read_Ds1302 ( unsigned char address )
{
 	unsigned char i,temp=0x00;
 	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_();
	return (temp);			
}
//--------------------------------------------------------------------------------------------
static int year,month,day,hour,min,sec;//定义的全局变量,为了方便写显示函数
int DEC_BCD(unsigned char dat)
{	
	unsigned char BCD;
	BCD = dat / 10;
	BCD <<= 4;
	dat = dat % 10;
	BCD = BCD | dat;
	return BCD;	
}
int BCD_DEC(unsigned char dat)
{
	unsigned char DEC;
	DEC = dat & 0x0f;
	dat >>= 4;
	DEC = dat * 10 + DEC;
	return DEC;
}
void read_ds1302()
{
	unsigned char t;
//	EA = 0;
	t = Read_Ds1302(0x81);sec  =  BCD_DEC(t);
	t = Read_Ds1302(0x83);min  =  BCD_DEC(t);
	t = Read_Ds1302(0x85);hour =  BCD_DEC(t);
	t = Read_Ds1302(0x87);day  =  BCD_DEC(t);
	t = Read_Ds1302(0x89);month = BCD_DEC(t);
	t = Read_Ds1302(0x8d);year =  BCD_DEC(t);
//	EA = 1;
}
void write_ds1302()
{
	Write_Ds1302(0x8e,0x00);//注意这里在写入是必须有
	Write_Ds1302(0x80,DEC_BCD(sec_t));
	Write_Ds1302(0x82,DEC_BCD(min_t));
	Write_Ds1302(0x84,DEC_BCD(hour_t));
	Write_Ds1302(0x86,DEC_BCD(day_t));
	Write_Ds1302(0x88,DEC_BCD(month_t));
	Write_Ds1302(0x8c,DEC_BCD(year_t));
	Write_Ds1302(0x8e,0x80);
}
我现在写的ds1302是电子表的时间,其中对于这种题目最重要的是显示部分,只有把显示的部分调好了,才能正确的调试出你想要的结果(当然不绝对),因为是显示时分秒,年月日所以我把显示分成了两部分(这是显示时分秒的,显示年月日的大部分一样,只是seven_duan[]中的变量不一样)
unsigned char seven_duan[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
    unsigned char seven_wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; 
void display0()
{
	char m;
	switch(m)
	{
		case 0:dis_play(seven_wei[7],seven_duan[sec%10]);break;
		case 1:dis_play(seven_wei[6],seven_duan[sec/10]);break;
		case 2:dis_play(seven_wei[5],0xbf|flash);break;
		case 3:dis_play(seven_wei[4],seven_duan[min%10]);break;
		case 4:dis_play(seven_wei[3],seven_duan[min/10]);break;
		case 5:dis_play(seven_wei[2],0xbf|flash);break;
		case 6:dis_play(seven_wei[1],seven_duan[hour%10]);break;
		case 7:dis_play(seven_wei[0],seven_duan[hour/10]);break;
	}
	m++;
	if(m >= 8) m = 0;
}
而其中的dis_play函数是
sfr P4 = 0xc0;
sbit wr = P4^2;

void dis_play(unsigned char x,unsigned char y)
{
	wr = 0;

	P2 = (P2&0x1f)|0xe0;    //打开控制数码管的段选的573
	P0 = 0xff;
	P2 &= 0x1f;         //把138的Y0置低

	P2 = (P2&0x1f)|0xc0;//打开控制数码管的位选的573
	P0 = x;         //控制数码管显示的位置
	P2 &= 0x1f;

	P2 = (P2&0x1f)|0xe0;
	P0 = y;       //控制数码管显示的段数
	P2 &= 0x1f;
	wr = 1;
	P0 = 0x00;
	P2 = 0x00;
}
鉴于本人比较菜,所以大家理解一下,我放中断和主函数了(我上了,不怂)
sfr AUXR = 0xa2;
void timer0_isr() interrupt 1
{
	TH0 = (65536-2000)/256;
	TL0 = (65536-2000)/256;
	cp++; 
	if(cp >= 500) 
	{                        
		cp = 0;	 
		flash = ~ flash; //为了使电子表看起来更像,加了个闪烁的变量
		cp1++; 
		read_ds1302();//一秒一读
	}	
	if(cp1 >= 2)
	{
		cp1 = 0;
		flag++;
		if(flag == 2) flag = 0;		 
	}
	if(flag == 0 && mode == 0)//这样写是为了,我之后写一个可调的电子表
		display0();
	if(flag == 1 && mode == 0)
		display1();	

}
void timer0_init()            
{
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD |= 0x01;
	TH0 = (65536 - 2000)/256;    //2ms
	TL0 = (65536 - 2000)/256;
	EA = 1;
	ET0 = 1;
	TR0 = 1;
}
void main()
{
	timer0_init();
	while(1);
}
大家可以直接用STC公司的软件直接计算定时器的初值,好了,这就是我想说的ds1302的程序。大家可以留下自己想对我说的话,有需要的程序或者帮助话,我会回复的。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值