基于80C51浇水小系统的Proteus仿真
在这里插入代码片
上图为这个小系统的仿真原理图,P2接的数码管其实是多余的,UP主有强迫症,所以把它接上了,感兴趣的初学者也可以玩一下怎么在这种情况下实现该数码管的0-9循环计数。
该系统实现的功能比较简单,就是到点浇水,通过用户自定义时间,即多少分钟后停水。24小时内可触发两次,只要指示灯不灭,将一直保持触发状态,每天到点触发。
z
(使用UP主的程序需要注意,当两次设置的时间为同一个小时时,触发将无法生效,可根据情况修改程序自行设定)
使用说明:
由于Protues没有电磁阀,也没有12V电源,此处通过接继电器的小灯代替电磁阀,VCC代替12V,实现仿真。
由上至下,我们分别设为它为KEY0-KEY5。在不同的屏幕下功能也不同。
屏幕标号 | 备注 |
---|---|
1 | 主时间计数屏幕 |
2 | 时间校准屏幕 |
3 | 浇水时间设定屏幕1 |
4 | 浇水时间设定屏幕2 |
屏幕 | 按键 | 功能 |
---|---|---|
所有 | KEY1 | 切屏 |
所有 | KEY5 | 停水 |
2、3、4 | KEY2 | 位选 |
2、3、4 | KEY3 | 置数 |
2、3、4 | KEY0 | 使能当前屏幕 |
??? | KEY4 | UP主强迫症 |
KEY0相当于确定键,按下后,所选位不闪烁,表示使能了当前屏幕;若在
浇水时间设定屏幕,则相应的指示灯将被点亮,并激活定时浇水功能。
(仿真与实物必有出入,希望同学们以实物为准,实践出真知。)
下面为所有源码,供大家拿来参考/学习/玩。
主函数
#include <reg52.h>
#include <start.h>
#include <screen1.h>
#include <screen2.h>
#include <screen3.h>
#include <screen4.h>
sbit select_screen=P3^1;
unsigned char i=0;
unsigned char screen_number=0;
unsigned char *SHOW_DATA=0;
/*unsigned char code watering_time[]=
{
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,
0x00,0x10
};*/
//定义16位共阳极0-F。
unsigned char code LED_data[16]=
{
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e
};
//定义8位共阳极数码管扫描码。
unsigned char LED_select[8]=
{
0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
};
void gain_data();
void Tab_screen();
void stop_all();
void open_start_water(void);
void main()
{
CPUexit_Init();
timer_Init(INT0,MODE_1);
timer_Init(INT1,MODE_1);
TH0=0xFC;
TL0=0x18;
TH1=0xD8;
TL1=0xF0;
P2=0x00;
P2|=0x02;
start_watering=1;
watering_LED_am=0;
watering_LED_pm=0;
while(1)
{
stop_all();
gain_data();
open_start_amwater();
open_start_pmwater();
}
}
//选屏幕
void Tab_screen()
{
if(key(select_screen))
{
flag=0;//闪烁位选
reset_twinkle();//光标复位
if(++screen_number==4)
screen_number=0;
}
}
//输出被选屏幕
void gain_data()
{
Tab_screen();
switch(screen_number)
{
case 0:SHOW_DATA=clock;break;
case 1:screen2_Clock(),SHOW_DATA=clock2;break;
case 2:screen3_Clock(),SHOW_DATA=clock3;break;
case 3:screen4_Clock(),SHOW_DATA=clock4;break;
}
}
void stop_all()
{
if(key(stop_watering))
{
watering_LED_am=0;
watering_LED_pm=0;
start_watering=1;
}
}
//10ms计数
void timer1()interrupt 3
{
TH1=0xD8;
TL1=0xF0;
main_Clock();
}
//1ms扫描输出
void timer0()interrupt 1
{
TH0=0xFC;
TL0=0x18;
if(delay_SWS)
{
delay_time++;
}
if(SWS)
{
if(++delay==10)
SWS=0;
}
switch(i)
{
case 0:P1=0xff,P0=LED_select[i];P1=LED_data[SHOW_DATA[0]],i++;break;//P1=0xff消隐
case 1:P1=0xff,P0=LED_select[i];P1=LED_data[SHOW_DATA[1]],i++;break;
case 2:P1=0xff,P0=LED_select[i];P1=LED_data[SHOW_DATA[2]],i++;break;
case 3:P1=0xff,P0=LED_select[i];P1=LED_data[SHOW_DATA[3]],i++;break;
case 4:P1=0xff,P0=LED_select[i];P1=LED_data[SHOW_DATA[4]],i++;break;
case 5:P1=0xff,P0=LED_select[i];P1=LED_data[SHOW_DATA[5]],i++;break;
case 6:P1=0xff,P0=LED_select[i];P1=LED_data[SHOW_DATA[6]],i++;break;
case 7:P1=0xff,P0=LED_select[i];P1=LED_data[SHOW_DATA[7]],i=0;break;
}
}
公共部分函数,内部有按键消抖,24小时设置,闪烁位选等函数
#ifndef _FUNCTION_INIT_H_
#define _FUNCTION_INIT_H_
#include <reg52.h>
sbit set_watertime=P3^0;
sbit select_bit=P3^2;
sbit set_data=P3^3;
sbit set_stop_time=P3^4;
sbit stop_watering=P3^5;
sbit start_watering=P3^6;
sbit watering_LED_am=P2^7;
sbit watering_LED_pm=P3^7;
extern unsigned char LED_select[8];
extern unsigned char select_bit2;
extern unsigned char select_bit3;
extern unsigned char select_bit4;
unsigned char SWS=0,delay=0;
unsigned char delay_SWS=0,delay_time=0;
unsigned char flag=0;
//按键消抖通用版
bit key(bit);
//延时函数
void Delay(unsigned char ms);
//闪烁位选
void twinkle(unsigned char Allselect_bit,unsigned char* ALLclock);
//当前屏幕时间设置函数:Allscreen_set_data(位选变量,数据数组)
unsigned char Allscreen_set_data(unsigned char Allselect_bit,unsigned char* Allclock);
//光标复位
void reset_twinkle(void);
bit key(bit button)//支持连按
{
SWS=0;
if(!button)
{
SWS=1;
}
while(SWS);
if(!button)
return 1;
else
return 0;
}
//延时函数
void Delay(unsigned char ms)
{
delay_SWS=1;
while(delay_SWS)
{
if(delay_time==ms)
{
delay_SWS=0;
delay_time=0;
}
}
}
//光标闪烁
void twinkle(unsigned char Allselect_bit,unsigned char* ALLclock)
{
if(!flag)
{
switch(Allselect_bit)
{
case 0: LED_select[Allselect_bit]=0,Delay(250),
ALLclock[Allselect_bit]=Allscreen_set_data(Allselect_bit,ALLclock),
LED_select[Allselect_bit]=0x01,Delay(250);break;
case 1: LED_select[Allselect_bit]=0,Delay(250),
ALLclock[Allselect_bit]=Allscreen_set_data(Allselect_bit,ALLclock),
LED_select[Allselect_bit]=0x02,Delay(250);break;
case 2: LED_select[Allselect_bit]=0,Delay(250),
ALLclock[Allselect_bit]=Allscreen_set_data(Allselect_bit,ALLclock),
LED_select[Allselect_bit]=0x04,Delay(250);break;
case 3: LED_select[Allselect_bit]=0,Delay(250),
ALLclock[Allselect_bit]=Allscreen_set_data(Allselect_bit,ALLclock),
LED_select[Allselect_bit]=0x08,Delay(250);break;
case 4: LED_select[Allselect_bit]=0,Delay(250),
ALLclock[Allselect_bit]=Allscreen_set_data(Allselect_bit,ALLclock),
LED_select[Allselect_bit]=0x10,Delay(250);break;
case 5: LED_select[Allselect_bit]=0,Delay(250),
ALLclock[Allselect_bit]=Allscreen_set_data(Allselect_bit,ALLclock),
LED_select[Allselect_bit]=0x20,Delay(250);break;
}
}
else
{
switch(Allselect_bit)
{
case 0:ALLclock[Allselect_bit]=Allscreen_set_data(Allselect_bit,ALLclock);break;
case 1:ALLclock[Allselect_bit]=Allscreen_set_data(Allselect_bit,ALLclock);break;
case 2:ALLclock[Allselect_bit]=Allscreen_set_data(Allselect_bit,ALLclock);break;
case 3:ALLclock[Allselect_bit]=Allscreen_set_data(Allselect_bit,ALLclock);break;
case 4:ALLclock[Allselect_bit]=Allscreen_set_data(Allselect_bit,ALLclock);break;
case 5:ALLclock[Allselect_bit]=Allscreen_set_data(Allselect_bit,ALLclock);break;
}
}
}
//当前屏幕时间设置函数:Allscreen_set_data(位选变量,数据数组)
unsigned char Allscreen_set_data(unsigned char Allselect_bit,unsigned char* Allclock)
{
if(!Allselect_bit||Allselect_bit==2||(Allselect_bit==4&&Allclock[5]<2))
{
if(key(set_data))
if(++Allclock[Allselect_bit]==10)
Allclock[Allselect_bit]=0;
}
else if(Allselect_bit==1||Allselect_bit==3)
{
if(key(set_data))
if(++Allclock[Allselect_bit]==6)
Allclock[Allselect_bit]=0;
}
else if(Allclock[5]==2&&Allselect_bit==4)
{
if(key(set_data))
if(++Allclock[Allselect_bit]==5)
Allclock[Allselect_bit]=0;
}
else if(Allselect_bit==5)
{
if(key(set_data))
if(++Allclock[Allselect_bit]==3)
Allclock[Allselect_bit]=0;
}
return Allclock[Allselect_bit];
}
void reset_twinkle(void)
{
select_bit2=0;
select_bit3=0;
select_bit4=0;
}
#endif
主时间屏幕
#ifndef _SCREEN1_H_
#define _SCREEN1_H_
#include <function_init.h>
//主时间计数
unsigned char clock[8]={0,0,0,0,0,0,0,0};
unsigned char tms=0,second=0,min=0,hour=0;
void main_Clock();
void main_Clock()
{
tms++;
if(tms==100)
{
second++;
tms=0;
}
if(second==60)
{
second=0;
min++;
}
if(min==60)
{
min=0;
hour++;
}
if(hour==24)
{
hour=0;
}
clock[0]=second%10;
clock[1]=second/10%10;
clock[2]=min%10;
clock[3]=min/10%10;
clock[4]=hour%10;
clock[5]=hour/10%10;
clock[6]=15;
clock[7]=10;
}
#endif
主时间校准屏幕
#ifndef _SCREEN2_H_
#define _SCREEN2_H_
#include <function_init.h>
//时间矫正区
unsigned char clock2[]={0,0,0,0,0,0,15,11};
unsigned char select_bit2=0;
void screen2_Clock();
void screen2_Clock()
{
if(key(select_bit))
{
flag=0;
if(++select_bit2==6)
select_bit2=0;
}
twinkle(select_bit2,clock2);
if(key(set_watertime))
{
flag=1;
second=clock2[0]+clock2[1]*10;
min=clock2[2]+clock2[3]*10;
hour=clock2[4]+clock2[5]*10;
}
}
#endif
第一个浇水时间的设定,可设为早(晚)。
#ifndef _SCREEN3_H_
#define _SCREEN3_H_
#include <function_init.h>
extern unsigned char clock[8];
extern unsigned char clock4[8];
unsigned char clock3[]={0,14,0,0,0,0,15,12};
unsigned char select_bit3=0;
typedef struct ma
{
unsigned char a;
unsigned char b;
}p;
//上午浇水时间设定
void screen3_Clock(void);
void open_start_amwater(void);
void screen3_Clock(void)
{
if(key(select_bit))
{
flag=0;
if(++select_bit3==6)
select_bit3=0;
if(select_bit3==1)
select_bit3=2;
}
twinkle(select_bit3,clock3);
if(key(set_watertime))
{
flag=1;
watering_LED_am=1;
}
}
void open_start_amwater(void)
{
if(clock4[5]!=clock3[5]&&clock4[4]!=clock3[4])
{
if(watering_LED_am)
{
if(clock[5]==clock3[5]&&clock[6]==clock3[6]&&clock[3]==clock3[3])
if(clock[2]==clock3[2])
start_watering=0;
else if(clock[2]-clock3[2]==clock3[0]||(!clock3[0]&&clock[2]!=clock3[2]))
start_watering=1;
}
}
else
watering_LED_am=0;
}
#endif
第二个浇水时间的设定,可设为晚(早)。
#ifndef _SCREEN4_H_
#define _SCREEN4_H_
#include <function_init.h>
extern unsigned char clock[8];
extern unsigned char clock3[8];
unsigned char select_bit4=0;
unsigned char clock4[]={0,15,0,0,3,1,15,13};
//下午时间设定
void screen3_Clock(void);
void open_start_pmwater(void);
void screen4_Clock(void)
{
if(key(select_bit))
{
flag=0;
if(++select_bit4==6)
select_bit4=0;
if(select_bit4==1)
select_bit4=2;
}
twinkle(select_bit4,clock4);
if(key(set_watertime))
{
flag=1;
watering_LED_pm=1;
}
}
void open_start_pmwater(void)
{
if(clock4[5]!=clock3[5]&&clock4[4]!=clock3[4])
{
if(watering_LED_pm&&clock4[5]!=clock3[5]&&clock4[4]!=clock3[4])
{
if(clock[5]==clock4[5]&&clock[6]==clock4[6]&&clock[3]==clock4[3])
if(clock[2]==clock4[2])
start_watering=0;
else if(clock[2]-clock4[2]==clock4[0]||(!clock4[0]&&clock[2]!=clock4[2]))
start_watering=1;
}
}
else
watering_LED_pm=0;
}
#endif