仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- /*温度控制仪主要材料变压器(220V-5V) 继电器、 STC89C52 、74LS145P 、74HC164、两个三位八段数码管。*/
- /*定时开关,可以设定什么时间启动,通电保持时间。该程序数码管第一位代表小时1-19。10以后的数字用小数点代表10。后两位是分钟。*/
- /*程序缺点:按键按下,数码管闪烁。暂未找到解决办法。另外想让设置键长按进入设置,小白一枚不会做,有高手希望指点一番。*/
- #include "reg51.h" //此文件中定义了单片机的一些特殊功能寄存器
- #define uint unsigned int //
- #define uchar unsigned char //
-
- int xmin=0,xhour=1,smin=10,shour=0;
- int count,sec,min,hour;
- int key_press=1;
- sbit DAT=P3^0;//显示段(数字)
- sbit CLK=P3^1;//锁存
- sbit JDQ=P3^5; //信号输出-控制继电器
- sbit KEY=P3^2; //按键
- //指示灯
- sbit L1=P0^0; // 设置 秒闪
- sbit L2=P0^1; // 增加
- sbit L3=P0^2; // 减少
- sbit A=P1^1;
- sbit E=P1^2;
- sbit C=P1^3;
- sbit D=P1^4;
- uchar sm_d[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
- 0xbf,0x96,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,
- 0x77,0x7c,0x39,0x5e,0x79,0x71};
- uint xs[4]; //保持分钟,保持小时,剩余启动分钟/已启动分钟、剩余启动小时/已启动小时
- //延时函数
- void delay(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- //发送数据函数
- void sendbyte(uchar byte)
- {
- uchar num,c;
- num=sm_d[byte];
- for(c=0;c<8;c++)
- {
- CLK=0;
- DAT=num&0x01;
- CLK=1;
- num>>=1;
- }
- }
- void js()
- {
- int a,b,c;
- a=sec+min*60+hour*60*60; //实时
- b=smin*60+shour*60*60; //变动时间
- c=xmin*60+xhour*60*60; //保持时间
-
-
- if(a<b) //启动倒计时
- {
- xs[0]=xmin; //下分钟
- xs[1]=xhour; //下小时
- xs[2]=((b-a)%3600)/60; //上分钟
- xs[3]=(b-a)/3600; //上小时
- JDQ=1;
- if(key_press==1)
- L2=0;
- else
- L2=1;
- }
- else if((b<a)&&(a<b+c)) //启动中
- {
- xs[0]=xmin;
- xs[1]=xhour;
- xs[2]=(a-b)%3600/60;
- xs[3]=(a-b)/3600;
- JDQ=0;
- if(key_press==1)
- L3=0;
- else
- L3=1;
- }
- else if(a>b+c)
- {
- xs[0]=0;
- xs[1]=0;
- xs[2]=(a-b-c)%3600/60;
- xs[3]=(a-b-c)/3600;
- JDQ=1;
- L2=1;
- L3=1;
- }
- }
- //正常显示函数
- void zcxs(uint wei)
- {
- uint i,j;
- uint zcsmg_num[6];
- js();
-
- zcsmg_num[0]= xs[0]%10;
- zcsmg_num[1]= xs[0]/10;
- zcsmg_num[2]= xs[1];
- zcsmg_num[3]= xs[2]%10;
- zcsmg_num[4]= xs[2]/10;
- zcsmg_num[5]= xs[3];
-
- for(i=0;i<6;i++)
- {
- switch(wei)
- {
- case 2:if((i==0)||(i==1)){j++;if(j<30)continue;else if(j>60)j=0;};break;
- case 3:if(i==2){j++;if(j<30)continue;else if(j>60)j=0;};break;
- case 4:if((i==3)||(i==4)){j++;if(j<30)continue;else if(j>60)j=0;};break;
- case 5:if(i==5){j++;if(j<30)continue;else if(j>60)j=0;};break;
- }
-
- switch(i)
- {
- case 0: A=0;E=0;C=0;D=0;sendbyte(zcsmg_num[0]);delay(2);break; //下右
- case 1: A=1;E=0;C=0;D=0;sendbyte(zcsmg_num[1]);delay(2);break;
- case 2: A=0;E=1;C=0;D=0;sendbyte(zcsmg_num[2]);delay(2);break;
- case 3: A=0;E=0;C=1;D=0;sendbyte(zcsmg_num[3]);delay(2);break; //上右
- case 4: A=1;E=0;C=1;D=0;sendbyte(zcsmg_num[4]);delay(2);break;
- case 5: A=0;E=1;C=1;D=0;sendbyte(zcsmg_num[5]);delay(2);break;
- }
- }
- }
- void Time0 (void) interrupt 1 using 1 //定时0中断函数
- {
- TH0=(65536-20000)/256; //0XEC
- TL0=(65536-20000)%256; //0X78
- count++;
- if(count<25)
- L1=0; //设置灯秒闪
- else
- L1=1;
- if(count==50)
- {
- sec++;
- count=0;
- if(sec==60)
- {
- min++;
- sec=0;
- if(min==60)
- {
- hour++;
- min=0;
- if(hour==39) //
- {
- hour=0;
- min=0;
- sec=0;
- }
- }
- }
- }
- }
- void init()
- {
- JDQ=1; //继电器高电平;
- L1=1;
- L2=1;
- L3=1;
- KEY=1;
-
- TMOD=0x01; //定时器T0工作于方式1,采用12M晶振,定时20ms
- TH0=(65536-20000)/256; //0XEC
- TL0=(65536-20000)%256; //0X78
-
- TR0 = 1; //定时器0开始计时
- ET0=1; //开定时器0中断
-
- EA=1; //开总中断
-
- }
- void key_scan()
- {
- uint i;
- for(i=6;i<9;i++)
- {
- switch(i)
- {
- case 6: A=1;E=1;C=1;D=0;delay(5);break; //按键
- case 7: A=0;E=0;C=0;D=1;delay(5);break;
- case 8: A=1;E=0;C=0;D=1;delay(5);break;
- }
-
- if(KEY==0)
- {
- delay(150);
- if((KEY==0)&&(i==6))
- {
- key_press++;
- if(key_press>5)
- key_press=1;
- }
- if(key_press!=1)
- {
- TR0=0;
- sec=0;
- min=0;
- hour=0;
- L1=0;
- }
- else
- {
- TR0=1;
- }
- if((KEY==0)&&(i==7)&&(key_press!=1))
- {
- L2=0;
- delay(100);
- switch(key_press%6)
- {
- case 2:xmin++;if(xmin>59)xmin=0;break;
- case 3:xhour++;if((xhour>19)&&(xmin==0)){xhour=0;xmin=5;}else if(xhour>19)xhour=0;break;
- case 4:smin++;if(smin>59)smin=0;break;
- case 5:shour++;if((shour>19)&&(smin==0)){shour=0;smin=5;}else if(shour>19)shour=0;break;
-
- }
- L2=1;
- }
- else if((KEY==0)&&(i==8)&&(key_press!=1))
- {
- L3=0;
- delay(100);
- switch(key_press%6)
- {
- case 2:xmin--;if(xmin<0)xmin=59;break;
- case 3:xhour--;if((xhour==0)&&(xmin==0)){xhour=0;xmin=10;}else if(xhour<0)xhour=19;break;
- case 4:smin--;if(smin<0)smin=59;break;
- case 5:shour--;if((shour==0)&&(smin==0)){shour=0;smin=5;}else if(shour<0)shour=19;break;
- }
- L3=1;
- }
- }
- else
- {
- zcxs(key_press);
- }
- }
- }
- void main()
- {
- init();
- while(1)
- {
- key_scan();
- }
- }
复制代码
Proteus仿真文件下载:
定时开关仿真.rar
(88.64 KB, 下载次数: 15)
|