大家帮助下完成最小系统后,目标做个ds12c887精确4位共阴数码管时钟,秒用发光二极管量灭表示,
不加887时,时钟功能一步一步进展还算顺利,但加上后就不行了,症状是全显示0,可以设定按键时间,但设定好退出按键,又回到全0状态,已经研究快一两礼拜了,请有经验的网友支支招,真没辙了
程序如下
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit led1 = P2^3; //小灯做秒显示
sbit led2 = P2^2;
sbit wela1 = P2^7; //分 个位
sbit wela2 = P2^6; //分 十位
sbit wela3 = P2^5; //时 个位
sbit wela4 = P2^4; //时 十位
sbit k1= P3^2; //选择
sbit k2 = P2^1; //加
sbit k3 = P2^0; //减
//sbit deep = P2^0; //蜂鸣器
sbit DS_DS = P3^4;
sbit DS_RW = P3^5;
sbit DS_AS = P3^6;
sbit DS_CS = P3^7;
void delayms(uint);
void DS_init();
uchar hr,sec,min,num,k1_num,k1_flag;
uchar qian,bai,shi,ge;
uchar code table[] = { 0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f,
};
void delayms(uint z)
{
uint i,j;
for(i=z;i>0;i--)
for(j=110;j>0;j--);
}
//时钟写
void write_ds(uchar add,uchar date)
{
DS_CS = 0;
DS_AS = 1;
DS_DS = 1;
DS_RW = 1;
P0 = add;
DS_AS = 0;
DS_RW = 0;
P0 = date;
DS_RW = 1;
DS_AS = 1;
DS_CS = 1;
}
//时钟读
uchar read_ds(uchar add)
{
uchar DS_date;
DS_AS = 1;
DS_DS = 1;
DS_RW = 1;
DS_CS = 0;
P0 = add;
DS_AS = 0;
DS_DS = 0;
P0 = 0xff;
DS_date = P0;
DS_DS = 1;
DS_AS = 1;
DS_CS = 1;
return(DS_date);
}
void set_time()//设定时间
{
write_ds(0,0); //秒
write_ds(2,43); //分
write_ds(4,3); //时
}
//初始化时钟
void DS_init()
{
DS_AS=0;
DS_DS=0;
DS_RW=0;
write_ds(0x0A,0x20); //打开晶振,开始计时
write_ds(0x0B,0x26); //设置24小时模式,数据二进制,开启闹钟中断
set_time();//实际应用中set_alarm()和set_time()仅第一次烧写需要
}
void display_smg(uchar qian,uchar bai,uchar shi,uchar ge)//以下数码管显示程序不加887显示都很正常
{
wela1 = wela2 = wela3 = wela4 = 0;
wela4 = 1;
P1=table[qian];
delayms(5);
wela4 = 0;
P1 = 0x00;
wela3=1;
P1=table[bai];
delayms(5);
wela3 = 0;
P1=0x00;
wela2=1;
P1=table[shi];
delayms(5);
wela2 = 0;
P1=0x00;
wela1=1;
P1=table[ge];
delayms(5);
wela1 = 0;
P1=0x00;
}
void keyscan()//按键功能
{
if(k1==0)//选择键按下
{
delayms(5);
if(k1==0)
{
k1_num++;
k1_flag=1;
while(!k1);
}
}
switch(k1_num)
{
case 1:
display_smg(qian,bai,shi,ge);
break;
case 2:
display_smg(qian,bai,shi,ge);
break;
case 3:
k1_num=0;
k1_flag=0;
break;
}
if(k1_num!=0)
{
if(k2==0)//加键按下
{
delayms(5);
if(k2==0)
{
while(!k2);
switch(k1_num)
{
case 1:
min++;
if(min==60)
min=0;
shi=min/10;//分钟的十位
ge=min%10;//分钟的个位
display_smg(qian,bai,shi,ge);
write_ds(2,min);
break;
case 2:
hr++;
if(hr==24)
hr=0;
qian=hr/10;//时钟的十位
bai=hr%10;//时钟的个位
display_smg(qian,bai,shi,ge);
write_ds(4,hr);
break;
}
}
}
if(k3==0)//减键按下
{
delayms(5);
if(k3==0)
{
while(!k3);
switch(k1_num)
{
case 1:
min--;
if(min==-1)
min=59;
shi=min/10;//分钟的十位
ge=min%10;//分钟的个位
display_smg(qian,bai,shi,ge);
write_ds(2,min);
break;
case 2:
shi--;
if(shi==-1)
shi=23;
qian=hr/10;//时钟的十位
bai=hr%10;//时钟的个位
display_smg(qian,bai,shi,ge);
write_ds(4,hr);
break;
}
}
}
}
}
/*void shanshuo()//闪烁部分暂时不写
{
} */
void main()//主函数
{
DS_init();
while(1)//大循环
{
keyscan();
if(k1_flag==0)//在S1没有按下时,flag为0
{
hr=read_ds(4); //读取时
min=read_ds(2);//读取分
sec=read_ds(0);//读秒
}
//shanshuo();
qian=hr/10;//时钟的十位
bai=hr%10;//时钟的个位
shi=min/10;//分钟的十位
ge=min%10;//分钟的个位
display_smg(qian,bai,shi,ge);//调用显示函数
}
}
不加887时,时钟功能一步一步进展还算顺利,但加上后就不行了,症状是全显示0,可以设定按键时间,但设定好退出按键,又回到全0状态,已经研究快一两礼拜了,请有经验的网友支支招,真没辙了
程序如下
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit led1 = P2^3; //小灯做秒显示
sbit led2 = P2^2;
sbit wela1 = P2^7; //分 个位
sbit wela2 = P2^6; //分 十位
sbit wela3 = P2^5; //时 个位
sbit wela4 = P2^4; //时 十位
sbit k1= P3^2; //选择
sbit k2 = P2^1; //加
sbit k3 = P2^0; //减
//sbit deep = P2^0; //蜂鸣器
sbit DS_DS = P3^4;
sbit DS_RW = P3^5;
sbit DS_AS = P3^6;
sbit DS_CS = P3^7;
void delayms(uint);
void DS_init();
uchar hr,sec,min,num,k1_num,k1_flag;
uchar qian,bai,shi,ge;
uchar code table[] = { 0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f,
};
void delayms(uint z)
{
uint i,j;
for(i=z;i>0;i--)
for(j=110;j>0;j--);
}
//时钟写
void write_ds(uchar add,uchar date)
{
DS_CS = 0;
DS_AS = 1;
DS_DS = 1;
DS_RW = 1;
P0 = add;
DS_AS = 0;
DS_RW = 0;
P0 = date;
DS_RW = 1;
DS_AS = 1;
DS_CS = 1;
}
//时钟读
uchar read_ds(uchar add)
{
uchar DS_date;
DS_AS = 1;
DS_DS = 1;
DS_RW = 1;
DS_CS = 0;
P0 = add;
DS_AS = 0;
DS_DS = 0;
P0 = 0xff;
DS_date = P0;
DS_DS = 1;
DS_AS = 1;
DS_CS = 1;
return(DS_date);
}
void set_time()//设定时间
{
write_ds(0,0); //秒
write_ds(2,43); //分
write_ds(4,3); //时
}
//初始化时钟
void DS_init()
{
DS_AS=0;
DS_DS=0;
DS_RW=0;
write_ds(0x0A,0x20); //打开晶振,开始计时
write_ds(0x0B,0x26); //设置24小时模式,数据二进制,开启闹钟中断
set_time();//实际应用中set_alarm()和set_time()仅第一次烧写需要
}
void display_smg(uchar qian,uchar bai,uchar shi,uchar ge)//以下数码管显示程序不加887显示都很正常
{
wela1 = wela2 = wela3 = wela4 = 0;
wela4 = 1;
P1=table[qian];
delayms(5);
wela4 = 0;
P1 = 0x00;
wela3=1;
P1=table[bai];
delayms(5);
wela3 = 0;
P1=0x00;
wela2=1;
P1=table[shi];
delayms(5);
wela2 = 0;
P1=0x00;
wela1=1;
P1=table[ge];
delayms(5);
wela1 = 0;
P1=0x00;
}
void keyscan()//按键功能
{
if(k1==0)//选择键按下
{
delayms(5);
if(k1==0)
{
k1_num++;
k1_flag=1;
while(!k1);
}
}
switch(k1_num)
{
case 1:
display_smg(qian,bai,shi,ge);
break;
case 2:
display_smg(qian,bai,shi,ge);
break;
case 3:
k1_num=0;
k1_flag=0;
break;
}
if(k1_num!=0)
{
if(k2==0)//加键按下
{
delayms(5);
if(k2==0)
{
while(!k2);
switch(k1_num)
{
case 1:
min++;
if(min==60)
min=0;
shi=min/10;//分钟的十位
ge=min%10;//分钟的个位
display_smg(qian,bai,shi,ge);
write_ds(2,min);
break;
case 2:
hr++;
if(hr==24)
hr=0;
qian=hr/10;//时钟的十位
bai=hr%10;//时钟的个位
display_smg(qian,bai,shi,ge);
write_ds(4,hr);
break;
}
}
}
if(k3==0)//减键按下
{
delayms(5);
if(k3==0)
{
while(!k3);
switch(k1_num)
{
case 1:
min--;
if(min==-1)
min=59;
shi=min/10;//分钟的十位
ge=min%10;//分钟的个位
display_smg(qian,bai,shi,ge);
write_ds(2,min);
break;
case 2:
shi--;
if(shi==-1)
shi=23;
qian=hr/10;//时钟的十位
bai=hr%10;//时钟的个位
display_smg(qian,bai,shi,ge);
write_ds(4,hr);
break;
}
}
}
}
}
/*void shanshuo()//闪烁部分暂时不写
{
} */
void main()//主函数
{
DS_init();
while(1)//大循环
{
keyscan();
if(k1_flag==0)//在S1没有按下时,flag为0
{
hr=read_ds(4); //读取时
min=read_ds(2);//读取分
sec=read_ds(0);//读秒
}
//shanshuo();
qian=hr/10;//时钟的十位
bai=hr%10;//时钟的个位
shi=min/10;//分钟的十位
ge=min%10;//分钟的个位
display_smg(qian,bai,shi,ge);//调用显示函数
}
}