DS1302时钟走时,分钟秒钟十位显示不出来 ,大神帮我看看
时间:10-02
整理:3721RD
点击:
#include<reg52.h>
#include"DS1302.h"
sbit P1_0=P1^0;
sbit P1_1=P1^1;
sbit P1_2=P1^2;
sbit P1_3=P1^3;
sbit LS138A=P2^2;
sbit LS138B=P2^3;
sbit LS138C=P2^4;
unsigned char code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};
unsigned char LedOut[10];
void delay(unsigned char xms)
{
unsigned int i,j;
for(i=xms;i>0;i--)
for(j=100;j>0;j--);
}
unsigned key_shijian(unsigned char n,unsigned char x,unsigned y)
{
if(P1_0==0)
{
delay(50);
if(P1_0==0)
{
n++;
if(n==x)
{
n=0;
while(P1_0==0);
}
}
}
if(P1_1==0)
{
delay(50);
if(P1_1==0)
{
if(n==0)
{
n=y;
}
else n--;
while(P1_1==0);
}
}
return n;
}
void display(uchar x1,uchar x2,uchar x3,uchar x4,uchar x5,uchar x6)
{
unsigned int i;
LedOut[0]=tab[x1];
LedOut[1]=tab[x2];
LedOut[2]=~0xbf;
LedOut[3]=tab[x3];
LedOut[4]=tab[x4];
LedOut[5]=~0xbf;
LedOut[6]=tab[x5];
LedOut[7]=tab[x6];
for(i=0;i<8;i++)
{
P0=LedOut[i];
switch(i)
{
case 0:LS138A=1; LS138B=1; LS138C=1; break;
case 1:LS138A=0; LS138B=1; LS138C=1; break;
case 2:LS138A=1; LS138B=0; LS138C=1; break;
case 3:LS138A=0; LS138B=0; LS138C=1; break;
case 4:LS138A=1; LS138B=1; LS138C=0; break;
case 5:LS138A=0; LS138B=1; LS138C=0; break;
case 6:LS138A=1; LS138B=0; LS138C=0; break;
case 7:LS138A=0; LS138B=0; LS138C=0; break;
}
delay(1);
}
}
main()
{
uchar falg;
Init_DS1302();
while(1)
{
get_time();
time[0]=second%10;
time[1]=second/10;
time[2]=minute%10;
time[3]=minute/10;
time[4]=hour%10;
time[5]=hour/10;
if(P1_2==0)
{
delay(50);
if(P1_2==0)
{
falg++;
if(falg==4) falg=0;
}
}
switch(falg)
{
case 0: display(time[0],time[1],time[2],time[3],time[4],time[5]);break;
case 1: second=key_shijian(second,60,59);
Set_time(0x80,second);
display(time[4],time[5],10,10,10,10) ;break;
case 2: minute=key_shijian(minute,60,59);
Set_time(0x82,minute);
display(10,10,time[2],time[3],10,10) ;break;
case 3: hour=key_shijian(hour,24,23);
Set_time(0x84,hour);
display(10,10,10,10,time[0],time[1]);break;
}
}
}
#ifndef DS1302_H_
#define DS1302_H_
#include<reg52.h>
#include<reg52.h>
#include<intrins.h> //包含_nop_()函数定义的头文件
sbit SCLK=P3^6; //位定义1302芯片的接口,时钟输出端口定义在P1.0引脚
sbit DATA=P3^4; //位定义1302芯片的接口,数据输出端定义在P1.1引脚
sbit RST=P3^5; //位定义1302芯片的接口,复位端口定义在P1.2引脚
#define uchar unsigned char
#define uint unsigned int
uchar data time[8];
uchar second,minute,hour, ReadValue;
/*****************************************************
函数功能:延时若干微秒
入口参数:n
***************************************************/
void delaynus(uchar n)
{
unsigned char i;
for(i=0;i<n;i++);
}
/*****************************************************
函数功能:向1302写一个字节数据
入口参数:x
***************************************************/
void Write1302(uchar dat)
{
unsigned char i;
SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备
delaynus(2); //稍微等待,使硬件做好准备
for(i=0;i<8;i++) //连续写8个二进制位数据
{
DATA=dat&0x01; //取出dat的第0位数据写入1302 低位在前,高位在后
delaynus(2); //稍微等待,使硬件做好准备
SCLK=1; //上升沿写入数据
delaynus(2); //稍微等待,使硬件做好准备
SCLK=0; //重新拉低SCLK,形成脉冲
dat>>=1; //将dat的各数据位右移1位,准备写入下一个数据位
}
}
/*****************************************************
函数功能:根据命令字,向1302写一个字节数据
入口参数:Cmd,储存命令字;dat,储存待写的数据
***************************************************/
void WriteSet1302(uchar Cmd,uchar dat)
{
RST=0; //禁止数据传递
SCLK=0; //确保写数居前SCLK被拉低
RST=1; //启动数据传输
delaynus(2); //稍微等待,使硬件做好准备
Write1302(Cmd); //写入命令字
Write1302(dat); //写数据
SCLK=1; //将时钟电平置于高电平状态
RST=0; //禁止数据传递
}
/*****************************************************
函数功能:从1302读一个字节数据
入口参数:x
***************************************************/
unsigned char Read1302(void)
{
unsigned char i,dat;
delaynus(2); //稍微等待,使硬件做好准备
for(i=0;i<8;i++) //连续读8个二进制位数据
{ dat>>=1;
if(DATA==1) //如果读出的数据是1
dat|=0x80; //将1取出,写在dat的最高位
SCLK=1; //将SCLK置于高电平,为下降沿读出
delaynus(2); //稍微等待
SCLK=0; //拉低SCLK,形成脉冲下降沿
delaynus(2); //稍微等待
}
return dat; //将读出的数据返回
}
/*****************************************************
函数功能:根据命令字,从1302读取一个字节数据
入口参数:Cmd
***************************************************/
unsigned char ReadSet1302(uchar Cmd)
{
unsigned char dat;
RST=0; //拉低RST
SCLK=0; //确保写数居前SCLK被拉低
RST=1; //启动数据传输
Write1302(Cmd); //写入命令字
dat=Read1302(); //读出数据
SCLK=1; //将时钟电平置于已知状态
RST=0; //禁止数据传递
return dat; //将读出的数据返回
}
/*****************************************************
函数功能: 1302进行初始化设置
***************************************************/
void Init_DS1302(void)
{
unsigned char flag;
flag= ReadSet1302(0x81);
if(flag&0x80) { //判断时钟芯片是否关闭
WriteSet1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令
WriteSet1302(0x80,((50/10)<<4|(50%10))); //根据写秒寄存器命令字,写入秒的初始值
WriteSet1302(0x82,((3/10)<<4|(3%10))); //根据写分寄存器命令字,写入分的初始值
WriteSet1302(0x84,((13/10)<<4|(13%10))); //根据写小时寄存器命令字,写入小时的初始值
WriteSet1302(0x90,0xa5); //打开充电功能 选择2K电阻充电方式
WriteSet1302(0x8E,0x80); //根据写状态寄存器命令字,写入保护指令
}
}
//如果不想每次都初始化时间,也就是掉电后还想让时钟继续走时的话 就用上面的语句
void get_time()
{
ReadValue = ReadSet1302(0x80); //从秒寄存器读数据
second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);//将读出数据转化
ReadValue = ReadSet1302(0x82); //从分寄存器读
minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
ReadValue = ReadSet1302(0x84); //从分寄存器读
hour=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
}
void Set_time(uchar adress,uchar dat)
{
WriteSet1302(0x8e,0x00);
WriteSet1302(adress,((dat/10)<<4|(dat%10)));
WriteSet1302(0x8e,0x10);
}
#endif
#include"DS1302.h"
sbit P1_0=P1^0;
sbit P1_1=P1^1;
sbit P1_2=P1^2;
sbit P1_3=P1^3;
sbit LS138A=P2^2;
sbit LS138B=P2^3;
sbit LS138C=P2^4;
unsigned char code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};
unsigned char LedOut[10];
void delay(unsigned char xms)
{
unsigned int i,j;
for(i=xms;i>0;i--)
for(j=100;j>0;j--);
}
unsigned key_shijian(unsigned char n,unsigned char x,unsigned y)
{
if(P1_0==0)
{
delay(50);
if(P1_0==0)
{
n++;
if(n==x)
{
n=0;
while(P1_0==0);
}
}
}
if(P1_1==0)
{
delay(50);
if(P1_1==0)
{
if(n==0)
{
n=y;
}
else n--;
while(P1_1==0);
}
}
return n;
}
void display(uchar x1,uchar x2,uchar x3,uchar x4,uchar x5,uchar x6)
{
unsigned int i;
LedOut[0]=tab[x1];
LedOut[1]=tab[x2];
LedOut[2]=~0xbf;
LedOut[3]=tab[x3];
LedOut[4]=tab[x4];
LedOut[5]=~0xbf;
LedOut[6]=tab[x5];
LedOut[7]=tab[x6];
for(i=0;i<8;i++)
{
P0=LedOut[i];
switch(i)
{
case 0:LS138A=1; LS138B=1; LS138C=1; break;
case 1:LS138A=0; LS138B=1; LS138C=1; break;
case 2:LS138A=1; LS138B=0; LS138C=1; break;
case 3:LS138A=0; LS138B=0; LS138C=1; break;
case 4:LS138A=1; LS138B=1; LS138C=0; break;
case 5:LS138A=0; LS138B=1; LS138C=0; break;
case 6:LS138A=1; LS138B=0; LS138C=0; break;
case 7:LS138A=0; LS138B=0; LS138C=0; break;
}
delay(1);
}
}
main()
{
uchar falg;
Init_DS1302();
while(1)
{
get_time();
time[0]=second%10;
time[1]=second/10;
time[2]=minute%10;
time[3]=minute/10;
time[4]=hour%10;
time[5]=hour/10;
if(P1_2==0)
{
delay(50);
if(P1_2==0)
{
falg++;
if(falg==4) falg=0;
}
}
switch(falg)
{
case 0: display(time[0],time[1],time[2],time[3],time[4],time[5]);break;
case 1: second=key_shijian(second,60,59);
Set_time(0x80,second);
display(time[4],time[5],10,10,10,10) ;break;
case 2: minute=key_shijian(minute,60,59);
Set_time(0x82,minute);
display(10,10,time[2],time[3],10,10) ;break;
case 3: hour=key_shijian(hour,24,23);
Set_time(0x84,hour);
display(10,10,10,10,time[0],time[1]);break;
}
}
}
#ifndef DS1302_H_
#define DS1302_H_
#include<reg52.h>
#include<reg52.h>
#include<intrins.h> //包含_nop_()函数定义的头文件
sbit SCLK=P3^6; //位定义1302芯片的接口,时钟输出端口定义在P1.0引脚
sbit DATA=P3^4; //位定义1302芯片的接口,数据输出端定义在P1.1引脚
sbit RST=P3^5; //位定义1302芯片的接口,复位端口定义在P1.2引脚
#define uchar unsigned char
#define uint unsigned int
uchar data time[8];
uchar second,minute,hour, ReadValue;
/*****************************************************
函数功能:延时若干微秒
入口参数:n
***************************************************/
void delaynus(uchar n)
{
unsigned char i;
for(i=0;i<n;i++);
}
/*****************************************************
函数功能:向1302写一个字节数据
入口参数:x
***************************************************/
void Write1302(uchar dat)
{
unsigned char i;
SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备
delaynus(2); //稍微等待,使硬件做好准备
for(i=0;i<8;i++) //连续写8个二进制位数据
{
DATA=dat&0x01; //取出dat的第0位数据写入1302 低位在前,高位在后
delaynus(2); //稍微等待,使硬件做好准备
SCLK=1; //上升沿写入数据
delaynus(2); //稍微等待,使硬件做好准备
SCLK=0; //重新拉低SCLK,形成脉冲
dat>>=1; //将dat的各数据位右移1位,准备写入下一个数据位
}
}
/*****************************************************
函数功能:根据命令字,向1302写一个字节数据
入口参数:Cmd,储存命令字;dat,储存待写的数据
***************************************************/
void WriteSet1302(uchar Cmd,uchar dat)
{
RST=0; //禁止数据传递
SCLK=0; //确保写数居前SCLK被拉低
RST=1; //启动数据传输
delaynus(2); //稍微等待,使硬件做好准备
Write1302(Cmd); //写入命令字
Write1302(dat); //写数据
SCLK=1; //将时钟电平置于高电平状态
RST=0; //禁止数据传递
}
/*****************************************************
函数功能:从1302读一个字节数据
入口参数:x
***************************************************/
unsigned char Read1302(void)
{
unsigned char i,dat;
delaynus(2); //稍微等待,使硬件做好准备
for(i=0;i<8;i++) //连续读8个二进制位数据
{ dat>>=1;
if(DATA==1) //如果读出的数据是1
dat|=0x80; //将1取出,写在dat的最高位
SCLK=1; //将SCLK置于高电平,为下降沿读出
delaynus(2); //稍微等待
SCLK=0; //拉低SCLK,形成脉冲下降沿
delaynus(2); //稍微等待
}
return dat; //将读出的数据返回
}
/*****************************************************
函数功能:根据命令字,从1302读取一个字节数据
入口参数:Cmd
***************************************************/
unsigned char ReadSet1302(uchar Cmd)
{
unsigned char dat;
RST=0; //拉低RST
SCLK=0; //确保写数居前SCLK被拉低
RST=1; //启动数据传输
Write1302(Cmd); //写入命令字
dat=Read1302(); //读出数据
SCLK=1; //将时钟电平置于已知状态
RST=0; //禁止数据传递
return dat; //将读出的数据返回
}
/*****************************************************
函数功能: 1302进行初始化设置
***************************************************/
void Init_DS1302(void)
{
unsigned char flag;
flag= ReadSet1302(0x81);
if(flag&0x80) { //判断时钟芯片是否关闭
WriteSet1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令
WriteSet1302(0x80,((50/10)<<4|(50%10))); //根据写秒寄存器命令字,写入秒的初始值
WriteSet1302(0x82,((3/10)<<4|(3%10))); //根据写分寄存器命令字,写入分的初始值
WriteSet1302(0x84,((13/10)<<4|(13%10))); //根据写小时寄存器命令字,写入小时的初始值
WriteSet1302(0x90,0xa5); //打开充电功能 选择2K电阻充电方式
WriteSet1302(0x8E,0x80); //根据写状态寄存器命令字,写入保护指令
}
}
//如果不想每次都初始化时间,也就是掉电后还想让时钟继续走时的话 就用上面的语句
void get_time()
{
ReadValue = ReadSet1302(0x80); //从秒寄存器读数据
second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);//将读出数据转化
ReadValue = ReadSet1302(0x82); //从分寄存器读
minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
ReadValue = ReadSet1302(0x84); //从分寄存器读
hour=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
}
void Set_time(uchar adress,uchar dat)
{
WriteSet1302(0x8e,0x00);
WriteSet1302(adress,((dat/10)<<4|(dat%10)));
WriteSet1302(0x8e,0x10);
}
#endif
void get_time()
{
ReadValue = ReadSet1302(0x80); //从秒寄存器读数据
second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);//将读出数据转化
ReadValue = ReadSet1302(0x82); //从分寄存器读
minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
ReadValue = ReadSet1302(0x84); //从分寄存器读
hour=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
}
中ReadValue&0x70 你把数据清理了,然后位移在*10 还是0啊
那应该改成什么样的?
在void get_time()中 ReadSet1302();括号里的应该是读数据的地址吧....那个 0x80 、0x82 、0x84 好像是写数据的地址吧。把它改回读的地址不知道能不能解决咧
读数据地址0x81、0x83、0x85