时钟是可以走的,但为什么数码管会闪?延时问题还是1302时序问题?请教。。。:handshake
#include<reg52.h>
sbit ds1302_clk=P3^4;
sbit ds1302_io=P3^6;
sbit ds1302_rst=P3^5;
sbit LATCH1=P2^6;
sbit LATCH2=P2^7;
unsigned char code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char code WeiMa[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
unsigned char data1[8];
unsigned char second,minute,hour;
unsigned char
time[]={0x12,0x30,0x00};
void delay(unsigned char i) //延时子程序
{
unsigned char j;
while((i--)!=0)
{
for(j=123;j>0;j--);
}
}
void delaynus(unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++);
}
void display(void)//数码管显示子函数;
{ unsigned char j;
data1[0]=hour/16;
data1[1]=hour%16;
data1[3]=minute/16;
data1[4]=minute%16;
data1[6]=second/16;
data1[7]=second%16;
for(j=0;j<8;j++)
{
if(j==2||j==5)
{LATCH1=1;
P0=0xbf;
LATCH1=0;
P0=0x00;
LATCH2=1;
P0=WeiMa[j];
LATCH2=0;
}
else
{LATCH1=1;
P0=tab[data1[j]];
LATCH1=0;
P0=0x00;
LATCH2=1;
P0=WeiMa[j];
LATCH2=0;
}
delay(1);
}
}
void Write1302(unsigned char dat)
{
unsigned char i;
ds1302_clk=0; //拉低SCLK,为脉冲上升沿写入数据做好准备
delaynus(2); //稍微等待,使硬件做好准备
for(i=0;i<8;i++) //连续写8个二进制位数据
{
ds1302_io=dat&0x01; //取出dat的第0位数据写入1302
delaynus(2); //稍微等待,使硬件做好准备
ds1302_clk=1; //上升沿写入数据
delaynus(2); //稍微等待,使硬件做好准备
ds1302_clk=0; //重新拉低SCLK,形成脉冲
dat>>=1; //将dat的各数据位右移1位,准备写入下一个数据位
}
}
unsigned char Read1302(void)
{
unsigned char i,dat;
delaynus(2); //稍微等待,使硬件做好准备
for(i=0;i<8;i++) //连续读8个二进制位数据
{
dat>>=1; //将dat的各数据位右移1位,因为先读出的是字节的最低位
if(ds1302_io==1) //如果读出的数据是1
dat|=0x80; //将1取出,写在dat的最高位
ds1302_clk=1; //将SCLK置于高电平,为下降沿读出
delaynus(2); //稍微等待
ds1302_clk=0; //拉低SCLK,形成脉冲下降沿
delaynus(2); //稍微等待
}
return dat; //将读出的数据返回
}
void WriteSet1302(unsigned char Cmd,unsigned char dat)
{
ds1302_rst=0; //禁止数据传递
ds1302_clk=0; //确保写数居前SCLK被拉低
ds1302_rst=1; //启动数据传输
delaynus(2); //稍微等待,使硬件做好准备
Write1302(Cmd); //写入命令字
Write1302(dat); //写数据
ds1302_clk=1; //将时钟电平置于已知状态
ds1302_rst=0; //禁止数据传递
}
unsigned char ReadSet1302(unsigned char Cmd)
{
unsigned char dat;
ds1302_rst=0; //拉低RST
ds1302_clk=0; //确保写数居前SCLK被拉低
ds1302_rst=1; //启动数据传输
Write1302(Cmd); //写入命令字
dat=Read1302(); //读出数据
ds1302_clk=1; //将时钟电平置于已知状态
ds1302_rst=0; //禁止数据传递
return dat; //将读出的数据返回
}
void Init_DS1302(void)
{
WriteSet1302(0x8e,0x00);
WriteSet1302(0x84,time[0]);
WriteSet1302(0x82,time[1]);
WriteSet1302(0x80,time[2]);
WriteSet1302(0x8e,0x80);
}
void read_time()
{
hour=ReadSet1302(0x85);
minute=ReadSet1302(0x83);
second=ReadSet1302(0x81);
}
void main(void)
{
Init_DS1302();
while(1)
{
read_time();
display();
}
}
一周热门 更多>