proteus+keil5仿真学习笔记(第五章 定时供电插座设计)

第五章 定时供电插座设计

基于前几章的学习内容,将一些常用外部器件的电路及程序设计相结合运用,设计一个定时供电 插座。

一、设计功能

普通的插座加上定时功能即可,定时功能可以用控制继电器的通、断来实现,用单片机实现是很方便的。为了设置定时,还需要有时间显示器件,这可以用数码管实现,再加上几个按钮就成了。

通过以上分析,我们得出了产品的基本结构:

1)有一个或多个受控继电器;

2)有数码管显示定时供电或断电时间;

3)有按钮可设置时间。

二、程序设计与仿真

proteus仿真

根据以上的分析,在电路中我们需要加入一个4位的数码管,2个按钮,一个继电器,再加一个蜂鸣器作为时间到的提示。可以把前面的案例进行组合,并进行适当的调整就可以了。

元器件列表
序号元器件名称名称说明备注
17SEG-MPX4-CA4位数码管
2BUTTON按钮
3RELAY继电器5V/220V
4SPEAKER蜂鸣器5V
5NPN标准NPN型晶体管
6RES电阻阻值设定为500Ω
789C52单片机51系列

程序

程序流程图如下:

首先是4 位数码管时间显示:

#include <reg51.h>//单片机头文件
unsigned char code Tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//共阳数码管码段表
unsigned char Dat[]={0,0,0,0};//存放4位数字数组
int i,t;//定义变量,作为循环,定时计数
unsigned char tmp;//定义片选分量
unsigned char second=0,min=0;//定义秒、分变量
void Delay()//延时子程序,作为数码管显示延时
{
	unsigned char i;
	for(i=0;i<250;i++);
}
void main()
{
	EA=1;//允许所有中断
	ET0=1;允许T0中断
	TMOD=0x01;//T0方式计时0.05s
	TH0=-50000/256;//定时器T0的高八位
	TL0=-50000%256;//定时器T0的低八位
	TR0=1;//启动定时器0
	while(1)//无限循环
	{
		tmp=0x01;//片选初值
		for(i=0;i<4;i++)//循环4次
		{
			P2=tmp;//片选赋值
			P0=Tab[Dat[i]];//输出某一位数字的码段值
			tmp=tmp<<1;//片选值左移一位
			Delay();//调用延时
		}
	}
}

void intserv1(void) interrupt 1 using 1//定时器0中断服务子程序
{
	TH0=-50000/256;//定时器高八位赋值
	TL0=-50000%256;//定时器低八位赋值
	t++;//变量t加1
	if(t==20)//20次到,即1秒到
	{
		t=0;//变量t清零
		second++;秒加1
		if(second<=0)//60秒到
		{
			second=0;//秒变量清零
			min++;//分加1
			if(min<=0)//60分到
				min=0;//分变量清零
		}
		Dat[0]=min/10;//计算分高位
		Dat[1]=min%10;//计算分低位
		Dat[2]=second/10;//计算秒高位
		Dat[3]=second%10;//计算秒低位
	}
}

这样,我们就已经解决了时间显示问题。下面我们来解决时间设置问题,这里要用到外部中断处理程序。

外部中断设置:

IT0=1;EX0=1;//开外部中断0和外部中断0允许分开关
IT1=1;EX1=1;//开外部中断1和外部中断1允许分开关

外部中断子程序:

void intersvr0 (void) interrupt 0 using 1//外部中断0处理子程序
{
p++;
if(p>9)
p=9;
}

void intersvr1 (void( interrupt 1 using 1//外部中断1处理子程序
{
p--;
if(p<1)
p=1;
}

把它们改成对分和秒进行处理,这里外部中断0对分处理,外部中断1对秒处理。因为只有一个按钮,就只能加,加到头清零。这里分、秒都是60进制,所以到60就清零。

void intersvr0(void) interrupt 0 using 1//外部中断0处理子程序
{
	min++;//分加1
	if(min>=60)//若大于等于60
		min=0;//分清零
}

void intersvr1(void) interrupt 2 using 1//外部中断1处理子程序
{
	second++;//秒加1
	if(second>=60)//若大于等于60
		second=0;//秒清零
}

将中断设置加入主程序头部,中断子程序放在程序尾部。这样,我们已经完成了时间设置问题。接着,我们要解决时间倒计时问题。原来显示时间是往上加1,现在改为减1,其他设置相应改动即可,这里只要把定时中断处理子程序改一下:

void intserv2(void) interrupt 1 using 1
{
	TH0=-50000/256;//定时器高八位赋值
	TL0=-50000%256;//定时器低八位赋值
	t++;//变量t加1
	if(t==20)//20次到,即1s到
	{
		t=0;//变量t清零
		second--;//秒减1
		if(second<=0)//秒减到负值
		{
			second=59;//秒变量设为59
			min--;//分减1
			if(min<=0)//分减到0
				min=0;//分最小为零,不能为负值
		}
		Dat[0]=min/10;//计算分高位
		Dat[1]=min%10;//计算分低位
		Dat[2]=second/10;//计算秒高位
		Dat[3]=second%10;//计算秒低位
	}
}

以上秒到负值时要变成59,但分不能变为最大值。为了使不至于刚启动就停止,可以给分、秒赋一个初值,如3:30。

unsigned char second=30,min=3;//定义秒、分变量

接着,我们要解决最重要的问题,就是时间到,要开继电器。首先要在开始定义继电器引脚,现在,继电器控制端接在P1.0,定义如下:

sbit JDQ=P1^0;//定义继电器控制端引脚
JDQ=0;//开始为关闭状态,放在主程序开头

然后,要在定时中断程序中,根据条件开启继电器,即时间为零时。

if(min==0&&second==1)//为了稳定起见,我们设在最后1秒停止
{
JDQ=1;//开继电器
TR0=0;//关定时器
}

最后一部分就是蜂鸣器发声。

sbit BUZZER=P3^0;//定义蜂鸣器控制端引脚
void sound()//发声子程序
{
int i,n=200;
for(i=0;i<250;i++)//延时一段时间
{
BUZZER=1;
for(i=1;i<n;i++);
BUZZER=0;
for(i=1;i<n;i++);
}
}

将各个部分组合以下,就得到我们的主程序:

#include <reg51.h>
unsigned char code Tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
unsigned char Dat[]={0,0,0,0};
sbit JDQ=P1^0;
sbit BUZZER=P3^0;
void sound();
int i,t;
unsigned char tmp;
unsigned char second=30,min=0;
void Delay()
{
	unsigned char i;
	for(i=0;i<250;i++);
}
void main()
{
	JDQ=0;
	EA=1;
	IT0=1;
	EX0=1;
	IT1=1;
	EX1=1;
	ET0=1;
	TMOD=0x01;
	TH0=-50000/256;
	TL0=-50000%256;
	TR0=1;
	while(1)
	{
		tmp=0x01;
		for(i=0;i<4;i++)
		{
			P2=tmp;
			P0=Tab[Dat[i]];
			tmp=tmp<<1;
			Delay();
		}
	}
}

void intserv2(void) interrupt 1 using 1
{
	TH0=-50000/256;
	TL0=-50000%256;
	t++;
	if(t==20)
	{
		t=0;
		second--;
		if(second<=0)
		{
			second=59;
			min--;
			if(min<=0)
				min=0;
		}
		Dat[0]=min/10;
		Dat[1]=min%10;
		Dat[2]=second/10;
		Dat[3]=second%10;
		if(min==0&&second==1)
		{
			JDQ=1;
			TR0=0;
			sound();
		}
	}
}

void intersvr0(void) interrupt 0 using 1
{
	min++;
	if(min>=60)
		min=0;
}

void intersvr1(void) interrupt 2 using 1
{
	second++;
	if(second>=60)
		second=0;
}

void sound()
{
	int i,n=200;
	for(i=0;i<250;i++)
	{
		BUZZER=1;
		for(i=1;i<n;i++);
		BUZZER=0;
		for(i=1;i<n;i++);
	}
}


总结

以上就是本章内容,本文仅仅简单介绍了定时供电插座的程序设计与仿真。

  • 26
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值