#include<reg52.h> #include<intrins.h> #define nop _nop_(); #define uchar unsigned char #define uint unsigned int sbit stb =P1^0;//定義片選通訊口 sbit clk =P1^1;//定義時鐘通訊口 sbit dio =P1^2;//定義數(shù)據(jù)輸入/輸出通訊口bdata uchar y=0;//定義可以位尋址全局變量ysbity7 =y^7; uchar show[16] = {0x76,0x7b,0x38,0x38,0x3f,0x40,0x40,0x40,0x40,0x40};//初始化顯示“HELLO”字符代碼 uchar CODE[10] ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //0~9顯示代碼ucharTIME_seconds,seconds_2,sub_1,sub_2,shi_1,shi_2; //時間寄存器,依次從秒個位至小時十位 uchar TIME_count; //定時中斷控制制位uchar T_count; //時鐘小數(shù)點閃 uchar count4; //保存按鍵控制對應(yīng)的數(shù)碼管閃uchar key_FLAG1;//按鍵標志位 uchar key_COUNT1;//按鍵移動數(shù)動顯示數(shù)據(jù)uchar key_LED=0; //按鍵單獨顯示賦值寄存器uchar count7; /********************************* 功能: TM1629寫數(shù)據(jù) **********************************/ void write(uchar wr_data){ uchari; stb=0; //給有效的片選信號(片選信號是低電平有效) nop; nop; for(i=0;i<8;i++)//開始傳送8位數(shù)據(jù),每循環(huán)一次傳送一位數(shù)據(jù) { clk=0; nop; nop; wr_data>>= 1;//移位數(shù)據(jù),低位在前! nop; dio =CY; nop; nop; clk =1; nop; } } /********************************* 功能:讀按鍵子程序 由y 返回1BIT按鍵數(shù)據(jù)**********************************/ unsigned char read(){ uchar d; stb =0; //給有效的片選信號(片選信號是低電平有效) dio =1; //將DIO置高,因為沒有按鍵按下時,鍵值默認為00H,此時為了與鍵值有區(qū)別 for(d=0;d<8;d++) { clk =0; nop; if(dio==1) { y7 = 1; } else { y7 = 0; } clk = 1; if(d!=7){y=(y>>1);} nop; nop; } return(y); } /********************************* TM1629控制指令 功能: 驅(qū)動LED屏做相應(yīng)的顯示 **********************************/ void xianshi(uchar show_led[16]){ ucharh; stb = 1; clk = 1; dio = 1; write(0x40);//寫數(shù)據(jù)到顯示寄存器,采用地址自動加一 stb = 1; write(0xc0);//顯示寄存器的00H單元開始 for(h=0;h<16;h++) { write(show_led[h]);//給顯示寄存器送數(shù)據(jù), } stb=1; write(0x8b);//顯示控制參數(shù),點亮數(shù)碼屏幕,亮度可以通過改變低三位調(diào)節(jié) stb = 1; } //-------讀按鍵以及相應(yīng)的顯示處理-------void panjian(){ ucharcount3,key[4]; stb = 1; write(0x42);//送讀按鍵命令(42H), for(count3=0;count3<5;count3++) { key[count3]=read();//讀4BIT按鍵數(shù)據(jù), } if((key_FLAG1 != 0x02)) { if((key[0]==0x01)){key_LED= 0;key_FLAG1 = 0x01;show[key_COUNT1] = CODE[key_LED];} //K3與SEG1按鍵按下,數(shù)碼管顯示數(shù)字0 if((key[0]==0x02)){key_LED= 1;key_FLAG1 = 0x01;show[key_COUNT1] = CODE[key_LED];} //K2與SEG1按鍵按下,數(shù)碼管顯示數(shù)字1 if((key[0]==0x04)){key_LED= 2;key_FLAG1 = 0x01;show[key_COUNT1] = CODE[key_LED];} //K1與SEG2按鍵按下,數(shù)碼管顯示數(shù)字2。 if((key[0]==0x08)){key_LED= 3;key_FLAG1 = 0x01;show[key_COUNT1] = CODE[key_LED];} //K0與SEG2按鍵按下,數(shù)碼管顯示數(shù)字3。 if((key[0]==0x80)){key_LED= 4;key_FLAG1 = 0x01;show[key_COUNT1] = CODE[key_LED];} //K0與SEG3按鍵按下,數(shù)碼管顯示數(shù)字4。 if((key[0]==0x40)){key_LED= 5;key_FLAG1 = 0x01;show[key_COUNT1] = CODE[key_LED];} //K1與SEG3按鍵按下,數(shù)碼管顯示數(shù)字5。 if((key[0]==0x20)){key_LED= 6;key_FLAG1 = 0x01;show[key_COUNT1] = CODE[key_LED];} //K2與SEG4按鍵按下,數(shù)碼管顯示數(shù)字6。 if((key[0]==0x10)){key_LED=7;key_FLAG1 = 0x01;show[key_COUNT1] = CODE[key_LED];} //K3與SEG4按鍵按下,數(shù)碼管顯示數(shù)字7。 if((key[1]==0x01)){key_LED= 8;key_FLAG1 = 0x01;show[key_COUNT1] = CODE[key_LED];} //K3與SEG5按鍵按下,數(shù)碼管顯示數(shù)字8。 if((key[1]==0x02)){key_LED= 9;key_FLAG1 = 0x01;show[key_COUNT1] = CODE[key_LED];} //K2與SEG5按鍵按 下,數(shù)碼管顯示數(shù)字9 } if((key[1]==0x04)){key_FLAG1= 0x00; count7 = 0;} //K1與SEG6按鍵按下,key_FLAG1 = 0x00啟動定時器,時間開始。 if((key[1]==0x08)){count7 = 0x01;TR0 = 0;key_FLAG1 = 0x02;} //當K0與SEG6按鍵按下,key_FLAG1= 0x02單獨顯示數(shù)字按鍵無效! 暫停。 if((key[1]==0x80)) // K0與SEG7按鍵按下,key_FLAG1= 0x00啟動定時器,時間開始。 { key_FLAG1 = 0x00; count7 = 0; shi_2 = 0; shi_1 = 0; sub_2 = 0; sub_1 = 0; seconds_2 =0; TIME_seconds = 0; } if((key[1] == 0x40)) // K1與SEG7按鍵按下,控制數(shù)碼管右移一位 { show[key_COUNT1] = count4; key_FLAG1 = 0x01;//key_FLAG1 = 0x00關(guān)閉定時器,時間暫停。 key_COUNT1 ++; if((key_COUNT1 == 10)){ key_COUNT1 = 0;} } if((key[1] == 0x20)) // K2與SEG7按鍵按下,控制數(shù)碼管左移一位 {show[key_COUNT1] = count4; key_FLAG1 = 0x01;//key_FLAG1 = 0x00關(guān)閉定時器,時間暫停。 if((key_COUNT1==0)){ key_COUNT1 = 10;} key_COUNT1 -= 1; } if((key_FLAG1 == 0x01)){ count4 =show[key_COUNT1];}//保存當前按鍵位顯示數(shù)據(jù) if((count7 != 0x01)){ key_FLAG1 = 0;} } /********************************** 定時中斷函數(shù)入口功能: 每50MS中斷一次 **********************************/ void time0(void) interrupt 1 using 2{ TH0=0x3c; TL0=0xb0; TIME_count++; if(TIME_count==21) { TIME_count = 0; TIME_seconds++;// 秒寄存器加1 T_count ^= 0x80; }} /********************************* 時鐘函數(shù) 功能: 處理時鐘顯示 **********************************/voidTIME_show(){ //sub_1 =sub_1|0x80; //shi_1 = shi_1|0x80; show[15] =CODE[TIME_seconds];// 數(shù)碼屏上最后一個“8”字,依次下去 show[14] =CODE[seconds_2]; //數(shù)碼屏倒數(shù)第二個“8”字,show[13] = CODE[sub_1]|T_count; show[12] = CODE[sub_2]; show[11] =CODE[shi_1]|T_count; show[10] =CODE[shi_2]; if(TIME_seconds ==10) //對時間數(shù)據(jù)進行處理,以免溢出。 { TIME_seconds = 0; seconds_2+=1; } if(seconds_2 == 6) { seconds_2 = 0; sub_1 +=1; } if(sub_1== 10) { sub_1 =0; sub_2 +=1; } if(sub_2 == 6) { sub_2 =0; shi_1+=1; } if(shi_1== 10) { shi_1 =0; shi_2 +=1; } if(shi_2== 6) //時鐘每60小時自動清0 { shi_2 =0; shi_1 = 0; sub_2 = 0; sub_1 = 0; seconds_2 = 0; TIME_seconds = 0; }} /********************************* 延時函數(shù)功能: 1ms延時 **********************************/voiddelay_ms(uchar cyc){ //當將=1的時候,延時1ms uchar ii,jj; for(jj=1;jj<=cyc;jj++) { for(ii=0;ii<200;ii++) { nop; } } } /********************************* 主函數(shù) **********************************/void main(){ ucharcount6;//按鍵按下時,所控制的位閃! P0=0xff; P1=0xff; P2=0xff; P3=0xff;//初始化單片機I/O口TMOD=0x01; //定時器設(shè)置 TH0=0x3c; TL0=0xb0;IE=0x82; TF0=1; xianshi(show);//初始化顯示“HELLO”字符 _delay_ms(230); _delay_ms(230); _delay_ms(230); _delay_ms(230); _delay_ms(230); // 共延時 1s count4 =show[key_COUNT1]; while(1)// 循環(huán) { count6+=1; if((count6%2)) { show[key_COUNT1] = count4;// 基數(shù)時,顯示當位數(shù) } else { show[key_COUNT1] =0; // 偶數(shù)時,滅當位數(shù) ! 程序循環(huán) 2 次,閃一次。 } if(key_FLAG1 == 0x02){ TR0 = 0;} if(key_FLAG1 == 0x00){ TR0 = 1;} stb = 1; dio = 1; clk = 1; TIME_show(); // 控制做時鐘顯示 panjian(); // 判斷按鍵值 xianshi(show); // 根據(jù)按鍵值,給顯示寄存器送相應(yīng)的顯示數(shù)據(jù) _delay_ms(230);// 延時 240ms! if(count6== 201){ count6 = 0;} } }
|