蓝桥杯51单片机-ds1302的应用

基本功能:在开发平台上通过读取ds1302在数码管上按时分秒显示任意时间

我们先来了解ds1302

1.什么是ds1302

DS1302是美国DALLAS公司推出的高性能、低功耗的实时时钟

在DS1302中有两块存储器:日历时钟寄存器和今天RAM存储器。前者用于记录实时时间,后者用于记录其他数据。对于基本计时应用,重点关注的是日历时钟寄存器。设定时间参数就是往这些寄存器写入内容,读取实时时间也是从这些寄存器读出数据。

2、日历时钟寄存器
    DS1302有关日历和时钟的寄存器有12个,我们最常用的有7个。

什么是BCD码?
   就是用十六进制来表示十进制。什么意思?怎么理解?
   例如,十六进制数0x13的值为整数19,但BCD码表示的是整数13

3、控制字的格式
    DS1302将地址和读写控制放到一个字节里面,形成一个控制字,格式如下:

通过上面的控制字格式,大家就可以明白为什么DS1302读寄存器和写寄存器的地址是不一样的了,因为这个地址包含了读写控制位。为了方便程序设计,我们把读寄存器地址、写寄存器地址和日历时钟寄存器方面用三个数组定义。

4.底层驱动

<1> 单字节写的时序

void DS1302_WriteByte(unsigned char addr, unsigned char dat)
{
        unsigned char n;
        RST = 0;
        _nop_();
        SCLK = 0;
        _nop_();
        RST = 1;
        _nop_();        

        for (n=0; n<8; n++)         //发送要写入数据的内存地址
        {
                DSIO = addr & 0x01;
                addr >>= 1;
                SCLK = 1;
                _nop_();
                SCLK = 0;
                _nop_();
        }
        for (n=0; n<8; n++)         //将指定内容写入该地址的内存
        {
                DSIO = dat & 0x01;
                dat >>= 1;
                SCLK = 1;
                _nop_();
                SCLK = 0;
                _nop_();
        }                 
        RST = 0;
        _nop_();
}

<2> 单字节读的时序

unsigned char DS1302_ReadByte(unsigned char addr)
{
        unsigned char n,dat,tmp;
        RST = 0;
        _nop_();
        SCLK = 0;
        _nop_();
        RST = 1;
        _nop_();

        for(n=0; n<8; n++)         //发送要读出数据的内存地址
        {
                DSIO = addr & 0x01;
                addr >>= 1;
                SCLK = 1;
                _nop_();
                SCLK = 0;
                _nop_();
        }
        
        for(n=0; n<8; n++)         //读出该地址内存的数据
        {
                tmp = DSIO;
                dat = (dat>>1) | (tmp<<7);
                SCLK = 1;
                _nop_();
                SCLK = 0;
                _nop_();
        }

        RST = 0;
        _nop_();
        SCLK = 1;
        _nop_();
        DSIO = 0;
        _nop_();
        DSIO = 1;
        _nop_();
        return dat;        
}

5.代码函数

日历时钟参数配置函数

unsigned char code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};

unsigned char code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};

unsigned char TIME[7] = {0x30, 0x50, 0x23, 0x17, 0x02, 0x06, 0x18};


void DS1302_Config()

{

        unsigned char n;

        DS1302_WriteByte(0x8E,0x00); 

        for (n=0; n<7; n++) 

        {

                DS1302_WriteByte(WRITE_RTC_ADDR[n],TIME[n]);        

        }

        DS1302_WriteByte(0x8E,0x80); 

}


日历时钟数据读取函数


void DS1302_ReadTime()

{

        unsigned char n;

        for (n=0; n<7; n++) 

        {

                TIME[n] = DS1302_ReadByte(READ_RTC_ADDR[n]);

        }                

}

6.代码编写(采用官方驱动)

#include "regx52.h"
#include "ds1302.h"
#include "intrins.h"
unsigned char code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
 
unsigned char code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
 
// unsigned char TIME[7] = {0x30, 0x50, 0x23, 0x17, 0x02, 0x06, 0x18};//2018/周六/2.17/23:50:30
unsigned char TIME[7] = {0x14, 0x45, 0x11, 0x17, 0x03, 0x07, 0x24};//BCD码,可以看作十进制


unsigned char code SMG_duanma[18]=
		{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
     0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
     0xbf,0x7f};
		 
unsigned char SMG[]={18,18,18,18,18,18,18,18};

void Delay1ms()		//@11.0592MHz
{
	unsigned char i, j;

	_nop_();
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
}

void SelectHC138(unsigned char n)
{
	switch(n)
	{
		case 4:
			P2 = (P2 & 0x1f) | 0x80;
		break;
		case 5:
			P2 = (P2 & 0x1f) | 0xa0;
		break;
		case 6:
			P2 = (P2 & 0x1f) | 0xc0;
		break;
		case 7:
			P2 = (P2 & 0x1f) | 0xe0;
		break;
		case 0:
			P2 = (P2 & 0x1f) | 0x00;		//所有锁存器不选择
		break;
	}
}
		 
void ShowSMG_Bit(unsigned char dat, unsigned pos)
{
	P0=0xff;
	SelectHC138(6);			//数码管的位置
	P0 = 0x01 << pos;
	SelectHC138(7);			//数码管的内容
	P0 = dat;
}

void DS1302_Config()
 
{
 
        unsigned char n;
 
       Ds1302_Single_Byte_Write(0x8E,0x00); 
 
        for (n=0; n<7; n++) 
 
        {
 
                Ds1302_Single_Byte_Write(WRITE_RTC_ADDR[n],TIME[n]);        
 
        }
 
       Ds1302_Single_Byte_Write(0x8E,0x80); 
 
}
 
 
void DS1302_ReadTime()
 
{
 
        unsigned char n;
 
        for (n=0; n<7; n++) 
 
        {
 
                TIME[n] = Ds1302_Single_Byte_Read(READ_RTC_ADDR[n]);
				Ds1302_Single_Byte_Write(0x00, 0x00);//必须得加,否则数据会混乱
 
        }                
 
}

void DisplaySMG()
{
	SMG[0]=TIME[2]/16;
	SMG[1]=TIME[2]%16;
	
	SMG[2]=SMG[5]=16;
	SMG[3]=TIME[1]/16;
	SMG[4]=TIME[1]%16;
	
	SMG[6]=TIME[0]/16;
	SMG[7]=TIME[0]%16;
	
	ShowSMG_Bit(SMG_duanma[SMG[0]], 0);
	Delay1ms();
	ShowSMG_Bit(SMG_duanma[SMG[1]], 1);
	Delay1ms();
	ShowSMG_Bit(SMG_duanma[SMG[2]], 2);
	Delay1ms();
	ShowSMG_Bit(SMG_duanma[SMG[3]], 3);
	Delay1ms();
	ShowSMG_Bit(SMG_duanma[SMG[4]], 4);
	Delay1ms();
	ShowSMG_Bit(SMG_duanma[SMG[5]], 5);
	Delay1ms();
	ShowSMG_Bit(SMG_duanma[SMG[6]], 6);
	Delay1ms();
	ShowSMG_Bit(SMG_duanma[SMG[7]], 7);
	Delay1ms();
	ShowSMG_Bit(0xff, 7);
}

void main()
{
	DS1302_Config();
	while(1)
	{
		DS1302_ReadTime();
		DisplaySMG();
	}

}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值