在蓝桥杯单片机当中,可以通过DS1302的芯片,显示实时时钟
各引脚的功能为: Vcc1:主电源;Vcc2:备份电源。当Vcc2>Vcc1+0.2V时,由Vcc2 向DS1302供电,当Vcc2,SCLK:串行时钟,输入,控制数据的输入与输出;I/O:三线接口时的双向数据线;CE:输入信号,在读、写数据期间,必须为高。该引脚有两个功能: 第一,CE开始控制字访问移位寄存器的控制逻辑;其次,CE提供结束单字节或多字节数据传输的方法。
如图,所示 CE输入驱动高启动所有的数据传输。
CE输入有两个功能。首先,CE打开控制逻辑,允许访问的移位寄存器的地址 /命令序列。
其次,CE提供了一个终止单字节或多字节数据传输方法。 一个时钟周期是由一个下降沿之后的上升沿序列。
对于数据传输而言,数据必 须在有效的时钟的上升沿输入,在时钟的下降沿输出。如果CE为低,所有的I / O引脚变为高阻抗状态,数据传输终止。
对于数据输入: 开始的8个SCLK周期,输入写命令字节,数据字节在后8个SCLK周期的 上升沿输入。数据输入位0开始。
对于数据输出: 开始的8个SCLK周期,输入一个读命令字节,数据字节在后8个SCLK周 期的下降沿输出。
注意,第一个数据字节的第一个下降沿发生后,命令字的最 后一位被写入(Notethat the first data bit to be transmitted occurs on the first falling edge after the last bit of the command byte is written. ),命令字节的最后一位被写入。当CE仍为高时。如果还有额外的 SCLK 周期,DS1302将重新发送数据字节,这使DS1302具有连续突发读取的 能力。
时间显示时序,通过通过BCD码来显示相关时间
#include <STC15F2K60S2.H>
#include <ds1302.h>
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 Write_DS1302_ADDR[7] = {0x80,0x82,0x84,0x86,0x88,0xa0,0xc0};
unsigned char Read_DS1302_ADDR[7] = {0x81,0x83,0x85,0x87,0x89,0xb0,0xd0};
//miao fen shi tian
unsigned char TIME[4] = {0x23,0x50,0x23,0x22};
void Select_HC573(unsigned char channl)
{
switch(channl)
{
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;
}
}
void Init_SMG(unsigned char date,unsigned char pos)
{
Select_HC573(6);
P0 = 0X01 << pos;
Select_HC573(7);
P0 = date;
}
//void SMG_DOWN(unsigned char down)
//{
// Select_HC573(6);
// P0 = 0xff;
// Select_HC573(7);
// P0 = down;
//}
//
void SMG_show()
{
static i;
i++;
if(i == 9) i = 1;
switch(i)
{
case 1:
Init_SMG(SMG_duanma[TIME[2] / 16],0);
break;
case 2:
Init_SMG(SMG_duanma[TIME[2] % 16],1);
break;
case 3:
Init_SMG(0xbf,2);
break;
case 4:
Init_SMG(SMG_duanma[TIME[1] / 16],3);
break;
case 5:
Init_SMG(SMG_duanma[TIME[1] % 16],4);
break;
case 6:
Init_SMG(0xbf,5);
break;
case 7:
Init_SMG(SMG_duanma[TIME[0] / 16],6);
break;
case 8:
Init_SMG(SMG_duanma[TIME[0] % 16],7);
break;
//SMG_DOWN(0xff);
}
}
void Init_Timer()
{
TMOD = 0x01;
TH0 = (65535 - 500) / 256;
TL0 = (65535 - 500) % 256;
ET0 = 1;
TR0 = 1;
EA = 1;
}
void Service_Timer() interrupt 1
{
TH0 = (65535 - 500) / 256;
TL0 = (65535 - 500) % 256;
SMG_show();
}
void Write_DS1302_SMG()
{
unsigned char i;
Write_Ds1302_Byte(0x8e,0x00);
for(i = 0;i < 3; i++)
{
Write_Ds1302_Byte(Write_DS1302_ADDR[i],TIME[i]);
}
Write_Ds1302_Byte(0x8e,0x80);
}
void Read_DS1302_SMG()
{
unsigned char i;
for(i = 0; i < 3;i++)
{
TIME[i] = Read_Ds1302_Byte(Read_DS1302_ADDR[i]);
}
}
void main()
{
Init_Timer();
Write_DS1302_SMG();
while(1)
{
Read_DS1302_SMG();
}
}
/* # DS1302代码片段说明
1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
中对单片机时钟频率的要求,进行代码调试和修改。
*/
//
#include <reg52.h>
#include <intrins.h>
sbit SCK = P1^7;
sbit SDA = P2^3;
sbit RST = P1^3;
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);
}
#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