51+數碼管秒表可設定計時時間的程序
1》復位與啟動鍵:在任何模式下按此鍵回到初始化狀態等待計數或減數狀態。
2》調參數:在任何模式下按復位與啟動按鈕,先回到初始化狀態,再按鍵后。通過ADD鍵及SUB鍵調整計數參數
3》ADD與SUB鍵:按下復位鍵后或程序在初始狀態下按此鍵進入計數或減數狀態。
注意:仿真時請將程序里WELA的變量H=0 L=1,開發板試驗請將變量H=1 L=0;
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.gif (200.44 KB, 下載次數: 77)
下載附件
2021-11-14 03:46 上傳
說明.jpg (112.64 KB, 下載次數: 77)
下載附件
2021-11-13 09:41 上傳
單片機源程序如下:
- //***定時計數器***C程序***//
- #include<reg52.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define FOSC 11059200L //晶振設置,默認使用11.0592M Hz
- //#define FOSC 12000000L //晶振設置,使用12M Hz
- //#define FOSC 24000000L //晶振設置,使用24M Hz
- #define TIME_MS 50 //設定定時時間 ms ,在11.0592M晶振下,不易超過60ms
- #define LED_PORT P0
- //數碼管管腳定義:
- sbit wela_1 = P2^0;
- sbit wela_2 = P2^1;
- sbit wela_3 = P2^2;
- sbit wela_4 = P2^3;
- sbit wela_5 = P2^4;
- sbit wela_6 = P2^5;
- sbit wela_7 = P2^6;
- sbit wela_8 = P2^7;
- //IO接口定義
- sbit Key=P3^0; //計數啟動和復位鍵
- sbit Key1=P3^1; //調參數按鍵
- sbit Key2=P3^4; //遞增計數啟動鍵
- sbit Key3=P3^5; //遞減計數啟動鍵
- sbit buzzer=P3^7; //蜂鳴器
- sbit relay=P3^1; //繼電器
- //定義全局變量定義
- uchar count,num,num1,num2,num3,num4=0,num5=0,num6=0,num7,H=0,L=1,i; //變量H L表示0或1表示數碼管位的開啟需要不同的高低電平。實際和仿真電平相反。
- uchar M1,M2,M3,M4,M5,M6,K1,K2,K3,K4,K5,K6,K7,K8;
- uint ss,temp,temp2=5,temp10,temp20,temp30,temp40,temp50,temp60;
- short temp1=0;
- uint num10=100;
- //LED顯示字模 0-F 共陽模式
- unsigned code table0[]={0Xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; //不帶小數點段碼
- unsigned code table1[]={0X40,0x79,0x24,0x30,0x19,0x12,0x2,0x78,0x0,0x10,0x8,0x3,0x46,0x21,0x6,0x5,0x3f}; //帶小數點段碼
- //共陰極
- //unsigned code table0[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71};
- //子程序聲明。
- void LEDdisplay(unsigned int num);
- void LEDdisplay_1();
- void LEDdisplay_2();
- void LEDdisplay_3();
- void KEY();
- void KEY_1();
- void SUB();
- void ADD();
- void Keyscan();
- void Keyscan_ADD();
- void Keyscan_SUB();
- void buzze1();
- void buzze3();
- /*******************************************************************************
- * 函 數 名 :Delayms
- * 函數功能 :實現 ms級的延時函數
- * 輸 入 :ms
- * 輸 出 :無
- *******************************************************************************/
- void delayms(unsigned int ms)
- {
- unsigned int i,j;
- for(i=0;i<ms;i++)
- #if FOSC == 11059200L
- for(j=0;j<114;j++);
- #elif FOSC == 12000000L
- for(j=0;j<123;j++);
- #elif FOSC == 24000000L
- for(j=0;j<249;j++);
- #else
- for(j=0;j<114;j++);
- #endif
- }
- /*******************************************************************************
- * 函 數 名 :Timer0Init
- * 函數功能 :定時器0初始化
- * 輸 入 :無
- * 輸 出 :無
- *******************************************************************************/
- void Timer0Init()
- {
- TMOD=0x01; //設置定時器0工作方式為1
- TH0=(65536-FOSC/12/1000*TIME_MS)/256;
- TL0=(65536-FOSC/12/1000*TIME_MS)%256;
- ET0=1; //開啟定時器0中斷
- TR0=1; //開啟定時器
- EA=1; //打開總中斷
- }
- void Timer0Int() interrupt 1
- {
- TH0=(65536-FOSC/12/1000*TIME_MS)/256;
- TL0=(65536-FOSC/12/1000*TIME_MS)%256;
- count++;
- num1++;
- num2++;
- num3++;
- num7++;
- if(count==10) //100ms
- {
- count=0;
- KEY();
- KEY_1();
- temp30=temp20;
- }
- if(num3==22) //if(num3==22)
- {
- num3=0;
- if(K5==1) //加計數開關按下
- {
- if(temp30==0)
- {
- temp1=temp1+1;
- buzze1();
- if(temp1==temp40)
- {
- K5=0;
- //temp1=0;
- temp40=num10;
- //LEDdisplay_2();
- }
- }
- else if(temp30!=0)
- {
- temp1=temp1+1;
- buzze1();
- if(temp1==temp30)
- {
- //temp1=0;
- K5=0;
- buzze3();
- //LEDdisplay_2();
- }
- }
- }
- if(K6==1&&temp30==0) //減計數開關打開與temp30==0;
- {
- temp1=temp40--; //那么用99秒減
- buzze1();
- if(temp1<0) //temp1==0;的時候退出程序。
- {
- K6=0;
- temp1=0;
- temp40=num10; //////////////////////////
- buzze3();
- LEDdisplay_2();
- }
- } ///////////////////////////////////////////////////////////////////////
- if(K6==1&&temp30!=0&&num6==0) //如果temp30大于0說明有參數調整
- {
- temp50=temp30;
- num6=1;
- }
- if(K6==1&&num6==1)
- {
- temp1=temp50--; //按設定后的參數秒減時間 //////////////////////////////
- buzze1(); /////////////////////////////////////////////////////////////////////////
- if(temp1<0) //temp1==0;的時候退出程序。
- {
- K6=0;
- temp1=0;
- num6=0;
- buzze3();
- LEDdisplay_2();
- }
- }
- }
- if(num2==40) //數碼管閃爍中斷時間
- {
- K8=1;
- num2=0;
- }
- if(num7==100)
- {
- K7=1;
- num7=0;
- }
- }
- void main()
- {
- EX0=1;
- IT0=1;
- Timer0Init();
- temp40=num10;
- while(1)
- {
-
- LEDdisplay_1();
- if(Key!=1)
- {
- temp1=0; //中途退出加計數,計數歸零。
- buzze3();
- break;
- }
- }
- while(1) //11111
- {
-
- LEDdisplay(temp1); //顯示“0”等待選擇加減計數模式。
- if(!Key2||!Key3)
- {
- if(!Key2)
- {
- K5=1;
- }
- if(!Key3)
- {
- K6=1;
- }
- break;
- }
- }
- ADD();
- SUB();
- }
- /*******************************************************************************
- * 函 數 名 :LEDdisplay
- * 函數功能 :循環顯示各個位上的數據
- * 輸 入 :num 需要顯示的數據
- * 輸 出 :無
- *******************************************************************************/
- void LEDdisplay(unsigned int num)
- {
- unsigned char qian,bai,shi,ge;
- qian=num/1000;
- bai=num%1000/100;
- shi=num%100/10;
- ge=num%10;
- wela_1 = H; //關閉所有數碼管
- wela_2 = H; //用軟件仿真時關閉數碼管全部改為0,單片機下載改為1.
- wela_3 = H;
- wela_4 = H;
- wela_5 = H;
- wela_6 = H;
- wela_7 = H;
- wela_8 = H;
- if(qian<=0)
- {
- wela_4=L; //不顯示千位
- LED_PORT=0XFF;
- delayms(1);
- LED_PORT = 0xff;
- wela_4=H;
- }
- if(qian>=1)
- {
- if(M1!=1)
- {
- wela_4=L; //顯示千位
- LED_PORT=table0[qian];
- delayms(2);
- LED_PORT = 0xff;
- wela_4=H;
- num=0;
- }
- else if(num2==38)
- {
- wela_4=L; //顯示千位
- LED_PORT=table0[qian];
- delayms(2);
- LED_PORT = 0xff;
- wela_4=H;
- num=0;
- }
- }
- if(qian>=1||bai>=1)
- {
- if(M2!=1)
- {
- wela_3=L; //顯示百位
- LED_PORT=table1[bai];
- delayms(2);
- LED_PORT = 0xff;
- wela_3=H;
- }
-
- else if(num2==38)
- {
- wela_3=L; //顯示百位
- LED_PORT=table1[bai];
- delayms(2);
- LED_PORT = 0xff;
- wela_3=H;
- }
- }
- if(qian>=1||shi>=1||bai>=1)
- {
- if(M3!=1)
- {
- wela_2=L; //顯示十位
- LED_PORT=table0[shi];
- delayms(2);
- LED_PORT = 0xff;
- wela_2=H;
- }
- else if(num2==38)
- {
- wela_2=L; //顯示十位
- LED_PORT=table0[shi];
- delayms(2);
- LED_PORT = 0xff;
- wela_2=H;
- }
- }
- if(M4!=1)
- {
- wela_1=L; //顯示個位
- LED_PORT=table1[ge];
- delayms(2);
- LED_PORT = 0xff;
- }
- else if(num2==38)
- {
- wela_1=L; //顯示個位
- LED_PORT=table1[ge];
- delayms(2);
- LED_PORT = 0xff;
- }
- }
- void LEDdisplay_1() //顯示-ON-
- {
- uchar a;
- wela_1 = H; //關閉所有數碼管
- wela_2 = H; //用軟件仿真時關閉數碼管全部改為0,單片機下載改為1.
- wela_3 = H;
- wela_4 = H;
- wela_5 = H;
- wela_6 = H;
- wela_7 = H;
- wela_8 = H;
-
- for(a=0;a<8;a++)
- {
- buzze3();
- }
- while(1)
- {
- wela_4=L; //控制從右向左第4位顯示
- LED_PORT=0xbf;
- delayms(1);
- LED_PORT = 0xff;
- wela_4=H;
-
- wela_3=L; //控制從右向左第3位顯示
- LED_PORT=0xc0;
- delayms(1);
- LED_PORT = 0xff;
- wela_3=H;
-
- wela_2=L; //控制從右向左第2位顯示
- LED_PORT=0xc8;
- delayms(1);
- LED_PORT = 0xff;
- wela_2=H;
-
- wela_1=L; //控制從右向左第1位顯示
- LED_PORT=0xbf;
- delayms(1);
- LED_PORT = 0xff;
- wela_1=H;
-
- if(Key!=1||!Key1) //不管哪個為一就跳出
- delayms(100);
- if(Key!=1||!Key1)
- {
- buzze1();
- break;
- }
-
- }
- }
- void LEDdisplay_2()
- {
- while(1)
- {
- wela_1=H;
- wela_4=H;
- wela_5=H;
- wela_6=H;
- wela_7=H;
- wela_8=H;
- wela_4=L; //控制從右向左第4位顯示- 字符
- LED_PORT=0xBF;
- delayms(1);
- LED_PORT = 0xff;
- wela_4=H;
- wela_3=L; //控制從右向左第3位顯示 E 字符
- LED_PORT=0x86;
- delayms(1);
- LED_PORT = 0xff;
- wela_3=H;
-
- wela_2=L; //控制從右向左第2位顯示N 字符
- LED_PORT=0xC8;
- delayms(1);
- LED_PORT = 0xff;
- wela_2=H;
-
- wela_1=L; //控制從右向左第1位顯示D 字符
- LED_PORT=0xA1;
- delayms(1);
- LED_PORT = 0xff;
- wela_1=H;
- KEY();
- if(num5==0) //第二次按下開關 /////////////////////////////
- {
- buzze1();
- num5=0;
- break;
- }
- }
- }
- void LEDdisplay_3(unsigned int num)
- {
- unsigned char qian,bai,shi,ge;
- qian=num/1000;
- bai=num%1000/100;
- shi=num%100/10;
- ge=num%10;
- wela_1 = H; //關閉所有數碼管
- wela_2 = H; //用軟件仿真時關閉數碼管全部改為0,單片機下載改為1.
- wela_3 = H;
- wela_4 = H;
- wela_5 = H;
- wela_6 = H;
- wela_7 = H;
- wela_8 = H;
-
- wela_4=L; //顯示千位
- LED_PORT=table0[qian];
- delayms(2);
- LED_PORT = 0xff;
- wela_4=H;
- num=0;
- wela_3=L; //顯示百位
- LED_PORT=table1[bai];
- delayms(2);
- LED_PORT = 0xff;
- wela_3=H;
- wela_2=L; //顯示十位
- LED_PORT=table0[shi];
- delayms(2);
- LED_PORT = 0xff;
- wela_2=H;
-
- wela_1=L; //顯示個位
- LED_PORT=table1[ge];
- delayms(2);
- LED_PORT = 0xff;
-
- }
- void LEDdisplay_4(unsigned int num)
- {
- unsigned char qian,bai,shi,ge;
- qian=num/1000;
- bai=num%1000/100;
- shi=num%100/10;
- ge=num%10;
- wela_1 = H; //關閉所有數碼管
- wela_2 = H; //用軟件仿真時關閉數碼管全部改為0,單片機下載改為1.
- wela_3 = H;
- wela_4 = H;
- wela_5 = H;
- wela_6 = H;
- wela_7 = H;
- wela_8 = H;
- if(M1==1)
- {
- wela_4=L; //顯示千位
- LED_PORT=table0[qian];
- delayms(2);
- LED_PORT = 0xff;
- wela_4=H;
- }
-
- if(M2==1)
- {
- wela_3=L; //顯示百位
- LED_PORT=table1[bai];
- delayms(2);
- LED_PORT = 0xff;
- wela_3=H;
- }
- if(M3==1)
- {
- wela_2=L; //顯示十位
- LED_PORT=table0[shi];
- delayms(2);
- LED_PORT = 0xff;
- wela_2=H;
- }
- if(M4==1)
- {
- wela_1=L; //顯示個位
- LED_PORT=table1[ge];
- delayms(2);
- LED_PORT = 0xff;
- }
- }
- void KEY()
- {
- if(!Key)
- delayms(20);
- if(!Key)
- {
- num5=num5+1;
- if(num5==3)
- num5=0;
- while(!Key);
- }
- switch(num5)
- {
- case 1: K1=0;
- break;
- case 2: K1=1;
- break;
- case 3: K1=0;
- num5=0;
- break;
- }
- }
- void KEY_1()
- {
- if(!Key1)
- delayms(20);
- if(!Key1)
- {
- num5=num5+1;
- while(!Key1);
- }
- switch(num5)
- {
- case 1: K2=0;
- break;
- case 2: K2=1;
- break;
- case 3: K2=0;
- num5=0;
- break;
- }
- }
- void INT0_Srv() interrupt 0 //外部中斷0,開始設置
- {
- while(1)
- {
- LEDdisplay_3(temp);
- if(!Key) //**************************************
- {
- break;
- }
- }
- while(1) //***************************************
- {
- Keyscan();
- Keyscan_ADD();
- Keyscan_SUB();
- LEDdisplay_4(temp);
- if(M5==1) //****************************************
- {
-
- M1=0;
- M2=0;
- M3=0;
- M4=0;
- M5=0;
- temp20=temp10;
- break;
- }
- } //*******************************************
- }
- void Keyscan()
- {
- if(!Key)
- delayms(50);
- if(!Key)
- {
- num4=num4+1;
- if(num4==6)
- num4=0;
- while(!Key);
- }
- switch(num4)
- {
- case 0: M1=0;
- M2=0;
- M3=0;
- M4=0;
- M5=0;
- num4=0;
- M5=1;
- break;
- case 1: M1=1;
- M2=0;
- M3=0;
- M4=0;
- break;
- case 2: M1=0;
- M2=1;
- M3=0;
- M4=0;
- break;
- case 3: M1=0;
- M2=0;
- M3=1;
- M4=0;
- break;
- case 4: M1=0;
- M2=0;
- M3=0;
- M4=1;
- break;
- case 5: M1=1;
- M2=1;
- M3=1;
- M4=1;
- break;
- }
- }
- void Keyscan_ADD()
- {
- if(!Key2)
- delayms(20);
- if(!Key2)
- {
- if(M1==1)
- {
- temp=temp+1000;
- }
- else if(M2==1)
- {
- temp=temp+100;
- }
- else if(M3==1)
- {
- temp=temp+10;
- }
- else if(M4==1)
- {
- temp=temp+1;
- }
- if(temp>=10000)
- {
- temp=0;
- }
- temp10=temp;
- while(!Key2);
- }
- }
- void Keyscan_SUB()
- {
- if(!Key3)
- delayms(20);
- if(!Key3)
- {
- if(M1==1)
- {
- if(temp>0)
- {
- temp=temp-1000;
- }
- }
- else if(M2==1)
- {
- temp=temp-100;
- }
- else if(M3==1)
- {
- temp=temp-10;
- }
- else if(M4==1)
- {
- temp=temp-1;
- }
- if(temp<=0)
- {
- temp=0;
- }
- temp10=temp;
- while(!Key3);
- }
- }
- void buzze1() //發聲子程序1
- {
- uint t,tt;
- for(t=0;t<20;t++) //45為蜂鳴器發聲頻率
- {
- buzzer=!buzzer;
- for(tt=0;tt<100;tt++);
- }
- }
- void buzze3() //發聲子程序3
- {
- uint c;
- for(c=0;c<3;c++)
- {
- buzze1();
- }
- }
- void ADD()
- {
- if(K5==1) //K6==1
- {
- while(1)
- {
- LEDdisplay(temp1);
- KEY();
- if(num5==1) //如果key按下一次停止計數。
- {
- K5=0;
- K6=0;
- }
- if(!Key2) //判斷如果key2按下繼續計數。
- {
- K5=1;
- num5=0;
- }
- // }
- if(temp30==0&&temp1==temp40)
- {
- while(K8==1)
- {
- wela_1=L;
- wela_2=L;
- wela_3=L;
- wela_4=L;
- delayms(500);
- K8=0;
- if(K8==0)
- {
- break;
- }
- }
- }
- if(temp30!=0&&temp1==temp30)
- {
- num5=1;
- while(K8==1)
- {
- wela_1=L;
- wela_2=L;
- wela_3=L;
- wela_4=L;
- delayms(500);
- K8=0;
- if(K8==0)
- {
- break;
- }
- }
- }
- if(!Key||num5==2)
- {
- K5=0;
- K6=0;
- EA=0;
- temp1=0; //中途退出加計數,計數歸零。
- temp40=num10; //中途退出加計數,計數歸零。
- temp50=0; //中途退出加計數,計數歸零。
- buzze3();
- break;
- }
- }
- }
- }
- void SUB()
- {
- if(K6==1) //K6==1
- {
- while(1)
- {
- LEDdisplay(temp1);
- KEY();
- if(num5==1) //如果key按下一次停止計數。
- {
- K5=0;
- K6=0;
- }
- if(!Key3) //判斷如果key3按下繼續計數。
- {
- K6=1;
- num5=0;
- }
- if(temp1<=0) ///////////////////////////////////
- {
- num5=1;
- while(K8==1)
- {
- wela_1=L;
- wela_2=L;
- wela_3=L;
- wela_4=L;
- delayms(500);
- K8=0;
- if(K8==0)
- {
- break;
- }
- }
- }
- if(num5==2) ////////////////////////////////////////////////////////////////////////////////////////
- {
- K5=0;
- K6=0;
- EA=0;
- temp1=0; //中途退出加計數,計數歸零。
- temp40=num10; //中途退出加計數,計數歸零。
- temp50=0; //中途退出加計數,計數歸零。
- buzze3();
- break;
- }
- }
- }
- }
復制代碼
51hei.png (16.58 KB, 下載次數: 71)
下載附件
2021-11-14 03:47 上傳
所有資料51hei附件下載:
51+數碼管秒表可設定計時時間的仿真程序.rar
(104.56 KB, 下載次數: 33)
2021-11-13 09:41 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|