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数码管显示程序 显示设计程序是在八段数码显示设计程序的基础上加以修改得到的。按要求高三位是固定不变的,只需要变化低三位。在低三位递减到指定数据时,保持固定不变。
- <font style="font-size: 12pt">#include<absacc.h>
- #define LEDLen 6
- #define mode 0x03;
- #define CAddr XBYTE[0xe100]/* 控制字地址 */
- #define OUTBIT XBYTE[0xe101]/* 位控制口 */
- #define CLK164 XBYTE[0xe102]/* 段控制口(接164时钟位) */
- #define DAT164 XBYTE[0xe102] /* 段控制口(接164数据位) */
- #define IN XBYTE[0xe103] /* 键盘读入口 */
- unsigned char LEDBuf[LEDLen]; /* 显示缓冲 */
- code unsigned char LEDMAP[] = { /* 八段管显示码 */
- 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
- 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71
- };
-
- void Delay(unsigned char CNT) /*延时中断程序*/
- {
- unsigned char i;
- while (CNT-- !=0)
- for (i=100; i !=0; i--);
- }
- 如何保证最后停在7654398,在前面建立一个无限循环程序,当满足一定条件是跳入该程序就能保证显示数码管把持不变,下面是该程序。
- void display() /*按要求最后显示765398,并用无限循环保持不变*/
- {
- while(1) {
- unsigned char j;
- LEDBuf[0] = LEDMAP[(7) & 0x0f]; /*六个八段数码管依次赋值*/
- LEDBuf[1] = LEDMAP[(6) & 0x0f];
- LEDBuf[2] = LEDMAP[(5) & 0x0f];
- LEDBuf[3] = LEDMAP[(3) & 0x0f];
- LEDBuf[4] = LEDMAP[(9) & 0x0f];
- LEDBuf[5] = LEDMAP[(8) & 0x0f];
- for(j=0; j<30; j++) /*延时*/
- DisplayLED(); /*显示上面赋值数据*/
- }
- }
- 如何让数码管由765432逐渐递减到7654398,下面是主函数的编写,循环的编写,来满足要求。
- void main() 主函数
- {
- unsigned char i=2;
- unsigned char m;
- unsigned char j;
- unsigned char n=3;
- unsigned char k=4; /*定义变量*/
- CAddr = mode;
- while(1) {
- LEDBuf[0] = LEDMAP[(m+7) & 0x0f]; /*八段数码管依次赋值*/
- LEDBuf[1] = LEDMAP[(m+6) & 0x0f];
- LEDBuf[2] = LEDMAP[(m+5) & 0x0f];
- LEDBuf[3] = LEDMAP[(k) & 0x0f];
- i--; /*个位逐渐减1*/
- LEDBuf[4] = LEDMAP[(n) & 0x0f]; /*十位八段数码管赋值*/
- if(i==0) /*当个位减小为0时,十位减1。同时给个{ 位赋值9*/
- n--;
- i=9;
- }
- LEDBuf[5] = LEDMAP[(i) & 0x0f];
- if(n==0&&i==1) { /*当十位个位同时减小到0时,百位减1;
- k--; 同时给个位和十位赋值9*/
- i=9;
- n=9;
- }
- for(j=0; j<30; j++)
- DisplayLED(); /* 显示该次循环所得数据 */
- if(k==3&&i==8) /*当减小到765398时,进去子程序display无限循环显示
- display(); 765398*/
- }
- }</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)
|