51+数码管秒表可设定计时时间的程序
1》复位与启动键:在任何模式下按此键回到初始化状态等待计数或减数状态。
2》调参数:在任何模式下按复位与启动按钮,先回到初始化状态,再按键后。通过ADD键及SUB键调整计数参数
3》ADD与SUB键:按下复位键后或程序在初始状态下按此键进入计数或减数状态。
注意:仿真时请将程序里WELA的变量H=0 L=1,开发板试验请将变量H=1 L=0;
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- //***定时计数器***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附件下载:
51+数码管秒表可设定计时时间的仿真程序.rar
(104.56 KB, 下载次数: 33)
|