单片机跑马灯
单片机跑马灯(流水灯)控制实验报告

单片机跑马灯(流水灯)控制实验报告实验目的:本实验旨在通过使用单片机对LED灯进行控制,实现跑马灯(流水灯)的效果,同时熟悉单片机编程和IO口的使用。
实验器材:1)STC89C52单片机2)最基本的LED灯3)面包板4)若干跳线实验过程:1.硬件连接:将单片机的P2口与面包板上的相应位置连接,再将LED灯接入面包板中。
2.编写程序:按照题目要求编写所需程序。
3.单片机烧录:将程序烧录进单片机中,即可实现跑马灯效果。
程序详解:1. 由于LED灯是呈现亮灭效果,我们要编写程序来控制LED的亮灭状态。
2. 在程序中,我们通过P2口控制LED灯的亮灭状态。
例如,若要让LED1亮,我们就将P2口的第一个引脚设置为低电平(0),此时LED1就会发光。
同样地,若要LED2,LED3等依次点亮,则需要将P2口的第二个、第三个引脚设置为低电平,依此类推即可。
3. 接下来,我们要实现每个LED灯的亮灭时间间隔,并实现跑马灯的效果。
4. 在本实验中,我们采用了计时器中断的方式来实现灯光的控制,即在定时器中断函数中对P2口进行控制,这样可以方便地控制灯亮灭时间和亮度。
通过改变定时器中断的时间,可以改变LED灯的亮灭时间;通过改变P2口的控制顺序,可以实现跑马灯效果。
5. 整个程序比较简单,具体的代码实现可以参考以下程序:#include <REG52.H>#include <intrins.h>#define uint unsigned int #define uchar unsigned char void Delay1ms(uchar _ms); void InitTimer0();sbit led1=P2^0;sbit led2=P2^1;sbit led3=P2^3;sbit led4=P2^4;sbit led5=P2^5;sbit led6=P2^6;sbit led7=P2^7;void InitTimer0(){TMOD=0x01;TH0=(65536-50000)/256; TL0=(65536-50000)%256; EA=1;ET0=1;TR0=1;}void Timer0() interrupt 1 {static uint i;TH0=(65536-50000)/256; TL0=(65536-50000)%256;i++;if(i%2==0){led1=~led1;}if(i%4==0){led2=~led2;}if(i%6==0){led3=~led3;}if(i%8==0){led4=~led4;}if(i%10==0){led5=~led5;}if(i%12==0){led6=~led6;}if(i%14==0){led7=~led7;}}void Delay1ms(uchar _ms){uchar i;while(_ms--){i=130;while(i--);}}实验总结:通过本次实验,我们掌握了单片机控制跑马灯(流水灯)的方法,对单片机编程和IO 口的使用有了更深入的了解。
单片机课程设计--跑马灯设计

单片机课程设计(跑马灯设计)专业:电气自动化摘要AT89C51是一种带4K字节闪存可编程可擦除只读存储器)(FPEROM—Flash Programmable and Erasable Read Only Memory 的低电压、高性能CMOS 8位微处理器,即单片机。
AT89C2051是一种带2K字节闪存可编程可擦除只读存储器的单片机。
单片机的可擦除只读存储器可以反复擦除1000次。
该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。
该设计使用A T89C51芯片作为控制芯片,利用P1口连接8个发光二极管,通过I/O的值控制“跑马灯”的亮灭,以达到显示效果。
开始时所有灯全亮,按下按键S时开始跑马灯,再按下按键S时停止,再按下S时继续,并要求有多种亮暗组合。
时继续,并要求有多种亮暗组合。
按键跑马灯 按键单片机 跑马灯关键词:A T89C51单片机目录摘要 (I)第一章芯片分析和设计概述 (3)第一节 AT89C51芯片分析 (3)第一节第二节 设计概述 (8)第二节第二章硬件电路设计 (9)第三章程序部分设计 (10)参考文献 (18)第一章 芯片分析和设计概述第一节 AT89C51芯片分析ATMEL 的AT89S51是一种高效微控制器,将多功能8位CPU 和闪烁存储器组合在单个芯片中,为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。
且价廉的方案。
AT89C51AT89C51的芯片引脚图如下:的芯片引脚图如下:图1.1 AT89C51引脚图引脚图各引脚的说明和功能分析如下:各引脚的说明和功能分析如下:VCC VCC:供电电压。
:供电电压。
:供电电压。
GND GND:接地。
:接地。
:接地。
P0口:口:P0P0口为一个8位漏级开路双向I/O 口,每脚可吸收8TTL 门电流。
当P1口的管脚第一次写1时,被定义为高阻输入。
时,被定义为高阻输入。
P0P0能够用于外部程序数据存储器,它可以被定义为数据外部程序数据存储器,它可以被定义为数据//地址的第八位。
单片机实例之跑马灯PPT课件

40
常用的调试按钮
KEIL 软件开发平台
复位按钮全,速按停运止全进速入跳循运跳过环行出循并单环步并执执单行行到断点处
下后,所行有的
系统状态将变
单步执行步执过行程
成初始状态。
图3-27 调试按钮
.
41
KEIL 软件开发平台
二、ISP软件的使用
打开下载软件,双击目录下的文件 ISP析,实现任务的思路是:程序 开始时,给某一变量赋初始值0xFE,然后每次将 数据左移后送入P1口直到所有循环次数输出完毕, 再次重复整个过程。根据思路得出的程序框图如 图3-29所示。
.
46
图3-29 程序流程图
.
47
(1)C语言程序:
#include "reg51.h"
#include "intrins.h"
退出此程序。
.
42
.
43
任务二 跑马灯
本任务让图3-28中的LED依次点亮
图3-28 LED硬件图
.
44
程序设计分析
为了让图3-28所示的LED依次点亮,就是要求从P1口从 P1.0至P1.7依次输出低电平,其余引脚都输出高电平,就 能让被接在端口的彩灯依次点亮。
从输出的具体的数据来看,第一个LED点亮需要的输 出数据,是对应于P1.0的位为0,其余位为1,组合为一个 字节时对应的二进制位从高到低为:1111 1110,即十六 进制数0xFE;同理,第二个LED点亮对应的数为:1111 1101,化为十六进制数为0xFD。
图3-10 目标1属性设置窗口
.
24
KEIL 软件开发平台
图3-11 目标1输出窗口设置
.
单片机试验三:跑马灯试验

单片机试验三:跑马灯试验
前面做了二极管的点亮与熄灭和二极管闪烁试验,在这基础上再来做一个
跑马灯试验。
所用到的器件也是试验板上的八只二极管,要让它们一个个的轮
流循环点亮,需要该变P1 口的值,即先送入11111110B 给P1 口,让第一只二级管点亮,由于程序执行时间很短(微秒级),所以我们需要它亮一段时间,
就是所说的延时;然后再送入11111101B 给P1 口即第二只点亮,其它都是熄灭的,延时,再让第三只点亮。
就这样不断的循环,这就成跑马灯了。
程序如下:第一种:
ORG 1000H
LJMP BEGIN
BEGIN: MOV A,#11111110B ;低电平对应的发光二极管亮
MOV P1,A ;将值送到P1 口,第一只点亮
LCALL DL ;调用延时
MOV A,#11111101B
MOV P1,A ;第二只点亮
LCALL DL ;调用延时
MOV A,#11111011B
MOV P1,A ;第三只点亮
LCALL DL ;调用延时
MOV A,#11110111B
MOV P1,A ;第四只点亮
LCALL DL ;调用延时
MOV A,#11101111B。
51单片机8个跑马灯程序汇编设计思路

【51单片机8个跑马灯程序汇编设计思路】1. 引言在嵌入式系统中,跑马灯程序是一个非常常见且基础的程序设计。
通过控制LED灯的亮灭顺序,实现灯光在一组灯中顺序轮流亮起的效果。
其中,51单片机是一种常用的嵌入式系统开发评台,本文将探讨如何通过汇编语言设计实现8个跑马灯程序的思路和方法。
2. 分析题目我们需要对题目进行细致的分析。
51单片机8个跑马灯程序要求我们设计并实现一个程序,能够控制8个LED灯依次轮流亮起的效果。
这意味着我们需要对LED灯进行控制,并且需要考虑如何实现循环、延时等功能。
3. LED灯控制在实现跑马灯程序时,首先需要考虑如何控制LED灯的亮灭。
一种常见的方法是通过I/O口控制LED灯的高低电平,从而实现灯的亮灭。
我们需要了解51单片机的I/O口控制方式,并结合LED灯的连接方式进行设计。
4. 循环控制跑马灯程序的核心在于实现LED灯的依次轮流亮起。
这就需要我们设计循环控制的程序结构。
在汇编语言中,可以通过跳转指令和计数器来实现循环效果,我们需要考虑如何设计循环的次数和顺序。
5. 延时控制为了让人眼能够观察到LED灯的亮灭效果,我们需要在程序中添加延时控制。
这需要我们了解51单片机的定时器控制和时钟频率,并根据LED灯的亮度要求设计合适的延时程序。
6. 汇编设计思路在进行汇编设计时,可以按照以下步骤进行:1)设置I/O口控制LED灯的引脚,确定LED的连接方式;2)设计循环控制结构,确定LED灯的顺序和次数;3)添加延时程序,控制LED灯亮灭的时间间隔;4)编写中断程序,处理定时器中断等事件;5)调试程序,验证跑马灯效果是否符合要求。
7. 个人观点和理解通过设计这个跑马灯程序,我深切体会到了汇编语言的精妙之处。
通过对硬件的直接控制和对程序结构的精心设计,我感受到了嵌入式系统开发中的乐趣和挑战。
而对于初学者来说,设计跑马灯程序也是一个很好的学习过程,可以加深对于51单片机结构和编程思想的理解。
《单片机原理及应用》跑马灯

《单片机原理及应用》跑马灯设计说明书第一章设计任务此次单片机设计任务是要求:按下按键三之后,灯的上半部分(四个灯)和下半部分交替闪烁9次,按下按键四之后,灯光全亮全灭九次。
在执行跑马灯的代码时,按下按键四,执行全亮全灭的时候,再按下按键三,灯光会先执行按键三的指令,然后再执行按键四的指令,也就是说按键三比按键四的优先级高,这就是此次单片机的设计任务。
第二章硬件设计在参考之前的跑马灯模拟电路的基础上,进行改造,完成相关模拟电路的设计。
在此次硬件设计的过程中,又让我再次的熟悉了电路的组成,元件的位置以及名称和连接,还有单片机内的系统及其功能。
首先是晶振电路,单片机最小系统的三要素之一,它在不停的振荡,为单片机系统提供基准时钟信号,是单片机的“心脏”。
电容的作用是帮助晶振起振,并维持振荡信号的稳定。
其次,复位电路主要功能是完成单片机上电初始功能,同时保障在单片机程序出现跑飞时能让它恢复正常状态,其实就是一个RC电路,RC的取值根据所需的复位时间来计算。
为实现跑马灯等功能,在P1端口接上8个LED灯,同时在P3口连上四个按键,实现中断功能。
此次硬件设计中,我做的唯一不足的就是忘记修改元件的具体数据,下次必须注意。
第三章软件设计在此次软件设计中,我做的很差,存在有许多问题,中间的各个代码都出现了问题,通过此次的失败,我总结了经验,明白了中断设计的函数应该怎那么写,参考了一下往日的作业,基本弄清了这类代码应该怎么写,但是仍然不熟练,还是需要多加练习,多加思考,争取能够自己独立写出程序代码。
第四章调试过程调试失败,在改进之后的代码进入调试之后,还是成功了的。
第五章总结此次单片机设计测试中主要考察了中断系统的使用,同时在硬件的设计上也有了更多的要求,在编写代码的同时还需要自主的设计和铺设电路,此次代码编写需要考虑全面,容易缺少程序,需要细心编写。
同时,在编写代码的时候,容易出错,出错的时候不能够慌,应该细心下来思考问题所在,此次测试中,看出来了我自身写代码的经验不足,使得代码编写非常错误,还有就是平时训练的还是比较少,以后应该多加训练。
跑马灯单片机实训报告
一、前言随着科技的不断发展,单片机技术在各个领域得到了广泛的应用。
为了提高我们的实践能力,加强理论知识与实际操作的结合,我们进行了单片机跑马灯实训。
通过本次实训,我们深入了解了单片机的基本原理,掌握了单片机的编程方法,并能够运用所学知识解决实际问题。
二、实训目的1. 熟悉单片机的硬件结构和工作原理。
2. 掌握单片机的编程方法,包括汇编语言和C语言。
3. 学会使用单片机进行简单的外设控制。
4. 提高动手能力和团队合作能力。
三、实训内容1. 实训设备(1)8051单片机开发板(2)LED灯(3)电阻(4)电源2. 实训步骤(1)搭建电路首先,我们需要搭建跑马灯的电路。
将LED灯串联,然后连接到单片机的P1口。
在LED灯的正极和负极之间串联一个电阻,用于限流。
(2)编写程序接下来,我们需要编写跑马灯的程序。
以下是用C语言编写的跑马灯程序:```c#include <reg51.h>#define LED P1void delay(unsigned int ms) {unsigned int i, j;for (i = 0; i < ms; i++)for (j = 0; j < 1275; j++);}void main() {while (1) {LED = 0x01; // 第一个LED灯亮 delay(500); // 延时LED = 0x02; // 第二个LED灯亮 delay(500); // 延时LED = 0x04; // 第三个LED灯亮 delay(500); // 延时LED = 0x08; // 第四个LED灯亮 delay(500); // 延时LED = 0x10; // 第五个LED灯亮 delay(500); // 延时LED = 0x20; // 第六个LED灯亮 delay(500); // 延时LED = 0x40; // 第七个LED灯亮 delay(500); // 延时LED = 0x80; // 第八个LED灯亮 delay(500); // 延时LED = 0x00; // 所有LED灯熄灭delay(500); // 延时}}```(3)编译程序将编写的程序导入到单片机开发板中,并下载到单片机中。
51单片机8个跑马灯程序设计思路
51单片机8个跑马灯程序设计思路单片机是一种集成电路,内部包含了计算机的主要组件,如中央处理单元(CPU)、存储器等。
通过编程,可以实现各种不同的功能。
在这里,我将以设计一个8个跑马灯的程序为例,来讲解单片机程序的设计思路。
1.硬件准备首先,我们需要准备一个适用于单片机的开发板,例如STC89C52,以及8个LED灯。
将LED灯连接到开发板的GPIO引脚上,并通过电阻进行限流。
使用跳线将GPIO引脚与LED灯的正极连接。
2.程序结构设计在单片机程序中,我们通常会使用循环结构。
因此,在设计跑马灯程序时,我们可以使用一个无限循环,来实现LED灯的闪烁效果。
具体的程序结构如下所示:```c#include <reg52.h>sbit led0 = P0 ^ 0; //第1个LED灯sbit led1 = P0 ^ 1; //第2个LED灯sbit led2 = P0 ^ 2; //第3个LED灯//...sbit led7 = P0 ^ 7; //第8个LED灯void mainwhile (1)//跑马灯代码}}```在这段代码中,我们首先引入头文件`reg52.h`,它包含了STC89C52的寄存器定义和常用函数的声明。
然后,我们定义了8个宏,用于表示8个LED灯所连接的引脚号。
接下来,在`main(`函数中,我们使用一个无限循环`while(1)`,来实现LED灯的闪烁效果。
3.跑马灯实现思路在无限循环中,我们需要通过对GPIO的控制来实现8个LED灯的闪烁。
具体的实现思路如下:- 首先,我们可以定义一个变量`index`,用于表示当前亮起的LED灯的索引值。
初始时,`index`的值为0,表示第一个LED灯亮起。
- 然后,我们可以使用`switch...case`语句来判断当前的`index`值,从而控制不同的LED灯亮起。
- 在每次循环中,我们可以通过对`index`的递增来实现灯的滚动效果。
单片机 跑马灯实验精选全文
可编辑修改精选全文完整版实验一跑马灯实验一、实验内容1、基本的流水灯根据图1电路,编写一段程序,使8个发光二极管D1、D2、D3、D4、D5、D6、D7、D8顺序(正序)点亮:先点亮D1,再点亮D2、D3……D8、D1……,循环点亮。
每点亮一个LED,采用软件延时一段时间。
2、简单键控的流水灯不按键,按正序点亮流水灯;按下K1不松手,按倒序点亮流水灯,即先点亮D8,再顺序点亮D7、D6……D1、D8……。
松手后,又按正序点亮流水灯。
3、键控的流水灯上电,不点亮LED,按一下K1键,按正序点亮流水灯。
按一下K2键,按倒序点亮流水灯,按一下K3键,全部关闭LED。
二、实验方案1、总体方案设计考虑到K4键未被使用,所以将实验内容中的三项合并到一个主函数中:K4键代替实验内容第二项中的K1键;单片机一开机即执行实验内容第一项;K1、K2、K3键实现实验内容第三项。
所用硬件:AT89C52、BUTTON、LED-BLUE、电源输入:P2.0-K1;P2.1-K2;P2.2-K3;P2.3-K4。
低电平有效输出:P0.0~P0.7-D0~D7。
LED组连线采用共阳极,低电平有效软件设计:软件延时采用延时函数delay(t),可调整延迟时间:void delay(uint t){uint i;while(t--)for(i=0;i<1000;i++){if(P2!=oldK&&P2!=K[0])break;//按下了其他键退出循环}}由于涉及到按键变化所以要设置一个变量oldK保留按键键值,要在延时程序中检测是否按键,当按键后立即设置oldK的值。
按键判断采用在while循环中利用条件语句判断P2的值然后执行该键对应的代码段,达到相应的响应。
为了让K4键的效果优化,即状态变化从当前已亮灯开始顺序点亮或逆序点亮,利用全局变量n来记录灯号,利用算法即可实现。
主要算法:1、全局变量的定义:uchar D[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0X7f};//单个LED亮uchar AllOff=0xff;//LED全灭uchar AllOn=0x00;//LED全亮uchar K[]={0xff,0xfe,0xfd,0xfb,0xf7};//按键开关uchar oldK;//记录已按键int n;2、顺序、逆序点亮流水灯:void forward(){for(n=0;n<=7;n++){out=D[n];delay(15);if(P2!=oldK&&P2!=K[0])break;}out=AllOff;}void backward(){for(n=7;n>=0;n--){out=D[n];delay(15);if(P2!=oldK&&P2!=K[0])break;}out=AllOff;}3、实验内容第二项流水灯灯亮顺序变换:void hold(){n=8;while(1){if(P2==K[4]){//一直按着K4键,逆序点亮跑马灯oldK=K[4];if(n==-1)n=7; //D0灯亮后点亮D7while(n>=0){out=D[n];n--;if(delay4(15))break;}}if(P2==K[0]){//未按下K4键,一直正序点亮跑马灯oldK=K[0];if(n==8)n=0;//D7灯亮后点亮D0while(n<=7){out=D[n];n++;if(delay4(15))break;}}if(P2!=K[4]&&P2!=K[0]){//按下了其他键,退出hold函数break;}}}4、对应实验内容第一项,开机顺序点亮流水灯:while(1){//开机即正序点亮流水灯forward();if(P2!=K[0]){break;}}2、实验原理图图2-1 实验原理图3、程序流程图图2-2 程序流程图三、源程序#include"reg51.h"#define uchar unsigned char#define uint unsigned int#define out P0uchar D[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0X7f};//单个LED亮uchar AllOff=0xff;//LED全灭uchar AllOn=0x00;//LED全亮uchar K[]={0xff,0xfe,0xfd,0xfb,0xf7};//按键开关uchar oldK;//记录已按键int n;//记录当前亮的灯号void delay(uint t){uint i;while(t--)for(i=0;i<1000;i++){if(P2!=oldK&&P2!=K[0])break;//按下了其他键退出循环}}void delay10ms(){uint i;for(i=0;i<10000;i++);}void forward(){for(n=0;n<=7;n++){out=D[n];delay(15);if(P2!=oldK&&P2!=K[0])break;}out=AllOff;}void backward(){for(n=7;n>=0;n--){out=D[n];delay(15);if(P2!=oldK&&P2!=K[0])break;}out=AllOff;}int delay4(uint t){uint i;while(t--)for(i=0;i<1000;i++){if(P2!=oldK){ //按键变化退出循环return 1;}}return 0;}void hold(){n=8;while(1){if(P2==K[4]){//一直按着K4键,逆序点亮跑马灯oldK=K[4];if(n==-1)n=7; //D0灯亮后点亮D7while(n>=0){n--;if(delay4(15))break;}}if(P2==K[0]){//未按下K4键,一直正序点亮跑马灯oldK=K[0];if(n==8)n=0;//D7灯亮后点亮D0while(n<=7){out=D[n];n++;if(delay4(15))break;}}if(P2!=K[4]&&P2!=K[0]){//按下了其他键,退出hold函数break;}}}void main(){oldK=K[0];while(1){//开机即正序点亮流水灯forward();if(P2!=K[0]){break;}}while(1){out=AllOff;if((P2&0x0f)!=0x0f){//检测有键按下delay10ms();//延时10ms再去检测//P2.0_K1键按下正序点亮流水灯if(P2==K[1]){oldK=K[1];while(1){forward();if(P2!=K[1]&&P2!=K[0]){//按下了其他键,退出break;}}}//P2.1_K2键按下逆序点亮流水灯if(P2==K[2]){while(1){backward();if(P2!=K[2]&&P2!=K[0]){//按下了其他键,退出break;}}}//P2.2_K3键按下关闭全部LEDif(P2==K[3]){oldK=K[3];out=AllOff;}//P2.3_K4键按下长按逆序点亮流水灯,不按正序点亮流水灯,直到其他键按下停止if(P2==K[4]){hold();}}}}四、实验结果1、基本的流水灯:开机后即重复顺序点亮流水灯,等待其他按键。
如何用51单片机数码管实现跑马灯功能?
如何用51单片机数码管实现跑马灯功能?51单片机数码管显示跑马灯程序源代码讲解基于51单片机学习板。
用S1键作为控制跑马灯的方向按键,S5键作为控制跑马灯方向的加速度按键,S9键作为控制跑马灯方向的减速度按键,S13键作为控制跑马灯方向的启动或者暂停按键。
记得把输出线P0.4一直输出低电平,模拟独立按键的触发地GND。
(2)实现功能:跑马灯运行:第1个至第8个LED灯一直不亮。
在第9个至第16个LED灯,依次逐个亮灯并且每次只能亮一个灯。
每按一次独立按键S13键,原来运行的跑马灯会暂停,原来暂停的跑马灯会运行。
用S1来改变方向。
用S5和S9来改变速度,每按一次按键的递增或者递减以10为单位。
数码管显示:本程序只有1个窗口,这个窗口分成3个局部显示。
8,7,6位数码管显示运行状态,启动时显示“on”,停止时显示“oFF”。
5位数码管显示数码管方向,正向显示“n”,反向显示“U”。
4,3,2,1位数码管显示速度。
数值越大速度越慢,最慢的速度是550,最快的速度是50。
(3)源代码讲解如下:#include "REG52.H"#define const_voice_short 40 //蜂鸣器短叫的持续时间#define const_key_time1 20 //按键去抖动延时的时间#define const_key_time2 20 //按键去抖动延时的时间#define const_key_time3 20 //按键去抖动延时的时间#define const_key_time4 20 //按键去抖动延时的时间void initial_myself();void initial_peripheral();void delay_short(unsigned int uiDelayShort);void delay_long(unsigned int uiDelaylong);。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
中国地质大学江城学院《单片机原理及应用》课程设计学部班级学号姓名指导教师年月日目录第1章系统开发的基本原理 (3)1.1 复位电路及时钟电路 (3)1.2 跑马灯的基本原理 (4)1.3 数码管的基本原理 (5)1.4 键盘的基本原理 (5)第2章系统硬件设计 (6)2.1 MCS-51单片机介绍 (6)2.2 74HC573锁存器介绍 (7)2.3 74HC02或非门介绍 (7)2.4 4511译码器介绍 (8)2.5 数码管介绍 (9)2.6 系统硬件电路设计 (10)第3章系统软件设计 (12)3.1 软件设计架构 (12)3.2 主程序模块 (13)3.3 跑马灯程序模块 (18)3.4 键盘程序模块 (18)3.5 数码管程序模块 (19)第4章系统测试 (19)4.1 测试方法 (19)4.2 测试考虑的因素 (20)4.3 测试结论 (20)第5章课程设计小结 (20)摘要:单片机最小系统,无论对单片机初学人员还是开发人员都具有十分重要的意义,可以利用最小系统进行编程实现工业控制。
单片机最小系统电路板在单片机开发市场和大学生电子设计方面十分流行。
本次课程设计包括AT89S52单片机最小系统(包括复位和时钟电路)及供电系统、4×4矩阵键盘、独立4个8段LED数码管显示电路。
利用Protel电路设计软件进行原理图设计,PCB布线,借此巩固单片机应用、模拟电路、数字电路课程及学会工程软件protel的使用。
第1章系统开发的基本原理对51 系列单片机来说,最小系统一般应该包括:单片机、时钟电路、复位电路、输入/ 输出设备等。
本次课程设计的系统还包括流水灯、4*4矩阵键盘和二位数码管显示。
1.1 复位电路及时钟电路复位电路和时钟电路是维持单片机最小系统运行的基本模块。
复位电路通常分为两种:上电复位和手动复位。
[2]上电复位手动复位有时系统在运行过程中出现程序跑飞的情况,在程序开发过程中,经常需要手动复位。
所以本次设计选用手动复位。
高频率的时钟有利于程序更快的运行,也有可以实现更高的信号采样率,从而实现更多的功能。
但是告诉对系统要求较高,而且功耗大,运行环境苛刻。
考虑到单片机本身用在控制,并非高速信号采样处理,所以选取合适的频率即可。
合适频率的晶振对于选频信号强度准确度都有好处,本次设计选取12.000M无源晶振接入XTAL1和XTAL2引脚。
并联2个30pF陶瓷电容帮助起振。
跑马灯的就是讲发光二极管分时点亮,产生流水的效果。
51单片机第32—39引脚为P0口,分别对应P0.7—P0.0,P0口外接10K Ω的上拉排阻。
P0口的P0.0—P0.7与74HC573的D0—D7一一对应相连,74HC573的Q0—Q7为输出,分别经220Ω电阻后接于发光二极管(跑马灯)的D0—D7上。
74HC573为8位锁存器,其1脚为输出使能端OE,低电平有效。
本电路将其接地,所以74HC573的8位Q端为直通输出。
74HC573的第11引脚LE为输入使能端,高电平有效。
本电路中或非门的输出与其相连,而或非门的两个输入端分别连接于51机的WR和P2.7引脚上。
将P0口的数据写入,74HC573的输入条件是在写入的瞬间必须使P2.7端为低电平,写入有效时,WR也同时为低电平。
这就构成,74HC573(跑马灯)的写入地址为0X7FFF,此电路中的或非门在此时从低电平观点视为低与非门。
单片机键盘控制及键号显示电路的硬件设计键号的数码显示方式仍采用P0口输出给两片4511译码器。
DC4511为四位BCD码输入,译码后产生7段数码管显示信号驱动数码管进行键号显示。
当控制地址为0xBFFF时,(即P2状态为10111111),与WR配合,驱动74HC02至4511的第5脚LE端,打开4511的锁存器,键号的显示由P0口输出。
见图1-2。
P0口的P0.3,P0.2,P0.1,P0.0与4511-1的D、C、B、A相连,再经译码后驱动数码管Ⅰ,显示键号的个位。
而P0的P0.7,P0.6,P0.5,P0.4与4511-2的D、C、B、A相连,经译码后驱动数码管Ⅱ,显示键盘号的十位数。
1.4 键盘的基本原理矩阵键盘是在要求按键不多是的一种简易键盘设计。
与编码键盘相比,矩阵键盘不需要专门的编码芯片,从而成本低,设计简单,用简单的面包板即可搭成。
缺点是占用单片机端口较多,而且编程实现行扫描列扫描比较占用资源。
键盘的原理是在一端接入高电平,用单片机一个端口去检测按键另一端的电平,另一端也是高电平时,说明按键被按下。
4×4矩阵键盘,分为4行4列,在每列加上拉电阻(加高电平),然后用程序控制行扫描和列扫描,判断具体哪个按键被按下。
由于本身键盘的特点,再设计程序是需要加入消除抖动处理。
51单片机的P1口控制键盘,其中P1.0,P1.1,P1.2,P1.3为列线,P1.4,P1.5,P1.6,P1.7为行线。
四根行线各接1只5.1K电阻,再与电源VCC(+5V)相连。
本次课程设计没有加中断,因而用扫描的方法写程序。
第2章系统硬件设计2.1 MCS-51单片机介绍AT89S52 8位单片机是MSC-51®系列产品的升级版,有世界著名半导体公司ATMEL在购买MSC-51®设计结构后,利用自身优势技术——(掉电不丢数据)闪存生产技术对旧技术进行改进和扩展,同时使用新的半导体生产工艺,最终得到成型产品。
与此同时,世界上其他的著名公司也通过基本的51内核,结合公司自身技术进行改进生产,推广一批如51F020等高性能单片机。
AT89S52片内集成256字节程序运行空间、8K字节Flash存储空间,支持最大64K外部存储扩展。
根据不同的运行速度和功耗的要求,时钟频率可以设置在0-33M之间。
片内资源有4组I/O控制端口、3个定时器、8个中断、软件设置低能耗模式、看门狗和断电保护。
可以在4V到5.5V宽电压范围内正常工作。
不断发展的半导体工艺也让该单片机的功耗不断降低。
同时,该单片机支持计算机并口下载,简单的数字芯片就可以制成下载线,仅仅几块钱的价格让该型号单片机畅销10年不衰。
根据不同场合的要求,这款单片机提供了多种封装,本次设计根据最小系统有时需要更换单片机的具体情况,使用双列直插DIP-40的封装。
DIP-40封装89S52引脚图2.2 74HC573锁存器介绍74HC573是八进制3 态非反转透明锁存器,器件的输入是和标准CMOS 输出兼容的;加上拉电阻,他们能和LS/ALSTTL 输出兼容。
当锁存使能端为高时,这些器件的锁存对于数据是透明的(也就是说输出同步)。
当锁存使能变低时,符合建立时间和保持时间的数据会被锁存。
74HC573引脚图 74HC573内部结构2.3 74HC02或非门介绍74HC02是四2输入或非门。
1A-4A 输入端,1B-4B 输入端,1Y-4Y 输出端。
2.4 4511译码器介绍CD4511是一个用于驱动共阴极LED (数码管)显示器的BCD 码—七段码译码器,特点:具有BCD转换、消隐和锁存控制、七段译码及驱动功能的CMOS电路能提供较大的拉电流。
可直接驱动LED显示器。
CD4511 是一片CMOS BCD—锁存/7 段译码/驱动器,引脚排列如图2 所示。
其中a b c d 为BCD 码输入,a为最低位。
LT为灯测试端,加高电平时,显示器正常显示,加低电平时,显示器一直显示数码“8”,各笔段都被点亮,以检查显示器是否有故障。
BI为消隐功能端,低电平时使所有笔段均消隐,正常显示时,B1端应加高电平。
另外CD4511有拒绝伪码的特点,当输入数据越过十进制数9(1001)时,显示字形也自行消隐。
LE是锁存控制端,高电平时锁存,低电平时传输数据。
a~g是7 段输出,可驱动共阴LED数码管。
另外,CD4511显示数“6”时,a段消隐;显示数“9”时,d段消隐,所以显示6、9这两个数时,字形不太美观图3是CD4511和CD4518配合而成一位计数显示电路,若要多位计数,只需将计数器级联,每级输出接一只CD4511 和LED 数码管即可。
所谓共阴LED 数码管是指7 段LED 的阴极是连在一起的,在应用中应接地。
CD4511 引脚图其功能介绍如下:BI:4脚是消隐输入控制端,当BI=0 时,不管其它输入端状态如何,七段数码管均处于熄灭(消隐)状态,不显示数字。
LT:3脚是测试输入端,当BI=1,LT=0 时,译码输出全为1,不管输入DCBA 状态如何,七段均发亮,显示“8”。
它主要用来检测数码管是否损坏。
LE:锁定控制端,当LE=0时,允许译码输出。
LE=1时译码器是锁定保持状态,译码器输出被保持在LE=0时的数值。
A1、A2、A3、A4、为8421BCD码输入端。
a、b、c、d、e、f、g:为译码输出端,输出为高电平1有效。
CD4511的工作真值表2.5 数码管介绍LED数码管显示是利用半导体发光制成条形的发光二极管,封装在一起组成数字或其他符号形状。
数码管根据公共端不同,分为共阴极和共阳极两种形式。
共阴极数码管共阳极数码管根据设计需要,本次选用共阴极数码管。
键号的数码显示方式仍采用P1口输出给两片4511译码器,如图1-4。
DC4511为四位BCD码输入,译码后产生7段数码管显示信号驱动数码管进行键号显示。
数码管引脚图2.6 系统硬件电路设计第3章系统软件设计3.1 软件设计架构本次系统的主要是用扫描的方法检测按键值,不同按键值设置不同的功能。
1号键——流水灯;2-13号键——直流电机手动调速;14号键——步进电机正转;15号键——步进电机反转;16号键——直流电机自动调速。
3.2 主程序模块#include <reg52.h>#include<intrins.h>#include <absacc.h>#define SEG_ADDR XBYTE[0xbfff] //数码管地址#define LED_ADDR XBYTE[0x7fff] //跑马灯地址#define DAC_ADDR XBYTE[0xdfff] //直流电机地址#define STEP_ADDR XBYTE[0xefff] //步进电机地址#define uchar unsigned chartypedef unsigned int uint16;typedef unsigned long uint32;typedef char int8;typedef int int16;typedef long int32;sbit KeyIn1 = P1^0; //矩阵键盘地址定义sbit KeyIn2 = P1^1;sbit KeyIn3 = P1^2;sbit KeyIn4 = P1^3;sbit KeyOut1 = P1^4;sbit KeyOut2 = P1^5;sbit KeyOut3 = P1^6;sbit KeyOut4 = P1^7;uchar code Pattern_P0[]={0xfc,0xf9,0xf3,0xe7,0xcf,0x9f,0x3f,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff ,0xe7,0xdb,0xbd,0x7e,0xbd,0xdb,0xe7,0xff,0xe7,0xc3,0x81,0x00,0x81,0xc3,0xe7,0xff ,0xaa,0x55,0x18,0xff,0xf0,0x0f,0x00,0xff,0xf8,0xf1,0xe3,0xc7,0x8f,0x1f,0x3f,0x7f ,0x7f,0x3f,0x1f,0x8f,0xc7,0xe3,0xf1,0xf8,0xff,0x00,0x00,0xff,0xff,0x0f,0xf0,0xff ,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; //流水灯函数定义uchar code bujingZ[]={0x01,0x02,0x04,0x08}; //步进电机正转函数uchar code bujingF[]={0x03,0x09,0x0c,0x06}; //步进电机反转函数void delay(uint16 t){uint16 k;while(t--){for(k=0; k<123; k++){ }}}/********************************************************/ /*/*步进电机正转/*/********************************************************/ void motor_ffw(uint16 n){uchar i;uint16 j;for (j=0; j<5*n; j++) //转n圈{for (i=0; i<4; i++) //一个周期转72度{STEP_ADDR = bujingZ[i]; //取数据delay(100); //调节转速}}}/********************************************************/ /*/*步进电机反转/*/********************************************************/ void motor_rev(uint16 n){uchar i;uint16 j;for (j=0; j<5*n; j++) //转n圈{for (i=0; i<4; i++) //一个周期转72度{STEP_ADDR = bujingF[i]; //取数据delay(100); //调节转速}}}void delay0(void){uint16 i=1000;while (i--);}void DelayMS(uint16 x){uchar i;while(x--){for(i=0;i<120;i++);}}main(){uint16 i;DAC_ADDR = 0x7f; //直流电机初始化定义while (1){KeyOut1 = 0; //扫描第一行KeyOut2 = 1;KeyOut3 = 1;KeyOut4 = 1;if(KeyIn1 == 0) //按键1按下{delay0(); //按键消抖if(KeyIn1 == 0)SEG_ADDR = 0x00; //数码管显示00DAC_ADDR = 0x7f; //直流电机停止转动for(i=0;i<80;i++) //流水灯开始运行{LED_ADDR =~Pattern_P0[i];DelayMS(150);}}if(KeyIn2 == 0) //按键2按下{delay0(); //按键消抖if(KeyIn2 == 0)SEG_ADDR = 0x10; //数码管显示01DAC_ADDR = 0x00; //直流电机转动}if(KeyIn3 == 0) //按键3按下{delay0(); //按键消抖if(KeyIn3 == 0)SEG_ADDR = 0x20; //数码管显示02DAC_ADDR =25; //直流电机转动}if(KeyIn4 == 0) //按键4按下{delay0(); //按键消抖if(KeyIn4 == 0)SEG_ADDR = 0x30; //数码管显示03DAC_ADDR = 50; //直流电机转动}while((KeyIn1 == 0)||(KeyIn2 == 0)||(KeyIn3 == 0)||(KeyIn4 == 0)); KeyOut1 = 1;KeyOut2 = 0; //扫描第二行KeyOut3 = 1;KeyOut4 = 1;if(KeyIn1 == 0) //按键5按下{delay0(); //按键消抖if(KeyIn1 == 0)SEG_ADDR = 0x40; //数码管显示04DAC_ADDR = 75; //直流电机转动}if(KeyIn2 == 0) //按键6按下{delay0(); //按键消抖if(KeyIn2 == 0)SEG_ADDR = 0x50; //数码管显示05 DAC_ADDR = 100; //直流电机转动}if(KeyIn3 == 0) //按键7按下{delay0(); //按键消抖if(KeyIn3 == 0)SEG_ADDR = 0x60; //数码管显示06DAC_ADDR = 125; //直流电机转动}if(KeyIn4 == 0) //按键8按下{delay0(); //按键消抖if(KeyIn4 == 0)SEG_ADDR = 0x70; //数码管显示07DAC_ADDR = 150; //直流电机转动}while((KeyIn1 == 0)||(KeyIn2 == 0)||(KeyIn3 == 0)||(KeyIn4 == 0)); KeyOut1 = 1;KeyOut2 = 1;KeyOut3 = 0; //扫描第三行KeyOut4 = 1;if(KeyIn1 == 0) //按键9按下{delay0(); //按键消抖if(KeyIn1 == 0)SEG_ADDR = 0x80; //数码管显示08DAC_ADDR = 175; //直流电机转动}if(KeyIn2 == 0) //按键10按下{delay0(); //按键消抖if(KeyIn2 == 0)SEG_ADDR = 0x90; //数码管显示09DAC_ADDR = 200; //直流电机转动}if(KeyIn3 == 0) //按键11按下{delay0(); //按键消抖if(KeyIn3 == 0)SEG_ADDR = 0x01; //数码管显示10DAC_ADDR = 225; //直流电机转动}if(KeyIn4 == 0) //按键12按下{delay0(); //按键消抖if(KeyIn4 == 0)SEG_ADDR = 0x11; //数码管显示11DAC_ADDR = 240; //直流电机转动}while((KeyIn1 == 0)||(KeyIn2 == 0)||(KeyIn3 == 0)||(KeyIn4 == 0)); KeyOut1 = 1;KeyOut2 = 1;KeyOut3 = 1;KeyOut4 = 0; //扫描第四行if(KeyIn1 == 0) //按键13按下{delay0(); //按键消抖if(KeyIn1 == 0)SEG_ADDR = 0x21; //数码管显示12DAC_ADDR = 255; //直流电机转动}if(KeyIn2 == 0) //按键14按下{delay0(); //按键消抖if(KeyIn2 == 0)SEG_ADDR = 0x31; //数码管显示13motor_ffw(5); //步进电机正转}if(KeyIn3 == 0) //按键15按下{delay0(); //按键消抖if(KeyIn3 == 0)SEG_ADDR = 0x41; //数码管显示14motor_rev(5); //步进电机反转}if(KeyIn4 == 0) //按键16按下{delay0(); //按键消抖if(KeyIn4 == 0)SEG_ADDR = 0x51; //数码管显示15for(i=0;i<255;i++) //直流电机自动调速{DAC_ADDR = i;DelayMS(150);}}while((KeyIn1 == 0)||(KeyIn2 == 0)||(KeyIn3 == 0)||(KeyIn4 == 0));}}3.3 跑马灯程序模块见3.2主程序模块。