您好,欢迎访问三七文档
第1页共17页题目:基于AT89C52单片机的多模式流水灯设计——程序设计一、概述AT89C52是一个低电压,高性能CMOS8位单片机,片内含8kbytes的可反复擦写的Flash只读程序存储器和256bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元。AT89C52有40个引脚,32个外部双向输入/输出(I/O)端口,同时内含2个外中断口,3个16位可编程定时计数器,2个全双工串行通信口,2个读写口线,AT89C52可以按照常规方法进行编程。P为40脚双列直插封装的8位通用微处理器,采用工业标准的C51内核,在内部功能及管脚排布上与通用的8xc52相同,其主要用于会聚调整时的功能控制。功能包括对会聚主IC内部寄存器、数据RAM及外部接口等功能部件的初始化,会聚调整控制,会聚测试图控制,红外遥控信号IR的接收解码及与主板CPU通信等。主要管脚有:XTAL1(19脚)和XTAL2(18脚)为振荡器输入输出端口,外接12MHz晶振。RST/Vpd(9脚)为复位输入端口,外接电阻电容组成的复位电路。VCC(40脚)和VSS(20脚)为供电端口,分别接+5V电源的正负端。P0~P3为可编程通用I/O脚,其功能用途由软件定义。二、实验原理与设计方案设计平台:AT89C51单片机;PC机,含Keil软件平台,Proteus软件平台;单片机开发板。第2页共17页如下图2为开发板:设计思路:本系统主要通过P1口来控制LED的闪烁,有10种模式(0~9)可供选择。通过模式按键来选择需要的闪烁方式,这里主要通过几个计数器来控制,按下一次按键,计数器加1,模式切换到下一种模式。同时利用数码管将模式显示出来。另外还有一个加速和减速的按键,系统设定有30种速度可供选择。按下一次加速键,速度计数器加1,按下一次减速键,速度计数器减1。其中加速减速主要是通过设定定时器2的定时时间来改变的,加速,减速主要是将定时器的时间加减。特别一提的是,按键的按下读取要消除抖动。设计方案与电路模块:要实现流水灯功能,我们只要将发光二极管LED1~LED16依次点亮、熄灭,16只LED灯便会一亮一暗的做流水灯了。在这个设计中,我们不只是单一的做向左运动或向右运动,而是设计了十个模式,而每一种模式也有30种速度可供选择,因此我们在普通的流水灯基础上增加了模式的选择功能、速度的选择功能和一个数码显示管来显示模式编号。在此我们还应注意一点,由于人眼的视觉暂留效应以及单片机执行每条指令的时间很短,我们在控制二极管亮灭的时候应该延时一段时间,否则我们就看不到“流水”效果了。该流水灯实验一共可分为六个模块:晶振电路模块、复位电路模块、数码管显示模块、AT89C52单片机模块、功能模式选择模块、LED流水灯模块。其中五个模块连接在AT89C52单片机上构成一个完整的系统。此系统的原理框图如图1所示:第3页共17页图11、晶振电路模块晶振是晶体振荡器的简称。在电气上它可以等效成一个电容和一个电阻并联再串联一个电容的二端网络,电工学上这个网络有两个谐振点,以频率的高低分其中较低的频率是串联谐振,较高的频率是并联谐振。由于晶体自身的特性致使这两个频率的距离相当的接近,在这个极窄的频率范围内,晶振等效为一个电感,所以只要晶振的两端并联上合适的电容它就会组成并联谐振电路。这个并联谐振电路加到一个负反馈电路中就可以构成正弦波振荡电路,由于晶振等效为电感的频率范围很窄,所以即使其他元件的参数变化很大,这个振荡器的频率也不会有很大的变化。晶振有一个重要的参数,那就是负载电容值,选择与负载电容值相等的并联电容,就可以得到晶振标称的谐振频率。一般的晶振的负载电容为15p或12.5p,如果再考虑元件引脚的等效输入电容,则两个22p的电容构成晶振的振荡电路就是比较好的选择。2、复位电路模块这个模块主要进行复位操作。3、LRD流水灯模块要实现流水灯功能,我们只要将发光二极管LED1~LED16依次点亮、熄灭,16只LED灯便会一亮一暗的做流水灯了。在此我们还应注意一点,由于人眼的视觉暂留效应以及单片机执行每条指令的时间很短,我们在控制二极管亮灭的时候应该延时一段时间,否则我们就看不到“流水”效果了。且每一个LED灯于一个电阻串联。4、功能模式选择模块在该模块中,我们要运用3个键,分别是模式键、加速键和减速键。因为该设计一共设有10种模式,因此模式键的功能就是选择运行哪一个模式。加速键顾名思义,是调节增加流水灯的运行速度。减速键就是减少流水灯的运行速度。5、数码管显示模块此模块主要是用来显示按下模式键后选择是哪个模式,其选择范围为0—9,既10个模式,因此只用一个数码管就可以了。第4页共17页三、硬件电路图与流程图1、电路图:硬件电路图2、消抖模块流程图因为在按键产生高电平的时候,数码管会产生抖动。在上升沿处抖动不强烈,可以忽略。但在下降沿处抖动会很强烈,而使我们很难观察到数码管的变化,只是会看到数码管在一直闪动,因此我们需要增加延迟的时间来消除抖动。如减慢键的程序:if(!(CheckValue&0x20))//判断是否被按下{delay(5);//判断上升沿if(!(CheckValue&0x20)){第5页共17页Key|=0x01;delay(500);//下降沿,消除抖动}elsereturn0x00;}上升沿的抖动可以忽略,故延迟时间只是5ms,而下降沿抖动剧烈,故延迟时间给了500ms,用以消除抖动。3、定时器中断和速度改变模块定时器中断程序:unsignedintTimerCount,SystemSpeed,SystemSpeedIndex;voidInitialTimer2(void){T2CON=0x00;//8位自动重装模式,设定时间,控制中断,控制流水灯速度TH2=RCAP2H=0xFC;//重装值,初始值TL2=RCAP2L=0x18;ET2=1;//定时器2中断允许TR2=1;//定时器2启动EA=1;}中断处理函数:voidTimer2(void)interrupt5using3{TF2=0;//中断端口,中断标志清除(Timer2必须软件清除标志)if(++TimerCount=SystemSpeed){TimerCount=0;TimerEventRun();}}速度改变程序:unsignedintcodeSpeedCode[]={1,2,3,5,8,10,14,17,20,30,40,50,60,70,80,90,100,120,140,160,180,200,300,400,500,600,700,800,900,1000};//30种速度第6页共17页voidSetSpeed(unsignedcharSpeed){SystemSpeed=SpeedCode[Speed];}这里采用数组法,并且定义一开始的速度是第十个,既30ms。4、主程序流程图由调用模式的模块实现:voidTimerEventRun(void){if(RunMode==0x00){Mode_0();}elseif(RunMode==0x01){Mode_1();}elseif(RunMode==0x02){Mode_2();}elseif(RunMode==0x03){Mode_3();}elseif(RunMode==0x04){Mode_4();}elseif(RunMode==0x05){Mode_5();}elseif(RunMode==0x06){Mode_6();}elseif(RunMode==0x07){Mode_7();}elseif(RunMode==0x08){Mode_8();}elseif(RunMode==0x09)第7页共17页{Mode_9();}}四、实验结果举例1、模式0:一个亮灯循环左移,按下列步骤运行,初始状态○○○○○○○○1○○○○○○○●2○○○○○○●○3○○○○○●○○4○○○○●○○○5○○○●○○○○6○○●○○○○○7○●○○○○○○8●○○○○○○○回初始状态重复循环2、模式5:四个亮灯一起循环左移,按下列步骤运行,初始状态○○○○○○○○1○○○○○○○●第8页共17页2○○○○○○●●3○○○○○●●●4○○○○●●●●5○○○●●●●○6○○●●●●○○7○●●●●○○○8●●●●○○○○9●●●○○○○○10●●○○○○○○11●○○○○○○○12○○○○○○○○3、模式8:五、实验总结在这次的作业中,我们选择做流水灯的实验,虽然难度不大,但我们用C语言编写了10种流水灯的模式,并从中较好的理解和运用AT89C52单片机的功能。我们利用空余时间焊了一个实物电路板,但由于粗心等原因,焊板质量比较粗糙。最终该焊板也没能正常工作。以下是我们的电路板:第9页共17页由于电路板不能正常工作,我们只好把原程序稍作改动,移植到开发板上,如图:另外上面所提到的电平抖动(电平毛刺)问题,按键抖动的问题对所有的处理器都存在,单片机、CPLD/FPGA以及ARM等等,都会存在抖动,所以在编写程序的时候,需要适当的绕开抖动的边沿再去采样,也就是说,要避免直接去采样按键瞬间产生的不稳定的信号。通常采用的方法有:延时采样和多次采样等,前者应用较多,如单片机中,按键之后延时一段时间再读取信号即可。本实验就是采用这种方法来消除抖动的。关于原程序的改动,就是去除了rst电路,其它原理和原程序完全一致。在编写程序时用的是C语言,其主要原因是因为相对之下,我比较掌握C语言,对于接近硬件方面的汇编不是很熟悉。编写最开始是要调用库文件、单片机端口、变量等。程序主要分5个部分:部分一是关于模式键的判断;部分二是流水灯的功能实现;部分三是调用模式;部分四是中断处理;部分五是执行循环。上面已经提过,消除抖动非常重要,主要办法是在下降沿地方给一个较大的延迟时间,以覆盖抖动的区域,不然实际操作中我们是看不到数码管的显示。通过这次作业,我对单片机的学习有了更深刻的掌握,并复习了C语言,对以后的设计提供基础。第10页共17页六、附录:完整C代码及注释#includeREG52.HunsignedcharRunMode;sbitdula=P2^6;sbitwela=P2^7;sbitleden=P2^5;voiddelay(unsignedintz)//无返回值,调用无符号变量z{unsignedintx,y;for(x=z;x0;x--)//x减1,循环语句for(y=110;y0;y--);}//**********************************SystemFuction*************************************************第一部分voidDelay1ms(unsignedintcount){unsignedinti,j;for(i=0;icount;i++)for(j=0;j120;j++);}unsignedcharcodeLEDDisplayCode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//0—9,定义一个无符号数组,显示一共有10种模式voidDisplay(unsignedcharValue)//上面10个取一个放进value{P0=LEDDisplayCode[Value];//P0端口接数码管}voidLEDFlash(unsignedcharCount)//设定LED的闪烁次数{unsignedchari;bitFlag;//定义flag是一个位数for(i=0;iCount;i++){Flag=!Flag;if(Flag)Display(RunMode);elseDisplay(0x10);Delay1ms(100);//延时100ms}Display(RunMode);}//整个功能为开电源后
本文标题:流水灯实验报告
链接地址:https://www.777doc.com/doc-7377860 .html