摘要
本实验是基于PHILIPS AT89C51 单片机所设计的,可以实现键位与数字动态显示的一种频率可调数字方波发生器。通过键盘键入(10HZ-10kHZ)随机频率,使用七段数码管显示,每一个数码管对应一个键位。单片机对各个键位进行扫描,确定键位的输入,然后数码管显示输入的数值,方波发生器输出以数码管显示的数值为频率的方波。
关键词:单片机 七段数码管 键盘电路 频率可调数字方波发生器
一、目的和功能
1.1 目的:
设计一种频率范围限定且可调的数字方波发生器,产生特定频率的方波。
1.2功能:
假设键盘是4*4的键盘,当键盘输入范围在10hz-10khz的数字,单片机控制数码管显示该数值,并把该数值当做数字方波发生器的输入频率,单片机控制数字方波发生器以该数值作为频率显示方波,从而得到我们想要频率的方波。
二、硬件设计
2.1 硬件设计思想
键盘的数字和键位关系固定,通过键盘输入产生频率,通过LED数码管显示出来,每一个数码管对应一个键位。基本设备是基于PHILIPS AT89C51单片机,外围设备采用的是4个七段数码管,PHILIPS AT89C51单片机,1个OSCILLOSCOPE 方波发生器,16个Button,若干电阻,电源电池。
2.2 部分硬件方案论述
2.2.1 七段数码管扫描显示方式的方案比较
方案一: 静态显示方式:静态显示方式是指当显示器显示某一字符时,七段数码管的每段发光二极管的位选始终被选中。在这种显示方式下,每一个LED数码管显示器都需要一个8位的输出口进行控制。静态显示主要的优点是显示稳定,在发光二极管导通电流一定的情况下显示器的亮度大,系统运行过程中,在需要更新显示内容时,CPU才去执行显示更新子程序,这样既节约了CPU的时间,又提高了CPU的工作效率。其不足之处是占用硬件资源较多,每个LED数码管需要独占8条输出线。随着显示器位数的增加,需要的I/O口线也将增加。
方案二: 动态显示方式:动态显示方式是指一位一位地轮流点亮每位显示器(称为扫描),即每个数码管的位选被轮流选中,多个数码管公用一组段选,段选数据仅对位选选中的数码管有效。对于每一位显示器来说,每隔一段时间点亮一次。显示器的亮度既与导通电流有关,也与点亮时间和间隔时间的比例有关。通过调整电流和时间参数,可以既保证亮度,又保证显示。若显示器的位数不大于8位,则显示器的公共端只需一个8位I/O口进行动态扫描(称为扫描口),控制每位显示器所显示的字形也需一个8位口(称为段码输出)。动态显示器的优点是节省硬件资源,成本较低。但在控制系统运行过程中,要保证显示器正常显示,CPU必需每隔一段时间执行一次显示子程序,占用CPU大量时间,降低了CPU的工作效率,同时显示亮度较静态显示器低。
由于PHILIPS AT89C51单片机本身提供的I/O口有限,因此我们选择方案二——动态扫描方式。扫描方式中在轮流点亮扫描过程中,每位显示器的点亮时间是极为短暂的约1ms,但由于人的视觉暂留现象及发光二极管的余辉效应,尽管实际上各位显示器并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感。节约了电能,节省 了I/O口。
2.2.2 键盘连接方式方案比较
方案一:独立式键盘
一个具有4个按键的独立式键盘,每一个按键的一端都接地,另一端接mega16的I/O口。独立式键盘每一按键都需要一根I/O线,占用mega16的硬件资源较多。因此独立式键盘只适合按键较少的场合。键盘是一组按键或开关的集合,键盘接口向计算机提供被按键的代码。特点:使用方便、结构复杂、成本高。
方案二:矩阵式键盘
我们采用4×4矩阵式键盘,键盘的行线X0~X3通过电阻接+5V,当键盘没有键闭合时,所有的行线和列线断开,行线X0~X3均呈高电平。当键盘上某一键闭合时,该键所对应的行线与列线短路,此时该行线的电平将由被短路的列线电平所决定。如果将行线接至单片机的输入端口,列线接至单片机的输出端口,则在单片机的控制下使列线Y0为低电平,其余三根列线Y1、Y2、Y3均为高电平,然后单片机读输入口状态(即键盘行线状态),若X0、X1、X2、X3均为高电平,则Y0这一列上没有键闭合,如果读出的行线状态不全为高电平,则为低电平的行线和Y0相交的键处于闭合状态。如果Y0这一列没有键闭合,紧接着使列线Y1为低电平,其余列线为高电平,用同样的方法检查Y1这一列有无键闭合,如此类推。这种逐行逐列地检查键盘状态的过程称为对键盘的扫描。CPU对键盘的扫描可以采取程序控制的随机方式,CPU空闲时才扫描键盘;也可以采取定时控制方式,每隔一段时间,CPU对键盘扫描一次;还可以采用中断方式,当键盘上有键闭合时,向CPU请求中断,CPU响应键盘发出的中断请求,对键盘进行扫描,以识别哪一个键处于闭合状态,并对键输入信息作相应处理。
因为如果采用独立式键盘PHILIPS AT89C51的I/O口对于方案一来说将是远远不够用的,为了节省I/O口,使我们的设计能够顺利进行,我们选用方案二——矩阵连接式键盘。为了能够较为简单的编程,和节省CPU的资源,我们采用定时扫描,每隔一段时间,CPU对键盘扫描一次,并将键值读入。
2.3 硬件电路图
三、软件
3.1 软件设计基本思想:
●键盘的不间断扫描。
●4个八段数码管的动态显示。
●方波发生器方波的输出
3.2 程序框图
3.3 程序功能
初始化后单片机产生初值,将初值以动态扫描的方式显示于八段数码管 ,同时还对键盘进行实时扫描,在扫描后,单片机读取键值,并将键值通过数码管模块显示出来,方波发生器输出该频率的方波。
四、总结
4.1已达到的成果:硬件电路图和键盘及显示的程序。
4.2未完成的部分:软件关于实行初值计算部分以及仿真。
4.3设计感悟:这一次课程设计遇到了很多问题。硬件基本上是没有问题的,每个人都会做;但是程序是我们的弱点,还有就是分工合作,很多时候都是有分歧,还好最后还有水兵帮忙,使得我们的程序进一步完善。做完这个程序只是我们学做程序的开始吧,今后会继续加强我们在做程序上的功力。
附录一程序代码
#include < reg52.h>
sbit out=P1^0;
#define uchar unsigned char
#define uint unsigned int
uchar TH,TL,c;
uchar keyscan();
void delay(uint z);
void main()
{
uchar s;
out=1;
EA=1;
ET0=1;
TR0=1;
while(1)
{
s=keyscan();
switch(s)
{
case 0x0e://10HZ
TH=0x3c;
TL=0xb0;TMOD=0X01;
break;
case 0x0d://100HZ
TH=0xec;
TL=0x78;TMOD=0X01;
break;
case 0x0b://1kHZ
TH=0xfe;
TL=0x0c;TMOD=0X01;
break;
case 0x07://10kHZ
TH=0xff;
TL=0xce;TMOD=0X01;
break;
}
}
}
void delay(uint z)
{
uint x,y;
for(x = z;x>0;x--)
for(y = 124;y>0;y--);
}
void timer0() interrupt 1
{
TH0=TH;
TL0=TL;
out=!out;
}
uchar keyscan()
{
uchar key;
if((P3&0x0f)==0x0f) return(0xff);
delay(20);
if((P3&0x0f)==0x0f) return(0xff);
key=(P3&0x0f);
while((P3&0x0f)!=0x0f);
return(key);
}
参考文献
1、潘永雄 高等学校信息工程类专业规划教材(新编单片机原理与应用)
第二篇:基于51单片机洗衣机课程设计报告
单片机原理及系统课程设计
专 业:自 动 化
班 级:12级《2》班
组 长:陈 浩
组 员:郑辉龙,王国稳,
指导教师:
基于51单片机的洗衣机设计
1设计目的、要求及原理
1.1设计目的
由单片机控制实现洗衣机的各项功能,单片机的体积小,控制功能灵活,因此,设计出基于单片机的全自动洗衣机控制电路系统具有很强的实用性。用单片机设计出简单操作省水省电的洗衣机,在方便日常生活和节约资源方面都有重要意义。由于个人能力有限,我能设计的洗衣机比前沿科技产品要差很多。所以我这次课设的主要目的在于通过亲手操作,查找资料,培养自己的分析设计能力。把这学期课程中零散的知识进行整合,将理论的知识联系到实际的生活中。在实例中深入理解一些理论知识,并从中有所收获,就是意义所在。
1.2设计要求
通过仿真软件模拟洗衣机的基本工作过程,如进水、洗涤、排水、漂洗、脱水等。
1.3设计方法
利用89C51单片机的P0,P1,P2,P3串行输入输出功能,控制数码管、电机、发光二极管的工作状态模拟洗衣机的基本工作过程。
2设计方案及原理
2.1设计方案
洗衣机的主要工作程序是:进水—洗涤—排水—进水—漂洗—排水—脱水—排水。上述工作程序中,主要包含三个过程,洗涤过程、漂洗过程、脱水过程。
(1) 洗涤过程:放好待洗物,启动开关,进水阀通电,向洗衣机供水,当供水达到预定时间后,进水阀断电关闭,停止供水。洗涤电动机接通电源,带动波轮(或桶)旋转,产生各种形式的水流搅动衣物进行洗涤。通过电动机不停的正转、反转,形成洗涤水对洗涤物产生强烈的翻滚作用。同时,衣物之间、衣物与四周桶壁之间产生互相摩擦和撞击力,以次达到洗涤衣物的目的。
(2) 漂洗过程:漂洗的目的在于清除衣物上的洗涤液。因此,在洗涤结束之后,换水进行漂洗。漂洗过程与洗涤过程的电器动作是完全相同的。为了完全漂净衣服上的洗衣粉等,所以要多次漂洗,在这次设计中漂洗次数设定为三次。
(3) 脱水过程:漂洗后,需要对衣物进行脱水以便晾干,节省水资源,所以脱水是洗衣过程中必不可少的环节。漂洗过程结束后,电动机停止转动,排水阀通电,打开排水阀门排水。当排水到达预定时间后,脱水电动机接通,电机带动脱水桶高速旋转,利用离心力把衣服上的水从桶壁的小眼里甩出。全部洗衣工作完成后,表示结束的LED灯点亮,表示衣物已经洗好,洗衣机在这时就会自动停止工作。
2.2设计原理
本设计用51单片机实现对洗衣机的控制,通过功能选择开关可以选择洗衣机的工作模式。当选择好模式后洗衣机进入相应的工作状态。该模式的参数已装入单片机中,洗衣机在单片机中预先装入程序的控制下进行工作。
程序实现的主要功能是洗涤,漂洗和脱水的控制。其中洗涤时间设为96s,用sec和min控制,其中sec代表分钟min代表秒。并且通过改变它们的值可以改变洗涤时间。用P3.2和P3.3控制电机的正反转(通过它们高低不同的电平控制电流的方向,从而改变电机的转向。漂洗过程和洗涤过程较为相似,由于漂洗要多次进行,所以用进水次数标志位flag1控制漂洗的次数,当flag1=2、3、4时为漂洗过程。脱水过程是在出水次数flag2的控制下进行。当flag2=4时脱水,当脱水时间到达0后,脱水结束,洗衣结束,表示停止的指示灯亮。
图1 系统组成框图
3硬件设计
3.1系统主要元器件
在本设计中主要使用了以下元器件:AT89C51芯片、74LS245芯片 、四数码管、发光二极管、直流电动机、三极管等。
3.2设计原理图
洗衣机的各项功能是由单片机控制实现的,单片机的体积小,控制功能灵活,因此,设计出基于单片机的全自动洗衣机控制电路系统具有很强的实用性采用5l系列单片机作为控制核心,主要包括功能选择及控制电路、洗衣机工作状态显示及输出控制电路。控制电机正反转以及进水阀和排水阀的开启和关闭。如图2所示为设计原理图。
图2 硬件连接图
4软件设计
4.1主程序流程图
按下K1键,洗衣机从待命状态。当按下K2键后,51单片机通过预先装入的程序控制各引脚的状态,让洗衣机才进入工作状态,以实现进水、洗衣、排水、漂洗、脱水、报警等基本功能。主程序流程图如图3所示。
图3 主程序流程图
5系统仿真及实际调试
5.1仿真结果
图4 :系统仿真结果
5.1问题分析
本电路为模拟洗衣机工作过程,所以进水和排水部分只能用输出引脚上的发光二极管表示工作状态,报警电路为脱水过程的保护电路,当脱水未结束打开洗衣机盖的时候,报警电路工作并断开电机电源,防止发生事故。
6总结
在本设计中通过软,硬件的配合设计,很好的实现了洗衣机的控制功能。本系统结构简单,控制功能强大,自动化程度高等特点。 系统软硬件设计采用模块化的设计方法,各模块功能相对独立,最后把它们整合在一起,大大的缩短了系统的设计周期。为保证洗衣机及人身安全,设计了报警电路。本设计还考虑半自动的设计,用户可以根据自己的需求自由选择洗衣机的工作方式,这一点是通过功能选择键实现的。通过这次单片机课程设计,不仅巩固了课本上所学的知识,而且更加深刻地认识到了单片机在生活中的重要地位,通过这次课程设计让我对单片机系统设计的过程与方法有了一定的认识,很好的培养了自己的创新设计能力。
参考文献
[1] 李朝青.单片机原理及接口技术[M].北京:北京航空航天出版社,1999.
[2] 顾滨.单片微计算机原理、开发及应用[M].北京:高等教育出版社,2000.
[3] 王思明,张金敏,苟军年等.单片机原理及应用系统设计[M]:科学出版社,2012.
[4] 房小翠.单片机实用系统设计技术[M].北京:国防工业出版社,1990.
附录
1源程序
#include
#define uchar unsigned char
#define uint unsigned int
//***************************//
sbit mo_r=P3^2; //电机右控制线
sbit mo_l=P3^3; //电机左控制线
//****************************//
sbit key_menu=P3^4; // 菜单按键
sbit key_on=P3^5; // 开始按键
sbit key_off=P3^6; // 结束按键
sbit key_se=P3^7; // 菜单选择按键
//***************************//
sbit led_in=P0^0; // 进水指示灯
sbit led_xi=P0^1; // 洗衣指示灯
sbit led_pao=P0^2; // 泡洗指示灯
sbit led_xx=P0^3; // 脱水指示灯
sbit led_out=P0^4; // 出水指示灯
sbit led_over=P0^5; // 洗衣结束指示灯
sbit led_work=P0^6; // 电机工作指示灯
sbit led_wring=P0^7; // 报警指示灯
sbit other=P3^1; // 脱水电源控制开关
sbit anther=P3^0; // 洗衣电源控制开关
//******************************//
uchar code num[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
//*****************************//
char sec=0; // 时间秒
char min=0; // 时间分
uchar count=0; // 中断计数
uchar flag0=0; // 洗衣机工作状态标志
uchar flag1=0; // 进水次数标志
uchar flag2=0; // 出水次数标志
uchar flag3=0; // 泡洗次数标志
uchar err=0; // 报警标志
uchar quan=0; // 正反转计数
//**********************************//
void delay(); // 延时函数
void in(); // 进水子程序
void out(); // 出水子程序
void over(); // 结束子程序
void xi(); // 洗衣子程序
void pao(); // 泡衣子程序
void xx(); // 脱水子程序
void on(); // 工作on处理子程序
void se(); // 显示菜单选择
void SEG_display(); // 显示时间子程序
void key_scan(); // 按键扫描子程序
void delay(uint i)
{
uint x,y;
for(x=i;x>0;x--)
for(y=120;y>0;y--);
}
//*********工作on处理子程序**********//
void on()
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
P0 = 0xff;
if(flag0==0)
in();
if(flag0==1)
xi();
if(flag0==2)
pao();
if(flag0==3)
xx();
if(flag0==4)
out();
}
//********结束子程序*********//
void over()
{ other=0;
anther=0;
P0=0xff;
mo_r=0;
mo_l=0;
led_over=0;
EA=0;
}
//**********进水子程序**********//
void in()
{ anther=0;
other=0;
P0=0xff;
led_in=0;
flag1++;
mo_r=0;
mo_l=0;
min=0;
sec=8;
}
//**********洗衣子程序**********//
void xi()
{ anther=1;
other=0;
P0=0xff;
led_work=0;
led_xi=0;
mo_r=1;
mo_l=0;
min=1;
sec=36;
quan=0;
}
//
//********泡衣子程序********//
void pao()
{
anther=1;
other=0;
P0=0xff;
led_pao=0;
led_work=0;
flag3++;
mo_r=1;
mo_l=0;
min=1;
sec=35;
quan=0;
}
//*********脱水子程序********//
void xx()
{ other=1;
anther=0;
P0=0xff;
led_xx=0;
mo_r=0;
mo_l=1;
min=0;
sec=50;
}
//********出水子程序********//
void out()
{ anther=0;
other=0;
P0=0xff;
led_out=0;
flag2++;
mo_r=0;
mo_l=0;
min=0;
sec=5;
}
//**********显示菜单选择********//
void se()
{
P0=0xff;
if(flag0 >= 5)
flag0=0;
if(flag0==0)
{
led_in=0;
}
if(flag0==1)
{
led_xi=0;
}
if(flag0==2)
{
led_pao=0;
}
if(flag0==3)
{
led_xx=0;
}
if(flag0==4)
{
led_out=0;
}
}
//*********菜单处理子程序**********//
void menu()
{
min=0;
sec=0;
mo_r=0;
mo_l=0;
SEG_display();
while(1)
{
if(key_on==0)
{
delay(5);
if(key_on==0)
{
while(!key_on);
on();
break;
}
}
//**************************//
if(key_off==0)
{
delay(5);
if(key_off==0)
{
while(!key_off);
over();
break;
}
}
//****************************//
if(key_se==0)
{
delay(5);
if(key_se==0)
{
while(!key_se);
flag0++;
se();
}
}
}
}
//*********按键扫描子程序*********//
void key_scan()
{
if(key_menu==0)
{
delay(5);
if(key_menu==0)
{
while(!key_menu);
menu();
}
}
//********************************//
if(key_on==0)
{
delay(5);
if(key_on==0)
{
while(!key_on);
on();
}
}
//*********************************//
if(key_off==0)
{
delay(5);
if(key_off==0)
{
while(!key_off);
over();
}
}
}
//*********显示子程序**********//
void SEG_display()
{
P1=0x01;
P2=num[min/10];
delay(10);
P1=0x02;
P2=num[min%10];
delay(10);
P1=0x04;
P2=num[sec/10];
delay(10);
P1=0x08;
P2=num[sec%10];
delay(10);
}
//*********主函数**********//
void main()
{
led_in=0;
anther=0;
other=0;
while(1)
{
SEG_display();
key_scan();
}
}
//*****定时器0中断处理程序*****//
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;
if(count==20)
{
count=0;
sec--;
if((flag0==1)||(flag0==2))
{
quan++;
switch(quan)
{
case 1:mo_r=1;mo_l=0;break;
case 10:mo_r=0;mo_l=0;break;
case 15:mo_r=0;mo_l=1;break;
case 25:mo_r=0;mo_l=0;break;
default:;
}
if(quan==30)
{
quan=0;
}
}
//**********************************//
if((sec==0)&&(min != 0))
{
min--;
sec=59;
}
//**********************************//
if((sec<0)&&(min==0)&&(flag0==0)) //进水结束
{
switch(flag1)
{
case 1:flag0=1;xi();break;
case 2:flag0=2;pao();break;
case 3:flag0=2;pao();break;
case 4:flag0=2;pao();break;
default: err=1;led_wring = 0;
}
}
//**********************************//
if((sec<0)&&(min==0)&&(flag0==1)) //洗衣结束
{
flag0=4;
out();
}
//**********************************//
if((sec<0)&&(min==0)&&(flag0==2)) //泡衣结束
{
switch(flag3)
{
case 1:flag0=4;out();break;
case 2:flag0=4;out();break;
case 3:flag0=4;out();break;
default: err=1;led_wring = 0;
}
}
//**********************************//
if((sec<0)&&(min==0)&&(flag0==4)) //出水结束
{
switch(flag2)
{
case 1:flag0=0;in();break;
case 2:flag0=0;in();break;
case 3:flag0=0;in();break;
case 4:flag0=3;xx();break;
default: err=1;led_wring=0;
}
}
//***********************************//
if((sec<0)&&(min==0)&&(flag0==3))
{ sec=0;
over();
}
}
}