当前位置: 首页 > >

蓝桥杯单片机CT107D_17_实时时钟DS1302的基本操作

发布时间:

驱动


//SPI.h
#include
#include

sbit SCLK = P1^7;
sbit RST = P1^3;
sbit DSIO = P2^3;

void DS1302_WriteByte(unsigned char addr, unsigned char dat); //单字节写的时序
unsigned char DS1302_ReadByte(unsigned char addr); //单字节读的时序

//SPI.c
#include

//单字节写的时序
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_();
}

//单字节读的时序
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_();
//dat = (((dat>>4)*10) | (dat%16));
return dat;
}

主程序


#include
#include
unsigned char code WRITE_RTC_ADDR[7] =
{0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //定义写操作的日历时钟寄存器地址
unsigned char code READ_RTC_ADDR[7] =
{0x81,0x83,0x85,0x87,0x89,0x8b,0xbd}; //定义读操作的日历时钟寄存器地址
unsigned char TIME[7] =
{0x30,0x50,0x23,0x18,0x02,0x02,0x20}; //定义日历时钟寄存器配置参数(秒、分、时、日、月、星期、年)
unsigned char code SEG_code[18] =
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,
0xbf,0x7f}; //定义共阳数码管段码内容:0~F,?,.

//时间参数配置
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]);
}
}

//端口选择
void Select_HC138(unsigned char n)
{
switch(n)
{
case 5:
P2 = (P2 & 0x1f) | 0xa0;
break;
case 6:
P2 = (P2 & 0x1f) | 0xc0;
break;
case 7:
P2 = (P2 & 0x1f) | 0xe0;
break;
}
}

//数码管延时函数
void Delay_tube(unsigned char t)
{
while(t--);
}

//数码管显示
void Show_tube(unsigned char position,unsigned char value)
{
Select_HC138(6);
P0 = 0x01 << position;
Select_HC138(7);
P0 = value;
}

//数码管动态显示
void Display_tube()
{
Show_tube(0,SEG_code[TIME[2]/16]); //显示时的十位(TIME[n]为16进制数,所以除以16)
Delay_tube(500);
Show_tube(1,SEG_code[TIME[2]%16]); //显示时的个位
Delay_tube(500);

Show_tube(2,SEG_code[16]); //显示分隔符
Delay_tube(500);

Show_tube(3,SEG_code[TIME[1]/16]); //显示分的十位
Delay_tube(500);
Show_tube(4,SEG_code[TIME[1]%16]); //显示分的个位
Delay_tube(500);

Show_tube(5,SEG_code[16]); //显示分隔符
Delay_tube(500);

Show_tube(6,SEG_code[TIME[0]/16]); //显示秒的十位
Delay_tube(500);
Show_tube(7,SEG_code[TIME[0]%16]); //显示秒的个位
Delay_tube(500);
}

//主函数
void main()
{
Select_HC138(5);
P0 = 0x00; //关闭蜂鸣器和继电器
DS1302_Config();
while(1)
{
DS1302_ReadTime();
Display_tube();
}
}



友情链接: