各位大師你們好!本人剛學習單片機,很多東西不明白,特來向各位請教!QQ:664967791
lhfplc@126.com
資料說明:時鐘電路板是在一收舊販購得,見圖片。上有時鐘數(shù)碼管4位,AT89C52等,12M晶振。
圖紙說明:照實物測繪無誤,見PDF文件。
問題是:怎樣從P0口分離出P0^0,讓秒點閃爍。
問題說明:秒點D5、D6由P0口的P0^0控制輸出,D5在DIG.3位,D6在DIG.4位,也就是圖中的Q3、Q4控制的個位和十位
圖片:
程序說明:網上下載,修改如下
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define sled_dm_port P0 /*定義P0口為段碼控制口*/
#define sled_wm_port P1 /*定義P1口為位碼控制口*/
sbit fm=P1^0; /*蜂鳴器輸出聲明*/
sbit dula=P1^1; /*運行指示燈聲明*/
sbit s1=P2^0; /*設置鍵聲明*/
sbit s2=P2^1; /*加一鍵聲明*/
sbit s3=P2^2; /*減一鍵聲明*/
sbit s4=P2^3; /*鬧鐘鍵聲明*/
uchar data count; /*50MS信號變量*/
uint data flag_count; /*1MS到5S的變量*/
uchar data flag; /*累加到5S的啟動標志位*/
char data sec=0,min=0,hou=12; /*時鐘的秒分時計數(shù)器*/
char data nz_sec=0,nz_min=0,nz_hou=0; /*鬧鐘的秒分時計數(shù)器*/
uchar data set_count,nz_count,dr; /*設置鍵按下次數(shù)變量,鬧鐘鍵按下次數(shù)變量,緩沖數(shù)組偏移變量*/
uchar data dis_buff[8]; /*段碼緩沖數(shù)組*/
uchar code num_table[10]={0x10,0xba,0x48,0x44,0x86,0x24,0x20,0x56,0x00,0x04};
/* 0 1 2 3 4 5 6 7 8 9 .*/
uchar data lighten_bit_table[4]={0xfb,0xf7,0xef,0xdf};/*定義每次掃描時需點亮的數(shù)碼管*/
void TimerValueSet(); /*定時器初始化程序*/
void key_scan(); /*設置鍵s1和鬧鐘鍵s4掃描程序*/
void set_time(); /*時間設置程序*/
void set_disp(); /*時間設置時的顯示程序*/
void display(); /*無鍵按下時的顯示程序*/
void set_nz(); /*鬧鐘設置程序*/
void nzset_disp(); /*鬧鐘設置時的顯示程序*/
void alarm(); /*鬧鐘報警程序*/
set_add(uchar n); /*按鍵加1程序*/
set_sub(char n); /*按鍵減1程序*/
void delay_1ms(uint x); /*1ms為單位的延時程序*/
/*主程序*/
void main()
{
TimerValueSet();
while(1)
{
key_scan();
set_time();
set_nz();
if(set_count==0&nz_count==0)
alarm();
}
}
/*定時器初始化程序*/
void TimerValueSet()
{
TMOD=0x11;
IE=0x8a;
IP=0x08;
TH0=0x4c; /*載入50ms定時初值*/
TL0=0x00;
TH1=0xfc; /*載入1ms定時初值*/
TL1=0x67;
TR0=1;
TR1=1;
}
/*設置鍵s1和鬧鐘鍵s4掃描程序*/
void key_scan()
{
if(s1==0&nz_count==0) /*設置鍵按下且之前沒有按下鬧鐘鍵*/
{
delay_1ms(20);
if(s1==0)
{
while(!s1);
set_count++;
if(set_count==3) /*設置鍵按下3次則清零退出設置*/
set_count=0;
}
}
if(s4==0&set_count==0) /*鬧鐘鍵按下且之前沒有按下設置鍵*/
{
delay_1ms(20);
if(s4==0)
{
while(!s4);
nz_count++;
if(nz_count==3) /*鬧鐘鍵按下3次則清零退出設置*/
nz_count=0;
}
}
}
/*時間設置程序*/
void set_time()
{
if(set_count!=0)
{
flag=1;
while(s2&s3)
{
key_scan();
if(flag_count>=5000)
{
set_count=0; /*5S內無鍵按下則退出設置*/
break;
}
}
flag_count=0;
flag=0;
}
if(set_count==1)
{
hou=set_add(hou);
if(hou==24)
hou=0;
hou=set_sub(hou);
if(hou<0)
hou=23;
}
if(set_count==2)
{
min=set_add(min);
if(min==60)
min=0;
min=set_sub(min);
if(min<0)
min=59;
}
}
/*鬧鐘設置程序*/
void set_nz()
{
if(nz_count!=0)
{
flag=1;
while(s2&s3)
{
key_scan();
if(flag_count>=5000)
{
nz_count=0; /*5S內無鍵按下則退出鬧鐘設置*/
break;
}
}
flag_count=0;
flag=0;
}
if(nz_count==1)
{
nz_hou=set_add(nz_hou);
if(nz_hou==24)
nz_hou=0;
nz_hou=set_sub(nz_hou);
if(nz_hou<0)
nz_hou=23;
}
if(nz_count==2)
{
nz_min=set_add(nz_min);
if(nz_min==60)
nz_min=0;
nz_min=set_sub(nz_min);
if(nz_min<0)
nz_min=59;
}
}
/*無鍵按下時的顯示程序*/
void display()
{
dis_buff[1]=num_table[min/10];
dis_buff[0]=num_table[min%10];
dis_buff[3]=num_table[hou/10];
dis_buff[2]=num_table[hou%10];
if(set_count==0&nz_count==0) /*無鍵按下時的顯示*/
{
sled_wm_port=0xff;
if(dr==2&count<10)
sled_dm_port=dis_buff[dr]&0x7f;
else
{ if(dr==3&dis_buff[3]==0xc0) /*若時變量的十位為零是則不顯示*/
sled_dm_port=0xff;
else
sled_dm_port=dis_buff[dr];
}
sled_wm_port=lighten_bit_table[dr];
}
if(set_count!=0) /*設置鍵按下調用設置顯示程序*/
set_disp();
if(nz_count!=0) /*鬧鐘鍵按下調用鬧鐘顯示程序*/
nzset_disp();
dr++;
if(dr==4) /*將dr改為4,段碼緩沖數(shù)組元素個數(shù)改為4可提高掃描亮度*/
dr=0;
}
/*時間設置時的顯示程序*/
void set_disp()
{
if(set_count==1)
{
sled_wm_port=0xff;
switch(dr)
{
case 0:
case 1:sled_dm_port=dis_buff[dr];break;
case 2:if(count<10)sled_dm_port=dis_buff[dr]&0x7f;else sled_dm_port=0x7f;break;
case 3:if(count<10&dis_buff[3]!=0xc0)sled_dm_port=dis_buff[dr];else sled_dm_port=0xff;break;
default:sled_dm_port=0xff;break;
}
sled_wm_port=lighten_bit_table[dr];
}
if(set_count==2)
{
sled_wm_port=0xff;
switch(dr)
{
case 0:
case 1:if(count<10)sled_dm_port=dis_buff[dr];else sled_dm_port=0xff;break;
case 2:sled_dm_port=dis_buff[dr]&0x7f;break;
case 3:if(dis_buff[3]!=0xc0)sled_dm_port=dis_buff[dr];else sled_dm_port=0xff;break;
default:sled_dm_port=0xff;break;
}
sled_wm_port=lighten_bit_table[dr];
}
}
/*鬧鐘設置時的顯示程序*/
void nzset_disp()
{
if(nz_count==1)
{
sled_wm_port=0xff;
switch(dr)
{
case 0: sled_dm_port=num_table[nz_min%10];break;
case 1: sled_dm_port=num_table[nz_min/10];break;
case 2: if(count<10)
sled_dm_port=num_table[nz_hou%10]&0x7f;else sled_dm_port=0xff;break;
case 3: if(count<10&num_table[nz_hou/10]!=0xc0)
sled_dm_port=num_table[nz_hou/10];else sled_dm_port=0xff;break;
default:sled_dm_port=0xff; break;
}
sled_wm_port=lighten_bit_table[dr];
}
if(nz_count==2)
{
sled_wm_port=0xff;
switch(dr)
{
case 0: if(count<10)
sled_dm_port=num_table[nz_min%10];else sled_dm_port=0xff;break;
case 1: if(count<10)
sled_dm_port=num_table[nz_min/10];else sled_dm_port=0xff;break;
case 2: if(count<10)
sled_dm_port=num_table[nz_hou%10]&0x7f;else sled_dm_port=num_table[nz_hou%10];break;
case 3: if(num_table[nz_hou/10]!=0xc0)
sled_dm_port=num_table[nz_hou/10];else sled_dm_port=0xff;break;
default:sled_dm_port=0xff;break;
}
sled_wm_port=lighten_bit_table[dr];
}
}
/*鬧鐘報警程序*/
void alarm()
{
if(hou==nz_hou&min==nz_min)
{
if(sec%2==0&sec<30)
{
fm=0;
delay_1ms(300);
fm=1;
delay_1ms(100);
fm=0;
delay_1ms(400);
fm=1;
delay_1ms(200);
}
}
}
/*按鍵加1程序*/
set_add(uchar n)
{
if(s2==0)
{
delay_1ms(20);
if(s2==0)
{
n++;
while(!s2);
}
}
return n;
}
/*按鍵減1程序*/
set_sub(uchar n)
{
if(s3==0)
{
delay_1ms(20);
if(s3==0)
{
n--;
while(!s3);
}
}
return n;
}
/*定時器T0中斷處理*/
void Timer0() interrupt 1
{
TH0=0x4c;
TL0=0x00;
count++;
if(count==20)
{
count=0;
sec++;
if(sec==60)
{
sec=0;
min++;
if(min==60)
{
min=0;
hou++;
if(hou==24)
hou=0;
}
}
}
}
/*定時器T1中斷處理*/
void Timer1() interrupt 3
{
TH1=0xfc;
TL1=0x67;
if(flag)
flag_count++;
display();
}
/*1ms位單位的延時程序*/
void delay_1ms(uint x)
{
uchar i;
while(x--)
for(i=0;i<125;i++);
}