本帖最后由 diehualong 于 2018-12-22 23:19 編輯
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit we = P2^7;
sbit du = P2^6;
sbit key_1 = P3^4;
sbit key_2 = P3^5;
sbit key_3 = P3^6;
sbit key_4 = P3^7;
uchar n1 = 0;//控制多長時(shí)間閃爍一次。
uchar shi = 0;
uchar shi_1,shi_2;
uchar fen = 0;
uchar fen_1,fen_2;
uchar miao = 0;
uchar miao_1,miao_2;
uchar n = 0;
bit shezhi = 0;
bit flag = 0;//控制設(shè)置時(shí)某些位的閃爍
uchar m = 0;//不亮的位置
uchar code leddata[]={
0x3F, //"0"
0x06, //"1"
0x5B, //"2"
0x4F, //"3"
0x66, //"4"
0x6D, //"5"
0x7D, //"6"
0x07, //"7"
0x7F, //"8"
0x6F, //"9"
0x40, //"-"
};
uchar code pos[] = {
0xfe,
0xfd,
0xfb,
0xf7,
0xef,
0xdf
};
一部分:參數(shù)初始化函數(shù) void init() { TMOD = 0x11;//將定時(shí)器0和定時(shí)器1設(shè)為工作方式1,16位定時(shí)器 TH0 = 0x4B; TL0 = 0xFC; //設(shè)置定時(shí)器0的中斷周期是50ms TH1 = 0x4B; TL1 = 0xFC; //設(shè)置定時(shí)器1的中斷周期是50ms PT0 = 1; //設(shè)置定時(shí)器0中斷的優(yōu)先級(jí)高于定時(shí)器1中斷 ET0 = 1; //開啟定時(shí)器0中斷 ET1 = 1; //開啟定時(shí)器1中斷 TR1 = 1; //定時(shí)器1開始計(jì)數(shù) TR0 = 1; //定時(shí)器0開始計(jì)數(shù) EA = 1; //開啟總中斷 } 第二部分:關(guān)于數(shù)碼管點(diǎn)亮的函數(shù) //--------------將小時(shí)對(duì)應(yīng)的數(shù)碼管的點(diǎn)亮的函數(shù)---------------// voidhour_display() { shi_1 = shi/10; //將小時(shí)的十位數(shù)字賦值給shi_1 shi_2 = shi%10; //將小時(shí)的個(gè)位數(shù)字賦值給shi_2 P0 = pos[0]; we = 1; we = 0; P0 = leddata[shi_1]; du = 1; du = 0; delay(1); //將最左邊的數(shù)碼管點(diǎn)亮并顯示小時(shí)的十位數(shù)字 P0 = pos[1]; we = 1; we = 0; P0 = leddata[shi_2]; du = 1; du = 0; //將左邊第二個(gè)數(shù)碼管點(diǎn)亮并顯示小時(shí)的個(gè)位數(shù)字 delay(1); } //----------------將分鐘對(duì)應(yīng)的數(shù)碼管的點(diǎn)亮的函數(shù)----------------// voidfen_display() { fen_1 = fen/10; //將分鐘的十位數(shù)字賦值給fen_1 fen_2 = fen%10; //將分鐘的個(gè)位數(shù)字賦值給fen_2 P0 = pos[2]; we = 1; we = 0; P0 = leddata[fen_1]; du = 1; du = 0; delay(1); //將左邊第三個(gè)數(shù)碼管點(diǎn)亮并顯示分鐘的十位數(shù)字 P0 = pos[3]; we = 1; we = 0; P0 = leddata[fen_2]; du = 1; du = 0; delay(1); //將左邊第四個(gè)數(shù)碼管點(diǎn)亮并顯示分鐘的個(gè)位數(shù)字 } //-------------將秒數(shù)對(duì)應(yīng)的數(shù)碼管的點(diǎn)亮的函數(shù)-------------// voidmiao_display() { miao_1 = miao/10; //將秒數(shù)的十位數(shù)字賦值給miao_1 miao_2 = miao%10; //將秒數(shù)的個(gè)位數(shù)字賦值給miao_2 P0 = pos[4]; we = 1; we = 0; P0 = leddata[miao_1]; du = 1; du = 0; delay(1); //將右邊第二個(gè)數(shù)碼管點(diǎn)亮并顯示秒數(shù)的十位數(shù)字 P0 = pos[5]; we = 1; we = 0; P0 = leddata[miao_2]; du = 1; du = 0; delay(1); //將右邊第一個(gè)數(shù)碼管點(diǎn)亮并顯示秒數(shù)的個(gè)位數(shù)字 } //------------判斷當(dāng)參數(shù)shezhi等于1時(shí)將小時(shí)、分鐘、秒數(shù)所對(duì)應(yīng)的數(shù)碼管點(diǎn)亮并顯示出相應(yīng)數(shù)字的函數(shù)-------------// void alldis() { if(shezhi == 0) //當(dāng)參數(shù)shezhi等于0的時(shí)候所有數(shù)碼管被點(diǎn)亮,并 { //將小時(shí)、分鐘、秒數(shù)所對(duì)應(yīng)數(shù)碼管顯示出對(duì)應(yīng)的數(shù)字 hour_display(); fen_display (); miao_display(); } } //------------判斷當(dāng)參數(shù)shezhi等于0時(shí)將要修改的位(即小時(shí)或分鐘或秒數(shù)對(duì)應(yīng)的某兩位數(shù)碼管)出現(xiàn)閃爍效果的函數(shù)--------------// void fourdis() { if(shezhi == 1) { P0 = 0xff; we = 0; //將所有的數(shù)碼管關(guān)閉,以防受到前一次數(shù)碼管打開 we = 1; //的影響,并為下面出現(xiàn)閃爍效果做準(zhǔn)備 if(flag == 0) //判斷當(dāng)參數(shù)flag等于0時(shí)將所有數(shù)碼管點(diǎn)亮 { hour_display(); fen_display (); miao_display(); } if(flag == 1) //判斷當(dāng)數(shù)碼管等于1時(shí)使需要修改的位置(即小時(shí) { //或分鐘或秒數(shù)對(duì)應(yīng)的某兩位數(shù)碼管)關(guān)閉 if(m == 0) //判斷當(dāng)參數(shù)m為0時(shí)將小時(shí)對(duì)應(yīng)的兩位數(shù)碼管關(guān)閉 { fen_display (); miao_display(); } if(m == 1) //判斷當(dāng)參數(shù)m為1時(shí)將分鐘對(duì)應(yīng)的兩位數(shù)碼管關(guān)閉 { hour_display(); miao_display(); } if(m == 2) //判斷當(dāng)參數(shù)m為2時(shí)將秒數(shù)對(duì)應(yīng)的兩位數(shù)碼管關(guān)閉 { hour_display(); fen_display (); } } } } //------------------匯總以上將數(shù)碼管點(diǎn)亮的函數(shù)(數(shù)碼管的狀態(tài)將隨參數(shù)的改變而變化----------------------// void display() { alldis() ; fourdis(); } 第三部分:延時(shí)類函數(shù) //---------通過數(shù)碼管顯示來做到延遲的函數(shù),為按鍵延時(shí)消抖做準(zhǔn)備---------// voiddelay0(uchar z) { for(;z > 0;z--) display(); //將數(shù)碼管以現(xiàn)在的狀態(tài)點(diǎn)亮的函數(shù) } //------毫秒級(jí)延時(shí)函數(shù);當(dāng)z = 1時(shí),即delay(1)代表運(yùn)行時(shí)間為1ms-----// void delay(uintz) { uint x,y; for(x = z;x > 0;x--) for(y = 114;y > 0;y--); } 第四部分:中斷類函數(shù) //-------------------定時(shí)器0中斷函數(shù)(控制每秒秒數(shù)增1,秒數(shù)、分鐘為60進(jìn)制,小時(shí)為24進(jìn)制)----------------------// void timer_0()interrupt 1 { TH0 = 0x4B; TL0 = 0xFC; //將定時(shí)器0設(shè)置為計(jì)時(shí)50ms中斷1次 n++; //參數(shù)n存儲(chǔ)定時(shí)器0中斷次數(shù),來計(jì)時(shí)是否過1s n1++; //參數(shù)n1存儲(chǔ)定時(shí)器0中斷次數(shù)控制數(shù)碼管閃爍頻率 if(n1 == 5) //當(dāng)n1等于5時(shí)將要修改位對(duì)應(yīng)的數(shù)碼管點(diǎn)亮(或關(guān)閉) flag = ~flag,n1 = 0; if(n >= 20) //當(dāng)n等于20時(shí)說明已中斷1s,將n清零并使秒數(shù)增1 { n = 0; miao++; } if(miao >= 60) //當(dāng)秒數(shù)等于60時(shí)使秒數(shù)清零并使分鐘增1,使秒數(shù)滿 { //足60進(jìn)制 miao = 0; fen++; } if(fen >= 60) //當(dāng)分鐘等于60時(shí)使分鐘清零并使小時(shí)增1,使分鐘滿 { //足60進(jìn)制 fen = 0; shi++; } if(shi >= 24) //當(dāng)小時(shí)等于24時(shí)使小時(shí)清零,使小時(shí)滿足24進(jìn)制 shi = 0; } //-----定時(shí)器1中斷函數(shù),每50ms中斷1次,判斷是否有按鍵按下-----// void timer1()interrupt 3 { TH1 = 0x4B; TL1 = 0xFC; //將定時(shí)器1設(shè)置為50ms計(jì)數(shù) if(key_3 == 0) //判斷K3按鍵是否按下 { m = 0; delay0(10); //按鍵延時(shí)消抖 if(key_3 == 0) shezhi = ~shezhi; //打開數(shù)值設(shè)置或者關(guān)閉數(shù)值設(shè)置 delay0(10); //延時(shí)消抖 // while(!key_3) // display(); } if(key_4 == 0&&shezhi == 1) //判斷在開啟設(shè)置數(shù)值狀態(tài)K4是否按下 { delay0(10); //按鍵延時(shí)消抖 if(key_4 == 0) m++; //當(dāng)K4按鍵按下使閃爍位后移兩個(gè) if(m >= 3) //當(dāng)閃爍位超過秒數(shù)兩位時(shí)時(shí),使之重新回 m = 0; //到小時(shí)對(duì)應(yīng)的兩位數(shù)碼管使之閃爍 delay0(10); //按鍵延時(shí)消抖 // while(!key_4) // display(); } if(key_2 == 0&&shezhi == 1)//判斷在開始數(shù)值設(shè)置K2是否按下 { //--------此參數(shù)flag可以設(shè)置當(dāng)按鍵按下時(shí)對(duì)應(yīng)數(shù)碼管是否閃爍---------// flag = 1; delay0(8); //延時(shí)消抖 if(key_2 == 0) { if(m == 0) //當(dāng)m等于0,說明此時(shí)設(shè)置的是小時(shí), shi++; //小時(shí)數(shù)值上增1 if(m == 1) //當(dāng)m等于1,說明此時(shí)設(shè)置的是分鐘, fen++; //分鐘數(shù)值上增1 if(m == 2) //當(dāng)m等于2,說明此時(shí)設(shè)置的是秒數(shù), miao++; //秒數(shù)數(shù)值上增1 } //------這條語句可使在設(shè)置數(shù)值狀態(tài)下,長按按鍵時(shí)數(shù)值連續(xù)增長------// delay0(8); //按鍵消抖延時(shí) //------------------------------------------------------------------------------------------// //---這兩條語句可以使在設(shè)置數(shù)值狀態(tài)下,長按按鍵閃爍位也只增1---// // while(!key_2) // display(); //------------------------------------------------------------------------------------------// } if(key_1 == 0&&shezhi == 1) //判斷在開始數(shù)值設(shè)置K1是否按下 { //--------此參數(shù)flag可以設(shè)置當(dāng)按鍵按下時(shí)對(duì)應(yīng)數(shù)碼管是否閃爍---------// flag = 0; //此時(shí)對(duì)應(yīng)的數(shù)碼管處于長亮狀態(tài) delay0(8); //按鍵延時(shí)消抖 if(key_1 == 0) { if(m == 0) //當(dāng)m等于0,說明此時(shí)設(shè)置的是小時(shí), shi--; //小時(shí)數(shù)值減1 if(shi == 255) shi = 23; if(m == 1) //當(dāng)m等于1,說明此時(shí)設(shè)置的是分鐘, fen--; //分鐘數(shù)值減1 if(fen == 255) fen = 59; if(m == 2) //當(dāng)m等于2,說明此時(shí)設(shè)置的是秒數(shù) miao--; //秒數(shù)數(shù)值減1 if(miao == 255) miao = 59; } //------這條語句可使在設(shè)置數(shù)值狀態(tài)下,長按按鍵時(shí)數(shù)值連續(xù)增長------// delay0(8); //------------------------------------------------------------------------------------------// //---這兩條語句可以使在設(shè)置數(shù)值狀態(tài)下,長按按鍵閃爍位也只增1---// //while(!key_1) // display(); //------------------------------------------------------------------------------------------// } } void main()
{
init();
while(1)
display();
}
|