OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 12100|回复: 2

DS1302时钟时间初始化

[复制链接]

23

主题

37

帖子

0

精华

初级会员

Rank: 2

积分
149
金钱
149
注册时间
2013-12-8
在线时间
0 小时
发表于 2013-12-8 22:28:00 | 显示全部楼层 |阅读模式
            

之前一直有在问DS1302的问题,这几天又想到一个问题。先上整个程序

#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit DU=P2^6;
sbit WE=P2^7;
sbit IO=P2^0;
sbit CLK=P2^1;
sbit RST=P2^4;
uchar code tab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//共阴数码管断码表
uchar second,minute,hour;
void delay(void)
{
uchar i,j;
for(j=1;j>0;j--)
for(i=110;i>0;i--) ;
}
void input(uchar byte)//写一个字节
{
uchar i;
for(i=8;i>0;i--)
{
IO=byte&0x01;
CLK=1;
CLK=0;
byte>>=1;
}
}
uchar output(void)//读一个字节
{
uchar i,dat=0;
for(i=8;i>0;i--)
{
dat>>=1;
if(IO)dat|=0x80;
CLK=1;
CLK=0;
}
return (dat);
}
void write(uchar addr,uchar dat)//在特定地址写数据
{
CLK=0;
RST=0;
RST=1;
input(addr);
input(dat);
CLK=1;
RST=0;
}
uchar read(uchar addr)//从特定地址读数据
{
uchar dat;
RST=0;
CLK=0;
RST=1;
input(addr);
dat=output();
CLK=1;
RST=0;
return(dat);
}
void init()//初始化时间,我想显示12点30分0秒
{
write(0x8e,0x00);//写保护

write(0x80,0x00);//秒 钟从0开始
write(0x82,0x30);//分钟设为30

write(0x84,0x12);//时钟设为12

}
void read_time()//读时间
{
second=read(0x81);
minute=read(0x83);
hour=read(0x85);
}
void display()//显示程序
{
WE=1;
P0=0xfe;
WE=0;
DU=1;
P0=tab[hour/16];//时钟十位
DU=0;
delay();

WE=1;
P0=0xfd;
WE=0;
DU=1;
P0=tab[hour%16];//时钟各位
DU=0;
delay();

WE=1;
P0=0xfb;
WE=0;
DU=1;
P0=tab[minute/16];
DU=0;
delay();

WE=1;
P0=0xf7;
WE=0;
DU=1;
P0=tab[minute%16];
DU=0;
delay();

WE=1;
P0=0xef;
WE=0;
DU=1;
P0=tab[second/16];
DU=0;
delay();

WE=1;
P0=0xdf;
WE=0;
DU=1;
P0=tab[second%16];
DU=0;
delay();
}
main()
{
init();
while(1)
{
read_time();
display();
}
}

问题是这样的,我想显示12点30分0秒,原本的程序是在相应的寄存器用16进制初始化,比如0x00,0x30,0x12。但我一开始不知道问什么16进制也可以写成10进制的形式“12:30:00“,毕竟10进制好理解些,我就尝试把对应的寄存器用十进制去初始化,然后在显示程序display中分别改成hour/10 hour%10 minute/10 minute%10 second/10 second%10 但这样结果是开发板上电初始化的一瞬间数码管显示是正确的,但是接下来就不正确 了,秒开始乱跳,越到后来都乱跳了,想问下为什么不能用十进制去初始化?

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

17

主题

470

帖子

1

精华

高级会员

Rank: 4

积分
718
金钱
718
注册时间
2013-11-23
在线时间
0 小时
发表于 2013-12-8 22:53:57 | 显示全部楼层
DS1302寄存器里的时间数据是BCD形式,16进制表示的十进制数,所以如果你写入的数据是十进制的话,一定要先进行BCD处理,转成16进制,这样1302才认的出来。。很多数字芯片都要注意这种问题
回复 支持 反对

使用道具 举报

120

主题

7877

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
发表于 2013-12-9 11:17:00 | 显示全部楼层
回复【楼主位】suso:
---------------------------------
我直接这样初始化
//时间参数初始化
Time_InitStructure.year = 0x13; //年
Time_InitStructure.month = 0x10; //月
Time_InitStructure.date = 0x07; //日
Time_InitStructure.week = 0x01; //星期
Time_InitStructure.hour = 0x20; //小时
Time_InitStructure.minute = 0x00; //分钟
Time_InitStructure.second = 0x00; //00秒,并启动时钟

DS1302_Init(&Time_InitStructure); //初始化时间参数

读取时间出来之后转换一下即可

/***********读取时间信息**********/
DS1302_GetTime(); //获取DS1302时间日历数据

/***********时间信息转换为ASCII码可视字符**********/
Display_Time[7] = (TimeValue.second>>4)+48;
Display_Time[8] = (TimeValue.second&0x0f)+48; //Second

Display_Time[4] = (TimeValue.minute>>4)+48;
Display_Time[5] = (TimeValue.minute&0x0f)+48; //Minute

Display_Time[1] = (TimeValue.hour>>4)+48;
Display_Time[2] = (TimeValue.hour&0x0f)+48; //Hour

Display_Date[9] = (TimeValue.date>>4)+48;
Display_Date[10] = (TimeValue.date&0x0f)+48; //Date

Display_Date[6] = (TimeValue.month>>4)+48;
Display_Date[7] = (TimeValue.month&0x0f)+48; //Month

Display_Date[3] = (TimeValue.year>>4)+48;
Display_Date[4] = (TimeValue.year&0x0f)+48; //Year

if(TimeValue.week == 0x00)
{ Display_Date[13] = 0x37; } //week
else
{ Display_Date[13] = (TimeValue.week&0x0f)+48; }
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 22:46

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表