找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5079|回复: 0
打印 上一主题 下一主题
收起左侧

单片机发光二极管及数码管的编程控制实验 带程序

[复制链接]
跳转到指定楼层
楼主
ID:561485 发表于 2019-6-13 09:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1.1设计目的

(1)加强对单片机和C语言的认识,充分掌握和理解设计各部分

的工作原理、设计过程、选择芯片器件、模块化编程等多项知识。

(2)用单片机模拟实现具体应用,使个人设计能够真正使用。

(3)把理论知识与实践相结合,充分发挥个人能力,并在实践中锻炼。

(4)提高利用已学知识分析和解决问题的能力。

(5)提高实践动手能力。

1.2控制要求

(1)用七只发光二极模拟工业控制中的7道工序,高电平点亮,每道工序用定时器进行工序间的顺序转换。

(2)与此同时运用动态扫描和定时器1在数码管上显示出从765432开始以1/10秒的速度递减至765398,并保持显示此数。

1.3系统总体方案设计


设计主要流程:



图1-1 课程设计总流



2.控制系统原理分析

2.1硬件部分分析
2.1.1 89C51单片机引脚图及引脚功能介绍

本次实习的中断功能就是基于89C51单片机的基础上实现的,首先来简单认识一下,它的引脚如图2-1所示:

图2-1 89C51引脚示意图


2.1.2显示系统工作原理

LED显示电路:

           

                           图2-2 LCD显示电路

LCD显示电路,由U33的74HC245驱动,以显示电平状态。高电平为“1”状态,点亮发光二极管。对于74HC245,实物图如下

图2-3 74HC24实物图

                        图2-4 74LS245结构图

引脚定义:

第1脚DIR,为输入输出端口转换用,DIR=“1”高电平时信号由“A”端输入“B”端输出,DIR=“0”低电平时信号由“B”端输入“A”端输出。

第2~9脚“A”信号输入输出端,A0=B0,A7=B7,A0与B0是一组,如果DIR=“1”OE=“0”则A1输入B1输出,其它类同。如果DIR=“0”OE=“0”则B1输入A1输出,其它类同。

第11~18脚“B”信号输入输出端,功能与“A”端一样,不再描述。

第19脚OE,若该脚为“1”A/B端的信号将不导通,只有为“0”时A/B端才被启用,该脚也就是起到开关的作用。

第10脚GND,电源地。

第20脚VCC,电源正极。

      

                            图2-5 显示电路结构图

八段数码管显示电路由8155的PB0、PB1经74LS164“串转并”后输出得到。6位位码由8155 的PA0口输出,经uA2003反向驱动后,选择相应显示位。74LS164是串行输入并行输出转换电路,串行输入的数据位由8155的PB0控制,时钟位由8155的PB1控制输出。

写程序时,只要向数据位地址输出数据,然后向时钟位地址输出一高一低两个电平就可以将数据位置到74LS164中,并且实现移位。向显示位选通地址输出高电平就可以点亮相应的显示位。

  

                    图2-6 74LS164引脚结构图

  引脚信息:            

符号

引脚

说明

DSA

1

数据输入

DSB

2

数据输入

Q0~Q3

3~6

输出

GND

7

地 (0 V)

CP

8

时钟输入(低电平到高电平边沿触发)

/M/R

9

中央复位输入(低电平有效)

Q4~Q7

10~13

输出

VCC

14

正电源


功能概述:

74LS164是8位边沿触发式移位寄存器,串行输入数据,然后并行输出。数据通过两个输入端(DSA 或 DSB)之一串行输入;任一输入端可以用作高电平使能端,控制另一输入端的数据输入。两个输入端或者连接在一起,或者把不用的输入端接高电平,一定不要悬空。时钟 (CP)每次由低变高时,数据右移一位,输入到 Q0, Q0 是两个数据输入端(DSA和 DSB)的逻辑与,它将上升时钟沿之前保持一个建立时间的长度。主复位 (MR) 输入端上的一个低电平将使其它所有输入端都无效,非同步地清除寄存器,强制所有的输出为低电平。

字段码:

        

图2-7 数码管数字代码表


2.2软件设计流程图
                         图2-8 设计流程图

    P1口的P1.0~P1.6接七只发光二极管,P1.7接报警器,P3.4接开工启动开关,P3.2接外部故障输入模拟开关。

   主程序流程图:当程序启动,开启中断,并使P1、P3口初始化,当给start开始信号即P3.4得电时,运行主程序中使发光二极管得电的程序,从L0至L7,按顺序每次只点亮一只二极管,并延时一段时间,然后点亮下一只二极管,当第七只二极管得电延时完成后,程序跳转到工序1开始的地方,按此规律从工序1到工序7依次循环进行下去。

   中断服务子程序:当外部故障输入模拟开关即P3.3得电时,运行中断子程序,先使P1=0x00即关闭输出保护现场,speak=1使报警器报警。然后判断故障情况,如果故障清除,则恢复现场跳出中断子程序回到主程序;如果故障没有清除,则报警器继续报警直至故障清除。


3.程序分析
3.1顺序控制程序

#include "reg51.h"

#define WORD unsigned int

#define BYTE unsigned char

sbit Speak=P1^7;          P1.7对应报警开关,用P1.7对应的得电信号来改变是否故障

sbit Start              =              P3^4;         定义P3口的P3.4为启动开关

sbit test              =              P1^0;        /*定义变量,报警P1.7;启动P3.4;外部故障开关P3.3*/

void delay(WORD time)

{

              WORD i;

              for(i=0;i<=time;i++);

}                          /*延时中断程序*/

void ErroBl (void) interrupt 2 using 1

{

        P1=0X00;                           

                            {

                                          Speak=1;

                                          delay(200);

                                          Speak=0;

                                          delay(100);

                            }

}                         /*外部故障中断报警程序,循环报警*/

void main()              主函数

{

              IE=0x84;

              IP=0x04;

    PSW=0x00;            /*辅助继电器赋值,允许外部中断;优先级别最高*/

              while(1)             循环

        {

        if(Start==1)         /*启动信号*/

              {        P1=0X01;     /*工序一*/给P1口赋值为00000001,即工序1对应的灯得电,灯亮。

           delay(6000); /*工序一延时*/采用延时程序,是得电信号延时,即灯亮延时6000后灭。

               其他灯的亮灭只是对赋值进行更改,来达到让7个灯互相交替亮灭。

程序分析说明:

    P3.4为开工启动开关,高电平启动。在主程序中P1 = 0xff表示高电平有效启动;IT0 = 0;表示Enable EX0,外部中断INT0低电平有效;EX0 = 1;表示中断标志位为1时,允许INT0中断;EA = 1;表示中断总控制开关,为1时CPU允许中断;在while语句中,P1 = 0xfe;表示从右第一个灯亮;Delay(1000);表示延时1S;往后以此类推。但是在Delay(1000);表示进入延时函数调用。其中while (cnt-- !=0)表示从1000往下减1。

3.2数码管显示程序

显示设计程序是在八段数码显示设计程序的基础上加以修改得到的。按要求高三位是固定不变的,只需要变化低三位。在低三位递减到指定数据时,保持固定不变。



  1. <font style="font-size: 12pt">#include<absacc.h>
  2. #define LEDLen 6
  3. #define mode 0x03;
  4. #define CAddr XBYTE[0xe100]/* 控制字地址 */
  5. #define OUTBIT XBYTE[0xe101]/*  位控制口 */
  6. #define CLK164 XBYTE[0xe102]/* 段控制口(接164时钟位) */
  7. #define DAT164 XBYTE[0xe102] /* 段控制口(接164数据位) */
  8. #define IN     XBYTE[0xe103] /* 键盘读入口 */
  9. unsigned char LEDBuf[LEDLen];  /* 显示缓冲 */
  10. code unsigned char LEDMAP[] = {  /* 八段管显示码 */
  11.   0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
  12.   0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71
  13. };

  14. void Delay(unsigned char CNT)  /*延时中断程序*/
  15. {
  16.   unsigned char i;
  17.   while (CNT-- !=0)
  18.     for (i=100; i !=0; i--);
  19. }
  20. 如何保证最后停在7654398,在前面建立一个无限循环程序,当满足一定条件是跳入该程序就能保证显示数码管把持不变,下面是该程序。
  21. void display()       /*按要求最后显示765398,并用无限循环保持不变*/
  22. {   
  23.               while(1) {
  24.                 unsigned char j;
  25.               LEDBuf[0] = LEDMAP[(7) & 0x0f];   /*六个八段数码管依次赋值*/
  26.      LEDBuf[1] = LEDMAP[(6) & 0x0f];
  27.      LEDBuf[2] = LEDMAP[(5) & 0x0f];
  28.      LEDBuf[3] = LEDMAP[(3) & 0x0f];
  29.               LEDBuf[4] = LEDMAP[(9) & 0x0f];
  30.               LEDBuf[5] = LEDMAP[(8) & 0x0f];
  31.                               for(j=0; j<30; j++)   /*延时*/        
  32.                  DisplayLED();         /*显示上面赋值数据*/
  33.                               }
  34. }
  35. 如何让数码管由765432逐渐递减到7654398,下面是主函数的编写,循环的编写,来满足要求。
  36. void main()                   主函数
  37. {
  38.    unsigned char i=2;
  39.    unsigned char m;
  40.    unsigned char j;
  41.    unsigned char n=3;
  42.    unsigned char k=4;        /*定义变量*/
  43.       CAddr = mode;
  44.    while(1) {
  45.      LEDBuf[0] = LEDMAP[(m+7) & 0x0f];     /*八段数码管依次赋值*/
  46.      LEDBuf[1] = LEDMAP[(m+6) & 0x0f];
  47.      LEDBuf[2] = LEDMAP[(m+5) & 0x0f];
  48.      LEDBuf[3] = LEDMAP[(k) & 0x0f];  
  49.      i--;                                   /*个位逐渐减1*/
  50. LEDBuf[4] = LEDMAP[(n) & 0x0f];       /*十位八段数码管赋值*/
  51.               if(i==0)                         /*当个位减小为0时,十位减1。同时给个{                                       位赋值9*/
  52.               n--;
  53.               i=9;
  54.               }
  55.               LEDBuf[5] = LEDMAP[(i) & 0x0f];
  56.               if(n==0&&i==1) {                 /*当十位个位同时减小到0时,百位减1;
  57.     k--;                               同时给个位和十位赋值9*/
  58.               i=9;
  59.               n=9;
  60.               }                                         
  61.     for(j=0; j<30; j++)
  62.                  DisplayLED();      /* 显示该次循环所得数据 */
  63.      if(k==3&&i==8)   /*当减小到765398时,进去子程序display无限循环显示   
  64.      display();                    765398*/
  65.    }
  66. }</font>
复制代码


4.运行调试
4.1软件调试过程

    点开软件,进入程序编译系统。点击菜单栏“项目”,选择下拉框里面的“新项目”。如下图4-1所示。                        




图 4-1 新建项目

   新建项目是要选择“Atmel”下拉框中的“AT89C51”然后点击确定。如下图

                           图4-2 目标选择设备

    新建项目之后,需要点击“新建一个文件”在项目目录下新建程序编译文件。

之后点击保存,需要注意的是保存时文档名称后面要加“.c”。如下图。                              

   



图4-3 新建程序编译文件

文件建好之后,就可以开始编写程序了。编写程序时注意减少不必要的编写错误,注意语句后面的分号是否需要;每个程序段的前大括号和后大括号相对应。这样在编译过程中能减少很多工作。

添加文件到组,编写程序完成后。右键单击源代码组1。选择添加文件到组“源代码组1”,出现如图所示对话框,选择刚建立的编译程序文件到源代码组1,完成添加。


图 4-4 编译重建目标文

编写完程序添加到组之后开始调试,首先检查程序是否有错误,单击“编译当前文件”,如果输出窗口中显示没有错误,那么接着单击“重建所有目标文件”;如果编译过程中出现错误,那么需要按照输出窗口中提示的错误改正之后再重建文件。



图 4-5 设置调试接口

重建目标文件之后需要先设置好通讯借口,计算机需要与硬件设备向通讯,需要设置合理的通讯方式。本调试中使用(U):Keil Monitor-51 driver,保护接口选择Com3,波特率选用38400,其他默认。



通讯方式选择后启动调试,单击菜单栏中“启动/停止调试(D)”开始调试。然后可选择运行到指定位置来检验程序是否能正常运行。一直检查无误后,可直接点击“运行”观察实验现象。

4.2安装调试及方法

(1)P3.4连K1,P3.3连K2,P1.0—P1.6分别连到L1—L7,P1.7连SIN(电子音响输入端)。

(2)K1开关拨在上面,K2拨在上面。

(3)用连续方式从起始地址0580H开始运行程序(输入0580后按EXEC键),此时应在等待开工状态。

(4)K1拨至下面(显低电平),各道工序应正常运行。

(5)K2拨至下面(低电平),应有声音报警(人为设置故障)。

(6)K2拨至上面(高电平),即排除故障,程序应从刚才报警的那道工序继续执行。


4.3 结果分析

实验中延时的时间的计算为DELAY1t=20*125*200*12*2/12000000=1S; 分别代表的含义为:20、125、200是循环的次数相乘,12代表一个指令周期为12个机器周期,2代表该指令周期为双指令周期,12000000表示晶振的频率,也是机器周期。

在实验中可以观察到VL1~VL7依次按照1~7秒间隔循环亮起。在故障出现时能够保护现场,待故障消除后从现场又开始循环。

数码管上显示出从765432开始以1/10秒的速度递减至765398,并保持显示此数。


5.总结

通过本设计,我们大家对单片机的工作原理以及运用要求有了更进一步的了解,对我们的动手能力,编程能力都有很大的帮助。这次课程设计的控制要求有两个,一个是用七只发光二极管模拟工业控制中的7道工序,高电平点亮,每道工序用定时器进行工序间的顺序转换。另一个是在第一个的基础上运用动态扫描和定时器1在数码管上显示出从765432开始以1/10秒的速度递减至765398,并保持显示此数。我们首先收集了大量的资料,查找有关集成芯片和器件的文献,只有对各种元器件有了充分的了解之后我们在实际的操作才会更快。

在完成第一个发光二极管的控制要求时,程序全部正确在走,硬件连接也全部正确,但是灯却一直是全亮的,搞不懂怎么回事。把老师请来了才知道,是我们设置的灯的闪光时间太短,就是说灯是按照要求在点亮,但是由于点亮的速度太快,肉眼分辨不出它是否熄灭过,看起来就像一直在亮。可见如果不对整个设计的每一个细节都了解的清清楚楚的话,哪怕你做对了,你都搞不懂这是怎么回事。这告诉我们,以后无论在工作还是在生活中,都要认真对待每一个细节,不能得过且过,不求甚解。

在编程方面一直是我的弱项,好多程序我都搞不明白,这个时候我都会尽量去问同学,在课程设计的过程中,同学之间的相互帮助是相当重要的,有时自己的一个坎半天都过不去,但是说不定同学的一个点拨,我们就通了。所以,我们要学会团结协作,这样,才会事半功倍。这次的设计教会我们的不止是专业知识,在生活道理上也教会了很多,让我们终生受益。


完整的Word格式文档51黑下载地址:
单片机原理及应用设计报告设计格式评分标准装订首页.docx (504.83 KB, 下载次数: 6)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表