沈阳航空航天大学课程设计报告课程设计名称:微机系统综合课程设计课程设计题目:按键反应速度测试院(系):计算机学院专业:计算机科学与技术班级:计算机1203学号:2012040101127姓名:王庆贺指导教师:张维君说明:结论(优秀、良好、中等、及格、不及格)作为相关教环节考核必要依据;格式不符合要求;数据不实,不予通过。
报告和电子数据必须作为实验现象重复的关键依据。
学术诚信声明本人声明:所呈交的报告(含电子版及数据文件)是我个人在导师指导下独立进行设计工作及取得的研究结果。
尽我所知,除了文中特别加以标注或致谢中所罗列的内容以外,报告中不包含其他人己经发表或撰写过的研究结果,也不包含其它教育机构使用过的材料。
与我一同工作的同学对本研究所做的任何贡献均己在报告中做了明确的说明并表示了谢意。
报告资料及实验数据若有不实之处,本人愿意接受本教学环节“不及格”和“重修或重做”的评分结论并承担相关一切后果。
本人签名: 日期:年月日沈阳航空航天大学课程设计任务书目录1 总体设计方案 (1)1.1课程设计内容和要求 (1)1.2设计原理 (1)1.3设计思路 (1)2 详细设计方案 (3)2.1实现方法 (3)2.1.1 硬件实现 (3)2.1.2 软件实现 (3)2.2模块设计 (4)2.2.1 测试数字控制模块 (4)2.2.2 按键状态读取模块 (5)2.2.3 计时模块 (5)2.2.4 显示模块 (6)3 调试及结果分析 (8)3.1调试步骤及方法 (8)3.2实验结果 (8)参考文献 (9)附录 (10)1 总体设计方案1.1课程设计内容和要求一、课程设计内容在LED数码管上显示一组数字,按对应数字键后显示内容换成下一组数字。
累计按键的延迟时间,最后显示被测试者的总反应时间。
二、课程设计要求1.认真查阅相关资料;2.独立设计、调试并通过指导教师现场验收;3.撰写课程设计报告。
1.2 设计原理根据课程设计任务书的要求,通过单片机的P1口控制8个发光二极管,测试被测试者从看到所显示数字到按下对应数字键的反应时间,累计十次,并将测试出的时间显示在数码管上。
时间的计数通过单片机的定时器实现,程序开始先配置定时器,设置定时器的工作模式和计数初值,之后开启定时器中断和总中断,并启动定时器。
在定时器启动同时,显示第一个数字,然后等待被测试者按下对应数字键,当按下对应数字键的时候,数码管显示下一组数字,再等待被测试者正确按下对应的数字键......这样重复十次。
当被测试者最后一次正确按下对应数字键时候,定时器停止工作。
之后根据计数器的定时计数情况,计算相应的反应时间,并在数码管上显示。
1.3 设计思路本文基于LAB8000型实验箱,以51单片机为控制核心,连接矩阵键盘,数码管采用内驱方式,只需要连接KEY/LED CS就可以控制数码管的显示。
本文采用C语言编程,根据模块化设计思想,软件主要包括:测试数字控制模块、按键状态读取模块、计时模块和显示模块。
测试数字控制模块的主要功能是显示测试数字。
按键状态读取模块的主要功能是读取数字键盘的状态并判断数字正误情况。
当计时开始的时候,显示第一个数字,然后等待被测试者按下对应数字键,当正确按下对应数字键的时候,数码管显示下一组数字,再等待被测试者正确按下对应的数字键......这样重复十次。
当被测试者最后一次正确按下对应数字键时候,定时器停止工作。
计时模块的功能就是用来计算总的反应时间,总反应时间是从计时开始,点数码管显示第一个数字到拨动最后一个开关,计时结束这一段时间。
本文采用单片机的定时/计数器0进行时间的测量,首先配置计时器工作于计时模式二,即8位自动重装载模式,并使能总中断和定时器中断,这样启动定时器就可以计时了,当计数器溢出的时候,进入中断处理函数,在定时器中断函数处理中记录定时器的溢出次数,同时会将高位寄存器的初值自动装载入低位寄存器,重新开始计时。
当测试结束时,停止计时,最终计算总的计数次数,得出计时时间。
显示模块的功能就是用来显示时间。
时间采用四位数码管进行显示,整数部分两位、小数部分也两位,单片机采用内驱的方式控制数码管的显示,在显示前,通过相应的算法得到十位、个位、十分位和百分位的字形码,通过单片机发送字形码以及相应的位选信号,就可以实现时间的显示了。
2 详细设计方案2.1 实现方法本文是基于LAB8000实验箱,并以单片机为控制核心的按键反应速度测试系统设计,系统分为硬件实现和软件实现两部分,下面将分别介绍。
2.1.1 硬件实现硬件电路包括三部分:单片机、矩阵键盘和数码管。
因为本文是基于LAB8000实验箱,相关的硬件电路已经设计好,我们需要做的就是进行相应的连线,具体的连线如表2.1所示。
表2.1 硬件连线2.1.2 软件实现软件实现是本文的重点,使用的是C语言编程,采用模块化的设计思想,根据系统要求和相关的硬件电路,软件实现可以分为三个部分:测试数字模块、按键状态读取模块、计时模块和显示模块。
具体的软件流程为:1.定时器初始化;2.开定时器中断和总中断;3.启动定时器;4.显示一个数字,等待被测试者按下对应数字键;5.点亮另一个发光二极管……重复十次;6.停止定时器;7.计算总反应时间;8.数码管显示总反应时间。
软件流程图如图2.1所示。
图2.1 软件流程图2.2 模块设计根据前面的介绍,本文可分为四个模块,分别为:测试数字控制模块、按键状态读取模块、定时器计时模块和数码管显示模块,下面将一一介绍。
2.2.1 测试数字控制模块在程序中,先运用位控制,关所有八段管,并使最低位选通,用于显示数字: OUTBIT = 0;OUTBIT = 0x01;人为设定十个数字,具体是通过如下数组实现的:OUTSEG = Disp_34[5];OUTSEG = Disp_34[0];……OUTSEG = Disp_34[4];测试数字右移两位,最低位显示:OUTBIT = 0x01|(0x0b<<2);2.2.2 按键状态读取模块图2.2 矩阵键盘电路图矩阵键盘通过扫描高电平到低电平的变化来判断被测试者按下的是哪一个数字键:while(!((KeyValue=(P1&0xf0)|0x0b)==0xbb));while(!((KeyValue=(P1&0xf0)|0x07)==0xe7));……while(!((KeyValue=(P1&0xf0)|0x07)==0xb7));while里就是一直读取测试数字,如果按键值如果是正确的就跳出,不正确则一直读直到是。
2.2.3 计时模块计时使用的是单片机内部的定时/计数器0,在使用定时器时,首先需要进行模式配置,定时器有四种工作模式,通过模式寄存器TMOD进行配置,我们使用模式二,即8位自动重装载模式,在该模式下,当低位数据寄存器的值溢出时,会将高位数据寄存器的值载入低位寄存器,重新开始计数,模式寄存器TMOD各位如表2.4所示。
表2.2 模式寄存器TMOD配置好模式后,因为我们需要使用定时器的中断,所以还需要使能定时器中断和总中断,中断控制在中断允许寄存器IE中,其各位定义如表2.5所示。
表2.3 中断允许寄存器IE使能中断后,就可以运行定时器了,运行定时器0的语句为TR0 = 1,其中TR0在定时器控制寄存器TCON中,TCON各位定义如表2.6所示。
表2.4 定时器控制寄存器TCON因为计时时间比较长,单次的计数值远远不能满足需求,所以我们使用定时器的中断功能,当计数值溢出的时候,触发定时器中断,在中断函数中,我们使溢出计数值加一,最后根据溢出次数值和计数器的值,就可以算出总时间。
2.2.4 显示模块本文使用数码管显示时间,在显示之前,我们需要将定时器的时间转换成数码管显示需要的字形码。
时间以秒为单位,通过分析,总反应时间应该不会超过100s,我们使用4位数码管进行显示足以,其中整数部分两位,小数部分两位。
得到整数部分和小数部分的算法如下:1.根据计数值得到时间,以秒为单位;2.将时间乘以100,即把小数部分转换成整数部分;3.将数据强制类型转换为整型,舍去剩下的小数部分;4.数据除以1000,取商,即得到十位数据值;5.数据除以1000,取余,再除以100,取商,即得到各位数据;6.数据除以100,取余,再除以10,取商,即得到十分位数据;7.数据除以10,取余,即得到百分位数据。
得到各位数据后,将这些数据转换为相应的字形码,通过单片机输出给数码管,就可以显示相应的数据了,数码管的字形码如表2.7所示。
表2.5 数码管字形码数码管显示程序流程图如图2.3所示。
图2.3 数码管显示流程图沈阳航空航天大学课程设计报告错误!未指定书签。
3 调试及结果分析3.1 调试步骤及方法1. 使用导线将相应的连接孔连接在一起;2. 将程序载入单片机;3. 复位,运行程序3.2 实验结果本程序能够满足题目的所有要求,其测试结果如下:当程序开始运行之后,显示第一个数字,然后等待被测试者按下对应数字键,当按下对应数字键的时候,数码管显示下一个数字。
1.当十次测试完成后,并且数码管显示测试总时间。
数码管时间显示正确。
沈阳航空航天大学课程设计报告错误!未指定书签。
参考文献[1] 张毅刚.单片机原理及应用[M].哈尔滨:哈尔滨工业大学出版社,2008[2] 戴仙金.51单片机及其C语言程序开发实例[M].北京:清华大学出版社,2011[3] 黄惟公.单片机原理及应用技术[M].西安:西安电子科技大学出版社,2010[4] 高锋.单片微型计算机原理与接口技术[M].北京:科学出版社,2007[5] 何立民.MSC--51系列单片机应用系统设计:北京航空航天大学出版社,1993[6] 余发山.单片机原理及应用技术:中国矿业大学出社,2003附录#include <REG51.H>xdata unsigned char OUTBIT _at_ 0x8002; // 位控制口xdata unsigned char OUTSEG _at_ 0x8004; // 段控制口unsigned int nCnt = 0;float tim = 0;unsigned int timshow = 0;unsigned int shiwei = 0;unsigned int gewei = 0;unsigned int shifenwei = 0;unsigned int baifenwei = 0;unsigned char Disp_1[] = {0x00,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; unsigned char Disp_2[] = {0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; unsigned char Disp_34[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};void main(void){unsigned char KeyValue = 0;TMOD = 0x02; // 定时器0,8位自动重装载TH0 = 0x0;TL0 = 0x0;EA = 1; // 使能总中断ET0 = 1; // 使能定时器中断TR0 = 1; // 计时开始OUTBIT = 0; // 关所有八段管OUTBIT = 0x01; // 最低位选通,用于显示数字OUTSEG = Disp_34[5]; // 显示第一个数字 5,其键值为 0xbbOUTBIT = 0x01|(0x0b<<2);while(!((KeyValue=(P1&0xf0)|0x0b)==0xbb));OUTSEG = Disp_34[0]; // 显示第二个数字 0,其键值为 0xe7OUTBIT = 0x01|(0x07<<2);while(!((KeyValue=(P1&0xf0)|0x07)==0xe7));OUTSEG = Disp_34[8]; // 显示第三个数字 8,其键值为 0x7b OUTBIT = 0x01|(0x0b<<2);while(!((KeyValue=(P1&0xf0)|0x0b)==0x7b));OUTSEG = Disp_34[6]; // 显示第四个数字 6,其键值为 0xbd OUTBIT = 0x01|(0x0d<<2);while(!((KeyValue=(P1&0xf0)|0x0d)==0xbd));OUTSEG = Disp_34[1]; // 显示第五个数字 1,其键值为 0xd7 OUTBIT = 0x01|(0x07<<2);while(!((KeyValue=(P1&0xf0)|0x07)==0xd7));OUTSEG = Disp_34[9]; // 显示第六个数字 9,其键值为 0x7d OUTBIT = 0x01|(0x0d<<2);while(!((KeyValue=(P1&0xf0)|0x0d)==0x7d));OUTSEG = Disp_34[7]; // 显示第七个数字 7,其键值为 0x77 OUTBIT = 0x01|(0x07<<2);while(!((KeyValue=(P1&0xf0)|0x07)==0x77));OUTSEG = Disp_34[3]; // 显示第八个数字 3,其键值为 0xdd OUTBIT = 0x01|(0x0d<<2);while(!((KeyValue=(P1&0xf0)|0x0d)==0xdd));OUTSEG = Disp_34[2]; // 显示第九个数字 2,其键值为 0xdb OUTBIT = 0x01|(0x0b<<2);while(!((KeyValue=(P1&0xf0)|0x0b)==0xdb));OUTSEG = Disp_34[4]; // 显示第十个数字 4,其键值为 0xb7 OUTBIT = 0x01|(0x07<<2);while(!((KeyValue=(P1&0xf0)|0x07)==0xb7));OUTBIT = 0x00;TR0 = 0; // 计时结束tim = (((float)nCnt)*256 + TL0) / 1000000; // 计算总时间 timshow = (unsigned int)(tim * 100);shiwei = timshow / 1000;gewei = timshow % 1000 / 100;shifenwei = timshow % 100 / 10;baifenwei = timshow % 10;while(1){unsigned int i = 0;OUTBIT = 0; // 关所有八段管OUTBIT = 0x04; // 百分位数码管位选信号OUTSEG = Disp_34[baifenwei]; // 显示百分位数据for(i=0;i<255;i++); // 简单延时OUTBIT = 0; // 关所有八段管OUTBIT = 0x08; // 十分位数码管位选信号OUTSEG = Disp_34[shifenwei]; // 显示十分位数据for(i=0;i<255;i++); // 简单延时OUTBIT = 0; // 关所有八段管OUTBIT = 0x10; // 个位数码管位选信号OUTSEG = Disp_2[gewei]; // 显示个位数据for(i=0;i<255;i++); // 简单延时OUTBIT = 0; // 关所有八段管OUTBIT = 0x20; // 十位数码管位选信号OUTSEG = Disp_1[shiwei]; // 显示十位数据for(i=0;i<255;i++); // 简单延时OUTBIT = 0; // 关所有八段管}}void Timer0_IRQ(void) interrupt 1{nCnt++;}。