時鐘可以顯示到秒位
從左到右的開關控制分別為:秒設置、分設置、時設置、進入時間設置(設置時間需要按一下這個再按前面3個按鍵設置)、鬧鐘設置(通過前面3個按鍵設置)、保存設置(設置完成后按下保存并退出)。
數碼管用的是共陰,共陽的話加三極管閑麻煩,沒加。
數碼管a~g接的P0口,沒用10K排阻上拉,試了下覺得亮度太低了,就都換成了2K的作為上拉。
有興趣的可以給加上溫度傳感器,可以顯示溫度(我這里面就沒加了)
初學單片機沒多久,歡迎大佬指導。
材料如下:89C52*1
4位數碼管*1+2位數碼管*1(當然如果有六位的也可以直接用,找不到其他數碼管了就這么混搭了 )
有源蜂鳴器*1(試過無源,但時間計算過于占用資源導致發聲不是很完美,大佬可以改一下)
輕觸開關*7(1個用于復位,其余六個用于設置) + 自鎖開關*1
電池*1 + 5V穩壓*1
單片機源碼:
- #include <reg52.h>
- #define uint unsigned int
- #define uchar unsigned char
- sbit WE1=P2^5;
- sbit WE2=P2^4;
- sbit WE3=P2^3;
- sbit WE4=P2^2;
- sbit WE5=P2^1;
- sbit WE6=P2^0;
- sbit K1=P1^0; //設置小時位
- sbit K2=P1^1; //設置分位
- sbit K3=P1^2; //設置秒位
- sbit K4=P1^3; //進入時間設置
- sbit K5=P1^4; //進入鬧鐘設置
- sbit K6=P1^5; //退出設置
- sbit BZ=P1^6; //蜂鳴器接口
- uchar code table[]={
- 0XC0,0XF9,0XA4,
- 0XB0,0X99,0X92,
- 0X82,0XF8,0X80,
- 0X90};
- uint tt=0,i=0,j=0,T=0,R=0,S;
- uint W1=0,W2=0,W3=0,W4=0,W5=0,W6=0; //當前時間位,依次接P0口即可,即W1=P0^0,W2=P0^2.....以此類推
- uint WD1=0,WD2=0,WD3=0,WD4=0,WD5=0,WD6=0; //鬧鐘時間位,用于儲存設置的鬧鐘時間,不接
- void delay(uint); //軟延時
- //void delay1(uint);
- void js(void); //時鐘進位定義
- void key(void); //按鍵
- void XS(uint,uint,uint,uint,uint,uint); //動態掃描數碼管顯示
- void xhsz(uint,uint,uint,uint,uint,uint,uint); //時鐘位設置函數
- void main()
- {
- P1=0X0;
- TMOD=0X01;
- TH0=(65536-49971)/256;
- TL0=(65536-49971)%256;
- //TH1=(65536-65535)/256; //定時器二(未啟用)
- //TL1=(65536-65535)%256;
- EA=1;
- ET0=1;
- //ET1=1;
- TR0=1;
- //TR1=1;
- while(1)
- {
- key();
- XS(W1,W2,W3,W4,W5,W6);
- js();
- if(WD1==W1&&WD2==W2&&WD3==W3&&WD4==W4&&WD5==W5&&WD6==W6) //鬧鐘定時判斷
- T=1;
- }
- }
- void xhsz(uint Q1,uint Q2,uint Q3,uint Q4,uint Q5,uint Q6,uint Y) //輸入需要設置的位Q1~Q6,末尾輸入1則將值賦給W1~W6,輸入0則賦給WD1~WD6
- {
- while(1)
- {
- if(Y==1)
- {
- W1=Q1;W2=Q2;W3=Q3;W4=Q4;W5=Q5;W6=Q6;
- }
- if(Y==0)
- {
- WD1=Q1;WD2=Q2;WD3=Q3;WD4=Q4;WD5=Q5;WD6=Q6;
- }
- if(K1==1)//秒調
- {
- delay(10);
- if(K1==1)
- {
- while(K1==1)
- XS(Q1,Q2,Q3,Q4,Q5,Q6);
- Q1++;
- if(Q1>9)
- {Q2++;Q1=0;}
- if(Q2>5)
- {Q2=0;Q3=0;}
- }
- }
- if(K2==1)//分調
- {
- delay(10);
- if(K2==1)
- {
- while(K2==1)
- XS(Q1,Q2,Q3,Q4,Q5,Q6);
- Q3++;
- if(Q3>9)
- {Q4++;Q3=0;}
- if(Q4>5)
- {Q4=0;Q3=0;}
- }
- }
- if(K3==1)//時調
- {
- delay(10);
- if(K3==1)
- {
- while(K3==1)
- XS(Q1,Q2,Q3,Q4,Q5,Q6);
- Q5++;
- if(Q5>9)
- {Q6++;Q5=0;}
- if(Q5>3&&Q6>1)
- {Q6=0;Q5=0;}
- }
- }
- XS(Q1,Q2,Q3,Q4,Q5,Q6);
- if(K6==1)
- break;
- }
- }
- void key()
- {
- if(K4==1) //設置時間
- {
- delay(10);
- if(K4==1)
- {
- while(K4==1);
- TR0=0;
- xhsz(W1,W2,W3,W4,W5,W6,1);
- TR0=1;
- }
- }
-
- if(K5==1) //設置鬧鐘
- {
- delay(10);
- if(K5==1)
- {
- while(K5==1);
- xhsz(WD1,WD2,WD3,WD4,WD5,WD6,0);
- }
- }
- if(K6==1) //關閉鬧鐘
- {
- delay(10);
- if(K6==1)
- {
- while(K6==1);
- T=0;
- BZ=0;
- }
- }
- }
- void time() interrupt 1 //定時器1
- {
- TH0=(65536-49971)/256;
- TL0=(65536-49971)%256;
- tt++;
- js();
- if(T==1)
- {
- R++;
- if(R==1000) //鬧鐘響鈴時間 計算方式是R*50ms,這里設置的是50S
- {T=0;R=0;}
- }
- }
- /*void time1() interrupt 3
- {
- TH1=(65536-65535)/256;
- TL1=(65536-65535)%256;
- S++;
- }*/
- void delay(uint t)
- {
- for(i=t;i>0;i--)
- {
- for(j=90;j>0;j--);
- }
- }
- /*void delay1(uint S)
- {
- for(i=S;i>0;i--)
- {
- for(j=1;j>0;j--);
- }
- }*/
- void js()
- {
- if(tt==20)
- {
- tt=0;
- W1++;
- }
-
- if(W1>9)
- {
- W2++;
- W1=0;
- }
-
- if(W2>5)
- {
- W3++;
- W2=0;
- }
-
- if(W3>9)
- {
- W4++;
- W3=0;
- }
-
- if(W4>5)
- {
- W5++;
- W4=0;
- }
-
- if(W5>9)
- {
- W6++;
- W5=0;
- }
-
- if(W5>3&&W6>1)
- {
- W1=0;
- W2=0;
- W3=0;
- W4=0;
- W5=0;
- W6=0;
- }
- }
- void XS(uint Q1,uint Q2,uint Q3,uint Q4,uint Q5,uint Q6)
- {
- WE1=0;
- P0=~table[Q1];
- delay(3);
- WE1=1;
-
- WE2=0;
- P0=~table[Q2];
- delay(3);
- WE2=1;
-
- WE3=0;
- P0=~table[Q3];
- delay(3);
- WE3=1;
-
- WE4=0;
- P0=~table[Q4];
- delay(3);
- WE4=1;
-
- WE5=0;
- P0=~table[Q5];
- delay(3);
- WE5=1;
-
- WE6=0;
- P0=~table[Q6];
- delay(3);
- WE6=1;
-
- if(T==1)
- BZ=1; //蜂鳴器響
- if(T==0)
- BZ=0; //蜂鳴器停
- }
復制代碼
附上電路+程序:
數碼管時鐘.rar
(46.54 KB, 下載次數: 377)
2018-5-26 14:00 上傳
點擊文件名下載附件
數碼管時鐘程序.rar
(34.36 KB, 下載次數: 287)
2018-5-26 13:37 上傳
點擊文件名下載附件
電路圖.PDF
(72.14 KB, 下載次數: 380)
2018-5-26 13:37 上傳
點擊文件名下載附件
|