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