心形灯的设计
设计一个心形灯,包含以下功能:
1、由32个LED灯组成心形流水灯,外接了4个按键,并且两个按键(开始和暂停)接在两个外部中断引脚上;
2、上电后心形灯先全亮5秒,后亮灭闪烁5秒,可以测试灯状态的好坏;
3、之后处于全灭等待状态,当按下开始按键后心形灯按照一定规律显示,规律自定义,创意越好分数越高;
4、当在任意状态下按下暂停键后心形灯停留在当前状态不再改变,再一次按下暂停键后则继续显示;
5、另外一个键为模式切换键,每按一次切换键则切换一次显示模式,切换键在灯运行状态和暂停状态均可切换;
6、第四个键为速度键,可以改变心形灯的亮灭切换速度,通过速度键可以切换不同的切换速度。
关键词:心形流水灯,AT89C51,复位电路,时钟电路,电路仿真
一、随着现代科学技术的持续进步和发展以及人们生活水平的不断提高,以大规模、超大规模集成电路为首的电子工艺技术的使用也越来越广泛,结合单片机技术设计的电子电路也层出不穷。 LED彩灯由于其丰富的灯光色彩、低廉的造价以及控制简单等特点而得到了广泛的应用,用彩灯来装饰街道和城市建筑物已经成为一种时尚。利用控制电路可使彩灯按一定的规律不断的改变状态,不仅可以获得良好的观赏效果,而且可以省电。
彩灯的运用已经遍布于人们的生活中,从歌舞厅到卡拉OK包房,从节日的祝贺到日常生活中的点缀,这些不仅说明了我们对生活的要求有了质的飞跃,也说明科技在现实生活中的运用有了较大的发展。在这一设计中我们将运用单片机技术,与单片机芯片AT89C51的功能,对心形流水灯系统进行设计,来实现流水灯的多种亮与灭的循环,给人带来美感。
当今社会,这种由单片机芯片控制各种硬件工作的技术也日益成熟,并普及在交通、化工、机械等各个领域。而流水灯这项技术在生活中的应用更是广泛,较为贴近生活。而流水灯的设计所需要的知识也正好吻合了我们本学期对于单片机这门课程的学习,所以设计流水灯控制的这个课题让我们对知识的学习和巩固都有了进一步的加深。
- 单片微计算机自20世纪70年代问世以来,已对人类生活产生了巨大的影响。尤其是美国Intel公司生产的MCS-51系列单片机,由于其具有集成度高、可靠性强、系统结构简单、价格低廉、易于使用等优点,在世界范围内已经得到了广泛的普及和应用,也正是由于单片机的这些特点,它的出现是集成电路技术与微型计算机技术高速发展的产物,给工业自动化等领域带来了一场重大的革命。
单片机体积小,很容易嵌入到系统之中,以实现各种方式的检测、计算或控制,而一般的微型计算机无法做到。由于单片机本身就是一个微型计算机,因此只要在单片机的外部适当的增加一些必要的外围扩展电路,就可以灵活的构成各种应用系统,如工业自动检测监控系统、数据采集系统、自动控制系统、智能仪器仪表等,除此之外,单片机在家用电器中的应用也很普及,例如,洗衣机、电冰箱、空调机、电风扇、电视机、微波炉、加湿机、消毒柜等,在这些设备中嵌入了单片机之后,其功能和性能大大提高,并可实现智能化和最优化控制。
第二章 概要设计
一、AT89C51介绍
1、芯片功能
AT89C51是一种带4K字节闪烁可编程可擦除只读存储器(FPEROM—Falsh Programmable and Erasable Read Only Memory)的低电压,高性能CMOS8位微处理器,俗称单片机。该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器,为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。
2、管脚说明
VCC:供电电压。
GND:接地。
P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。当P1口的管脚一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。
P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。
P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。
P3口:P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电流。当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。
P3口也可作为AT89C51的一些特殊功能口,如下表所示:
口管脚 备选功能
P3.0 RXD(串行输入口)
P3.1 TXD(串行输出口)
P3.2 /INT0(外部中断0)
P3.3 /INT1(外部中断1)
P3.4 T0(记时器0外部输入)
P3.5 T1(记时器1外部输入)
P3.6 /WR(外部数据存储器写选通)
P3.7 /RD(外部数据存储器读选通)
P3口同时为闪烁编程和编程校验接收一些控制信号。
RST:复位输入。当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。
ALE/PROG:当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节。在FLASH编程期间,此引脚用于输入编程脉冲。在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。因此它可用作对外部输出的脉冲或用于定时目的。然而要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲。如想禁止ALE的输出可在SFR8EH地址上置0。此时, ALE只有在执行MOVX,MOVC指令是ALE才起作用。另外,该引脚被略微拉高。如果微处理器在外部执行状态ALE禁止,置位无效。
/PSEN:外部程序存储器的选通信号。在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。
/EA/VPP:当/EA保持低电平时,则在此期间外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器。注意加密方式1时,/EA将内部锁定为RESET;当/EA端保持高电平时,此间内部程序存储器。在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。
XTAL1:反向振荡放大器的输入及内部时钟工作电路的输入。
XTAL2:来自反向振荡器的输出。
3.振荡器特性:
XTAL1和XTAL2分别为反向放大器的输入和输出。该反向放大器可以配置为片内振荡器。石晶振荡和陶瓷振荡均可采用。如采用外部时钟源驱动器件,XTAL2应不接。有余输入至内部时钟信号要通过一个二分频触发器,因此对外部时钟信号的脉宽无任何要求,但必须保证脉冲的高低电平要求的宽度。
二、选择AT89C51芯片
选择AT89C51芯片后,选择元器件连接仿真图
三、写代码
写出代码,控制灯亮循环,中断
第三章 系统软件设计
c51只有两级中断,所以这里将外部中断0与外部中断1进行嵌套使用,相当于外部只用了外部中断0,外部中断1嵌套在了外部中断0里面。然后设置中断优先级,由于只有两级中断,所以设置了定时器中断优先级高,外部中断0优先级低。其中外部中断0的功能是控制开始,外部中断1的功能是控制暂停,定时器中断控制的是心型灯亮灭的类型和亮灭速度。
第四章 系统仿真设计
一个AT89C51芯片,三个BUTTON按键,一个JUMPER,32个LED-BIRY,三个GROUND接地端,连接如图所示
第五章 总结
一、刚开始画仿真图时一个口接一个灯,导致所有接口用完了,按键没地方接。并且在接P0口的灯不亮,后来才发现需要用上拉电阻
二、重新画仿真图后,接按键写代码时,外部中断1与外部中断0的优先级没考虑到,只能实现一个按键的内容。在搜索查询后,使用中断嵌套才可以。在设计切换灯闪烁规律与速度的按键时出现了同样的优先级问题,多次调试改变优先级才成功。
第六章 参考文献
[1] 林志琦.基于Proteus的单片机可视化软硬件仿真[M] .北京:北京航空航天大学出版社,2006.
[2] 何立民.MCS-51单片机应用系统设计[M] .北京:北京航空航天大学出版社,1990.
[3] 张毅刚.单片机原理及应用[M] .北京:高等教育出版社,2004.
[4] 谷树忠,刘文洲,姜航.Altium Designer教程-原理图、PCB设计与仿真.北京:电子工业出版社,2010.
[5] 张阳天,韩异凡.Protel DXP电路设计[M].北京:高等教育出版社,2005.
第七章 附录
//L&J
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit key1=P3^2; //位定义
sbit key2=P3^3;
sbit key3=P3^4;
sbit key4=P3^5;
uint sudu=1000;
uint time=0,type=0;
bit flag=0;
void delay_ms(unsigned int ms)
{
unsigned int a;
while(ms--) //while()内的ms不为0,即为真
for(a=0;a<123;a++);
}
void ss1()
{
P1=0xff;
P2=0X00;
delay_ms(sudu);
while(key2==0);
P1=~P1; //取反
P2=~P2;
delay_ms(sudu);
}
void ss2()
{
P1=0xf0;
P2=0X0f;
delay_ms(sudu);
while(key2==0);
P1=~P1;
P2=~P2;
delay_ms(sudu);
}
void ss3()
{
P1=0x10;
P2=0X01;
delay_ms(sudu);
while(key2==0);
P1=~P1;
P2=~P2;
delay_ms(sudu);
}
void ss4()
{
P1=0x55;
P2=0X55;
delay_ms(sudu);
while(key2==0);
P1=~P1;
P2=~P2;
delay_ms(sudu);
}
void fun()
{
while(1)
{
while(key2==0);
if(type%4==0) ss1();
else if(type%4==1) ss2();
else if(type%4==2) ss3();
else ss4();
}
}
//xiaoshouzi
void T0_INT() interrupt 0//开始中断
{
fun();
}
void T1_INT() interrupt 2//开始中断
{
flag=~flag;
}
void T0_TIME() interrupt 1
{
TH0=(65536-5000)/256;//取高八位,算初值
TL0=(65536-5000)%256;//取低八位
if(key3==0)
{ delay_ms(10);
if(key3==0)
type++;
}
if(key4==0)
{ delay_ms(10);
if(key4==0)
time++;
}
if(time%4==0) sudu=1000;
else if(time%4==1) sudu=500;
else if(time%4==2) sudu=300;
else if(time%4==3) sudu=100;
}
//W&H
void main()
{
uint i;
P1=0xff;
P2=0xff;
delay_ms(500);
for(i=0;i<5;i++)
{
P1=~P1;
P2=~P2;
delay_ms(100);
}
TMOD=0x01;//中断方式1
IT0 = 1; //TCON中控制INT0触发方式位,INT0下降沿触发中断
IT1 = 1;
EA = 1; //总中断允许
EX0 = 1;
EX1 = 1;
ET0=1;//允许t0中断
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
TR0=1;//控制位打开
IP=0X02;
while(1)
{
P1=0X00;
P2=0X00;
}
}