电梯运行模拟控制器_第1页
电梯运行模拟控制器_第2页
电梯运行模拟控制器_第3页
电梯运行模拟控制器_第4页
电梯运行模拟控制器_第5页
已阅读5页,还剩21页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、目录1.课程设计简介11.1简介11.2设计总电路图21.3实物图22.设计题目23.总体设计33.1电梯运行模拟控制器的总体运作流程33.2电梯运行模拟控制器各模块关系34.详细设计46.1基本的IO配置(输入/输出模式)4输出模式配置4输入模式配置46.2外部中断配置5定时器中断5外部按键输入中断56.3电梯运行逻辑设计(软件编码)6数据结构设计6功能接口设计65.体会与总结76.附录7源代码7参考文献211. 课程设计简介1.1 简介本设计使用STM8S系列作为主控芯片,使用矩阵键盘、若干个LED和两位数码管作为外设。其中矩阵键盘用来模拟电梯按键,若干个LED灯用来模拟电梯的运动方向、楼

2、层的指示灯(电梯内部楼层对应的按钮),两位的数码管用于显示电梯目前所处楼层。1.2 设计总电路图(基于AD这个平台生成的PCB图与原理图)原理图原理图PCB图PCB图1.3 实物图实物图2. 设计题目设计一个电梯运行模拟控制器,其系统框图如下图所示:MCU1位七段数码管,3个LED灯(显示当前电梯所处楼层与运行方向以及电梯门的状态)键盘以及对应的LED灯(18,开门,关门)每个数字按键对应一个LED灯,按下按键灯亮,执行完命令灯灭)8个LED灯显示电梯所处楼层2个灯显示当前电梯运行方向8×2214个按键表示每层楼入口的电梯按键电梯运行模拟控制器框图功能要求:能够模拟控制一个8层楼梯的

3、电梯的运行。具体要求如下:1.电梯平时没有接到命令时候或者执行完命令后停在1楼,门关闭.。2.电梯运行速度2秒一层楼3.电梯门在开启的情况下没有收到命令10秒中后自动关闭。在运动中门必须关闭,(最后3秒可以设置音响警告信号)4.一句话,电梯控制器满足实际电梯的运行要求,电梯在运行的时候可以最多记住8个命令。并且综合考虑公平性(先按键先执行)和有效性(完成任务的总的行走路径最短)来执行。要求完成的内容:1.完成硬件电路的设计与安装调试(可借助单片机实验电路板),并用CAD软件画出原理电路图。2.画出流程图,编写并调试驱动程序。3.撰写设计报告。3. 总体设计233.1 电梯运行模拟控制器的总体运

4、作流程电梯运行模拟控制器整体运作流程3.2 电梯运行模拟控制器各模块关系电梯运行模拟控制器各模块关系图4. 详细设计4566.1 基本的IO配置(输入/输出模式)输出模式配置对于输出模式IO的配置,用到的外设(LED灯,数码管,矩阵键盘),在代码中都有对它们进行对应的配置。其中将LED的对应的IO口配置成推挽输出模式。当然数码管也是相同的配置方式,所以不做赘述。输出模式的引脚的配置输入模式配置对于IO口为输入模式的配置,将矩阵键盘设为输入模式,等待外部去触发。输入模式的引脚的配置6.2 外部中断配置定时器中断此设计使用了定时器中断用于每2s产生一个中断信号,这个信号的作用是让主控芯片知道当前(

5、正在运动的)电梯的所处楼层发生了变化(向上运动了一层或是向下运动了一层)。定时器中断配置外部按键输入中断此设计使用外部按键输入中断,用来及时检测电梯内部、外部的楼层按钮被按下的情况,每当有按钮被按下就产生信号使主控芯片进行相应的逻辑处理。外部按键输入中断(部分)6.3 电梯运行逻辑设计(软件编码)数据结构设计在电梯运行期间,电梯的运行方向、电梯当前所处楼层、电梯内部的哪几个对应的按钮被按下需要被存储下来。以及当外部有按钮被按下时,需要记录当前被按下的按钮编号所以设计了以下的数据结构。数据结构设计功能接口设计为了让模拟电梯的控制器的运作与现实的电梯相似,需要设计相应的接口以便模拟控制器以正确的逻

6、辑正常运作。功能接口设计5. 体会与总结对于这次的课设,我个人认为这是大学以来工程量最大的课设,因为它涉及了软件方便的编码,还有硬件方面的PCB制版还有最后就是要自行编写一个规范的文档报告,总的来说工作的内容还是比较丰富的。在软件编码方面,由于C语言有一段时间没有去使用了,所以在对单片机进行裸机编程的时候,我去复习了单片机原理和C语言的相关书籍,以便我去选择更好的数据结构用来存储数据。在软件编码过程中,比较有意思的就是去设计电梯运作逻辑,在设计这个逻辑时,我自己也再次对我们生活中的电梯运作流程进行了进一步的观察。这个逻辑相对于比较有挑战性的就是,你要让你写的逻辑穿插在硬件层和软件曾中正常运行,

7、所以在DEBUG的时候也比较难去查问题,由于自己也比较懒,在DEBUG的时候懒得用那个仿真调试的功能,导致最后解决BUG的时间花的还是比较多的。在硬件PCB板制作方面,主要就是去学习怎样去使用AD这个专业的画板软件,自己也第一次去用化学药剂腐蚀的方法去制作最小版,自己动手去做一个小玩意儿的经历也是很有意思的。在文档编写方面,由于之前上了WORD的选修,所以我也就趁这次机会,把之前所学的只是进行学以致用,这次文档的编写我尽量按照毕业课设的规范来要求自己,以求让文档的格式看起来更加的让人赏心悦目。6. 附录源代码#include "iostm8s105c6.h"#include

8、 <stdio.h>#include <stdbool.h>/*宏定义*/#define Floors 8/*全局数组,变量*/int floorStateFloors + 1 = 0,0,0,0,0,0,0,0,0; /*true表示有该楼层的请求还未处理,false表示在该楼层没有请求*/unsigned char DisDisplay10 = 0X00,0XF3,0X49,0X61,0X33,0X25,0X05,0XF1,0X01,0X7F;int FloorNow = 1; /电梯所处的楼层unsigned char i = 0; /解决定时器第一次中断问题un

9、signed char j = 0; /解决电梯按下关门请求后会自动开门的变量unsigned char Temp1 = 0; /计数为两秒用(电梯上升楼层的间隔时间)unsigned char Temp2 = 0; /10s,自动关门用unsigned char FloorPoint = 0; /记忆指针unsigned char FloorStart = 0; /记忆初始位置unsigned char FloorOver = 0; /记忆终止位置unsigned char Index = 0;int bottonNum = -1;int direction = -2; /*初始值为 -2*

10、/int floorToGo = -1; /*楼梯将要去的楼层*/void DisBegin(void); /初始化内部数码管和上下说明void LedBegin(void); /初始化内部LED函数声明void KeyBegin(void); /初始化键盘输入函数声明void BreakPoint(void); /键盘中断优先级函数初始化void Running(void); /电梯运行函数声明void TIM1_Init(void); /定时器初始化函数声明void DoorJudge(void); /中断内开关门的判断程序void delay(unsigned int time); /延

11、时函数声明void Floor_To_Go(); /吐出要去的楼层命令void Judge_Direction();void Step_one(int bottonNum);void main(void) LedBegin(); /LED初始化 KeyBegin(); /键盘初始化 DisBegin(); /内部数码管初始化 _asm("sim"); BreakPoint(); /键盘中断初始化 TIM1_Init(); /定时器初始化 TIM1_CR1 = 0X04; /置CEN零,先不计数 /TIM1_CR1 = 0X01; /开始计数 _asm("rim&q

12、uot;); /开总中断 while (1) Running(); /电梯运行s /*在主循环内要频繁的去对比,电梯运行到的当前楼层是否到达了最近需要去到达的楼层(最迫切去处理的请求)*/ if (FloorNow = floorToGo) floorStateFloorNow = 0; /*清除当前楼层的请求*/ /上下指示灯的行为步骤 if (direction = 0) PG_ODR = 0XFD; else if(direction = 1) PG_ODR = 0XFE; else PG_ODR |= 0XFF; /到达楼层,关掉上下指示灯 /初始化内部LED函数定义void LedB

13、egin(void) PD_DDR = 0XFF; PD_CR1 = 0XFF; PD_CR2 = 0X00; PD_ODR = 0XFF; PE_DDR = 0XFF; PE_CR1 = 0XFF; PE_CR2 = 0X00; PE_ODR = 0X00; /初始化开关门指示灯的同时顺便初始化按键使其输出全零扫描码 PG_DDR = 0XFF; /初始化方向指示灯 PG_CR1 = 0XFF; PG_CR2 = 0X00; PG_ODR = 0XFF;/初始化内部数码管void DisBegin(void) PC_DDR = 0XFF; PC_CR1 = 0XFF; PC_CR2 = 0X

14、00;/初始化键盘输入函数定义void KeyBegin(void) /初始化键盘输出与输入 PA_DDR = 0XFF; /初始化开关门键输出全零扫描码 PA_CR1 = 0XFF; PA_CR2 = 0X00; PA_ODR = 0X00; PB_DDR = 0X00; /两个矩阵键盘的输入检测 PB_CR1 = 0XFF; PB_CR2 = 0XFF;/键盘中断初始化函数定义void BreakPoint(void) ITC_SPR2 = 0X03; EXTI_CR1 = 0X08;/定时器初始化函数定义void TIM1_Init(void) TIM1_SMCR = 0X00; TIM

15、1_ETR = 0X00; TIM1_SR1 &= 0XEF; /先清除一次更新中断标志 TIM1_PSCRH = 0; TIM1_PSCRL = (unsigned char)199; /对2MHz进行200分频,之后频率为10kHz TIM1_IER = 0X01; /开启溢出中断 TIM1_ARRH = (unsigned char)(10000 >> 8); TIM1_ARRL = (unsigned char)10000; /数10000次,记为1s TIM1_CNTRH =0 ;/(unsigned char)(20000 >> 8); TIM1_C

16、NTRL =0 ;/(unsigned char)20000; /先溢出一次/电梯运行函数定义void Running(void) PC_ODR = DisDisplayFloorNow; unsigned char FloorLed = 0; for(Index = Floors;Index >= 1; Index -) FloorLed = FloorLed + floorStateIndex; if (Index = 1) break; FloorLed <<= 1; PD_ODR = FloorLed;#pragma vector = 13_interrupt voi

17、d TIM1_OVF_IRQ(void) i +; if(i > 1) Temp1 +; if(Temp1 > 1) /判定为两秒 if(floorToGo > 0 && floorToGo < 9) if(FloorNow < floorToGo) /去往请求楼层 FloorNow +; PG_ODR = 0XFE; /上指示灯 Temp2 = 0; j = 0; /关门bug解决变量回位 else if(FloorNow > floorToGo) FloorNow -; PG_ODR = 0XFE; /下指示灯 Temp2 = 0; j

18、= 0; /关门bug解决变量回位 else if (FloorNow = floorToGo) /到达楼层 DoorJudge(); Temp1 = 0; else DoorJudge(); else; TIM1_SR1 = 0X00; /清除更新中断标志#pragma vector = 6 /用于判断按下了哪里的按钮_interrupt void KeyScan(void) TIM1_SR1 = 0X00; /先清除一次更新中断标志 TIM1_CR1 = 0X05; /开始计数 i = 0; PE_ODR |= 0XFE; PE_ODR &= 0XFD; /内部第一行检测 if(P

19、B_IDR & 0X0F) != 0X0F) delay(50); if(PB_IDR & 0X0F) != 0X0F) switch (PB_IDR & 0X0F) case 0X0E: bottonNum = 1; break; case 0X0D: bottonNum = 2; break; case 0X0B: bottonNum = 3; break; case 0X07: bottonNum = 4; break; default: break; PE_ODR |= 0XFE; PE_ODR &= 0XFB; /内部第二行检测 if(PB_IDR &

20、amp; 0X0F) != 0X0F) delay(50); if(PB_IDR & 0X0F) != 0X0F) switch (PB_IDR & 0X0F) case 0X0E: bottonNum = 5; break; case 0X0D:; bottonNum = 6; break; case 0X0B: bottonNum = 7; break; case 0X07: bottonNum = 8; break; default: break; PE_ODR |= 0XFE; PE_ODR &= 0XF7; /内部第三行开关请求检测 if(PB_IDR &am

21、p; 0X0F) != 0X0F) delay(50); if(PB_IDR & 0X0F) != 0X0F) switch (PB_IDR & 0X0F) case 0X0E: /开门请求 if(FloorNow = floorToGo) | (floorToGo = -1) PE_ODR |= 0X01; else ; break; case 0X0D: /关门请求 PE_ODR &= 0XFE; j +; break; default: break; PE_ODR |= 0XFE; /用完一次行扫描就关闭本次行扫描码进行其他判断,判断完了重新开就是了 PA_ODR

22、 = 0XF7; /外部按键第一行检测 if(PB_IDR & 0XF0) != 0XF0) delay(50); if(PB_IDR & 0XF0) != 0XF0) switch (PB_IDR & 0XF0) case 0XE0: bottonNum = 1; break; case 0XD0: bottonNum = 2; break; case 0XB0: bottonNum = 3; break; case 0X70: bottonNum = 4; break; default: break; PA_ODR = 0XEF; /外部按键第二行检测 if(PB_

23、IDR & 0XF0) != 0XF0) delay(50); if(PB_IDR & 0XF0) != 0XF0) switch (PB_IDR & 0XF0) case 0XD0: bottonNum = 2; break; case 0XB0: bottonNum = 3; break; case 0X70: bottonNum = 4; break; default: break; PA_ODR = 0XDF; /外部按键第三行检测 if(PB_IDR & 0XF0) != 0XF0) delay(50); if(PB_IDR & 0XF0) !

24、= 0XF0) switch (PB_IDR & 0XF0) case 0XE0: bottonNum = 5; break; case 0XD0: bottonNum = 6; break; case 0XB0: bottonNum = 7; break; default: break; PA_ODR = 0XBF; /外部按键第四行检测 if(PB_IDR & 0XF0) != 0XF0) delay(50); if(PB_IDR & 0XF0) != 0XF0) switch (PB_IDR & 0XF0) case 0XE0: bottonNum = 5

25、; break; case 0XD0: bottonNum = 6; break; case 0XB0: bottonNum = 7; break; case 0X70: bottonNum = 8; break; default: break; Step_one(bottonNum); Judge_Direction(); Floor_To_Go(); /if(HXFloorNow != floorToGo) /目的楼层亮灯判断 if(floorToGo != -1) PE_ODR &= 0XFE; /电梯移动时的强制关门指令 else; /上下指示灯的行为步骤 if (direct

26、ion = 0) PG_ODR = 0XFD; else if(direction = 1) PG_ODR = 0XFE; else PG_ODR |= 0XFF; /到达楼层,关掉上下指示灯 PE_ODR &= 0X01; /继续输出全零扫描码 PA_ODR = 0X00;/中断内开关电梯门判断程序void DoorJudge(void) Temp2 +; /开始计数(10s) PG_ODR = 0XFF; /再次确认关掉上下指示灯 if(Temp2 > 5) /到了10s PE_ODR &= 0XFE; /把门关上 Floor_To_Go(); else /没到10s

27、 if(j > 0) /但是有人按了关门键 PE_ODR &= 0XFE; /那就关门 Floor_To_Go(); else /如果没人按键盘 PE_ODR |= 0X01; /那就先开着电梯门 void delay(unsigned int time) while(time -);/*当按钮按下时,将会触发外部中断*/*外部中断的第一步将会修改全局数组*/void Step_one(int bottonNum) if (bottonNum != FloorNow) floorStatebottonNum = 1;/*外部中断的第二步将会判断direction变量的取值*/vo

28、id Judge_Direction() int i; bool flag = 0; if (direction = -2) /*此时电梯处于刚开机的状态*/ direction = 1; /*电梯运行方向为向上*/ else if (direction = 1) /*当电梯在向上运行时*/ for (i = FloorNow + 1; i <= Floors; i+) if (floorStatei = 1) flag = 1; return; if (flag = 0) for (i = FloorNow - 1; i >= 1; i-) if (floorStatei = 1

29、) flag = 1; direction = 0; return; if (flag = 0) direction = -1; return; else if (direction = 0) /*当电梯在向下运行时*/ for (i = FloorNow - 1; i >= 1; i-) if (floorStatei = 1) flag = 1; return; if (flag = 0) for (i = FloorNow + 1; i <= Floors; i+) if (floorStatei = 1) flag = 1; return; if (flag = 0) direction = -1; return; else if (direction = -1) /*电梯再次静止*/ int a = 0, b = 0, i, flag1 = 0, fl

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论