求教1302数码管显示的问题
#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();
}
}
主函数里的延时时间过长了,可以适当减小些试试
回复 feiren45 的帖子
请教:可主函数就调用了初始化、读时间和显示三个子程序啊 还是不太明白 麻烦您再讲清楚些 谢谢
void main(void)
{
Init_DS1302();
while(1)
{
read_time();
display();
delay(oxf0i);
}
}
回复 agj032 的帖子
弱弱的问一句:“delay(oxf0i);”什么意思 请指教
不知你的主频是多少.1.力求读时间函数( read_time();)控制在40ms以内,2.显示函数display();后面加一个延时(delay(oxf0i);),延时时间最好为960ms.oxf0i为你自己定长度.
回复 agj032 的帖子
主频12MHZ 好象不行啊。
你在读时间时也调用一下显示看看
#include<reg52.h>
#define DS1302_W_ADDR 0x80
#define DS1302_R_ADDR 0x81
#define uchar unsigned char
uchar s,f,m;
uchar time[7]={55,47,23,16,1,1,13};
uchar code a[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
uchar code b[]={0xbF,0x86,0xdB,0xcF,0xe6,0xeD,0xfD,0x87,0xfF,0xeF};
void delay(int z) //延迟
{
int x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void delay1()
{ ;; }
void write_ds1302_byte(uchar dat)
{
int i;
WR=0;
for(i=8;i>0;i--)
{
RD=dat&0x01;
WR=1;
dat>>=1;
WR=0;
}
}
uchar read_ds1302_byte()
{
uchar i,dat=0;
WR=0;
for(i=8;i>0;i--)
{
WR=1;
dat>>=1;
if(RD)
dat|=0x80;
WR=0;
}
return dat;
}
void reset_ds1302()
{
T1=0;
WR=0;
T1=1;
}
void clear_ds1302_WP(void)
{
reset_ds1302();
T1=1;
write_ds1302_byte(0x8E);
write_ds1302_byte(0x00);
WR=1;
T1=0;
}
void set_ds1302_WP()
{
reset_ds1302();
T1=1;
write_ds1302_byte(0x8E);
write_ds1302_byte(0x80);
WR=1;
T1=0;
}
void write_ds1302(uchar addr,uchar dat)
{
reset_ds1302();
T1=1;
write_ds1302_byte(addr);
write_ds1302_byte(dat);
WR=1;
T1=0;
}
void set_time(uchar *timedata)
{
uchar i,tmp;
for(i=0;i<7;i++)
{
tmp=timedata[i]/10;
timedata[i]=timedata[i]%10;
timedata[i]=timedata[i]+tmp*16;
}
clear_ds1302_WP();
tmp=DS1302_W_ADDR;
for(i=0;i<7;i++)
{
write_ds1302(tmp,timedata[i]);
tmp+=2;
}
set_ds1302_WP();
}
uchar read_ds1302(uchar addr)
{
uchar temp=0;
reset_ds1302();
T1=1;
write_ds1302_byte(addr);
temp=read_ds1302_byte();
WR=1;
T1=0;
return temp;
}
void read_time(uchar *timedata)
{
uchar i,tmp;
tmp=DS1302_R_ADDR;
for(i=3;i>0;i--)
{
timedata[i]=read_ds1302(tmp);
tmp+=2;
}
}
void main()
{
set_time(&time);
while(1)
{
reset_ds1302();
read_time(&time);
P2=0x02;
P0=a[time[3]/16];
delay(5);
P2=0x01;
P0=a[time[3]%16];
delay(5);
P2=0x08;
P0=a[time[2]/16];
delay(5);
P2=0x04;
P0=a[time[2]%16];
delay(5);
P2=0x20;
P0=a[time[1]/16];
delay(5);
P2=0x10;
P0=a[time[1]%16];
delay(5);
}
}
这是我的程序,我的已经可以读出时钟在走,但用数码管显示时在闪烁,有时候读取不到实时的时间来显示,经常有全显零的现象