99秒秒表课程设计.docx
《99秒秒表课程设计.docx》由会员分享,可在线阅读,更多相关《99秒秒表课程设计.docx(17页珍藏版)》请在冰豆网上搜索。
99秒秒表课程设计
第1章99秒秒表设计背景及目的要求
1.199秒秒表设计背景
目前,单片机正朝着高性能和对品种方向发展,趋势是进一步向着低功耗、小体积、大存量、高性能、低价格和电路内装化等几个方面发展。
单片机应用的重要意义还在于他从根本上改变了传统的控制系统设计思想和设计方法。
从前必须由模拟电路或数字电路实现的大部分功能,现在已能用单片机通过软件方法来实现了。
这种软件代替硬件的控制技术也称为微控制技术,是传统控制技术的一次革命。
单片机模块中最常见的是秒表、数字钟等显示时间类的装置,此装置是一种用数字电路实现时、分、秒计时的装置,与机械式时钟相比具有更高的准确性和直观性,且无机械装置,具有更长的使用寿命,因此得到了广泛的使用。
此设计利用凌阳科技公司的凌阳16位单片机SPCE061A为主控芯片,充分利用61单片机开发板上面的三个按键,完成一个简易的现实系统——99秒秒表。
61单片机开发板是一套完整的16位单片机开发系统,可直接把程序下载到61单片机开发板上进行调试和封装。
集成度高、运算速度快、体积小、运算可靠、价格低廉,在过程控制、数据采集、机电一体化、智能仪器仪表、网络技术等方面得到广泛应用。
1.2设计目的
随着单片机应用的日益广泛,在校学生加强对单片机的认识和动手能力,已经是非常重要的一项锻炼。
课程设计就是为加强实践机会、培养学生动手能力的一个重要环节,将理论知识与实际联系起来的一个关键机会。
本课程设计的基本要求是:
1.掌握LED数码管原理及使用方法。
2.掌握61单片机开发板的使用方法。
3.初步掌握SPCE061A单片机汇编语言一般编程技巧。
4.初步掌握61单片机开发板系统调试的一般步骤及方法。
1.3硬件选择
装有Windowsxp系统和μ’nSP™IDE仿真环境的PC机一台,μ’nSP™十六位SPCE061A单片机开发板一块。
本设计用到的硬件模块为:
SPCE061A核心及周边电路模块(包含16个I/O口),LED数码管。
1.4设计内容
本装置将实现0-99的计数,每次改变计数器将加0.5,在数码管上显示当前计数值,并可用键盘按制计数的起始,以及归零。
具体要求如下:
1.开机时数码管显示00.0。
2.每次改变,计数器自动加0.5。
3.按键控制计数,分别控制开始计时、停止计时和归零,功能分配如下:
表1-1按键功能分配
按键
功能描述
KEY1
开始计时
KEY2
停止计时
KEY3
归零
第2章设计方案及基本原理
2.1预备知识
1.熟悉凌阳单片机的工作原理。
(1)I/O口的使用原理和设置;
(2)定时器或时基的设置、使用;
(3)中断的设定。
2.了解数码管的显示原理。
3.熟悉键盘扫描原理。
4.熟悉汇编语言或C语言。
2.2LED显示原理
静态显示就是显示驱动电路具有输出锁存功能,单片机将所要显示的数据送出后就可以,直到下一次显示数据需要更新时再传送一次新数据,显示数据稳定,占用很少的CPU时间。
动态显示需要CPU时刻对显示器件进行数据刷新,显示数据有闪烁感,占用的CPU时间多。
这两种显示方式各有利弊;静态显示虽然数据稳定,占用很少的CPU时间,但每个显示单元都需要单独的显示驱动电路,使用的硬件较多;动态显示虽然有闪烁感,占用的CPU时间多,但使用的硬件少,能节省线路板空间。
基本的半导体数码管是由七个条状发光二极管排列而成的,可实现0~9的显示。
LED数码管是由发光二级管显示字段组成的显示器,有8段和“米”字段之分,这种显示器有共阳级和共阴极两种方式。
所谓共阳方式是指笔画显示器各段发光管的阳极(即P区)是公共的,而阴极互相隔离。
所谓共阴方式是笔画显示器各段发光管的阴极(即N区)是公共的,而阳极是互相隔离的。
2.3元器件选择
SPCE061A单片机开发板一块、21针并口下载线一条、八路排线两条、显示模块等。
2.4系统设计
根据设计题目的要求分析,并考虑到题目的可扩展性,可将系统分成两大部分:
1.时间的产生和显示。
2.按键控制计数起始、归零。
根据系统的功能现选择61单片机开发板,作为单片机控制处理部分;利用三位LED作为显示部分,而按键采用61单片机开发板上自带的三个按键,如图2-1所示。
图2-1系统框图
2.5硬件工作原理
三位数的显示采用的是一个三位共阴极LED数码管,连接方法是SPCE061A的IOB0-IOB7接LED焊接板的a-g以及dp端;IOB8-IOB9分别接LED的位选COM1、COM2、COM3,电路原理图如图2-2。
LED与SPCE061A的引脚连接如表2-1。
采用凌阳大学计划的LED键盘模组和61单片机开发板搭配可以很容易的完成这个课程设计的题目。
它的连结图如图所示,IOB的低八位控制数码管的段选,高八位控制数码管的位选。
表2-1LED引脚连接表
SPCE061A
LED模块
SPCE061A
LED模块
IOB8
A
IOB0
COM1
IOB9
B
IOB1
COM2
IOB10
C
IOB2
COM3
IOB11
D
IOB12
E
IOB13
F
IOB14
G
IOB15
DP
2.6硬件连接
采用凌阳大学计划的LED键盘模组和61单片机开发板搭配可以很容易的完成这个课程设计的题目。
它的连结图如图所示,IOB的低八位控制数码管的段选,高八位控制数码管的位选。
图2-2LED键盘模组和61单片机开发板连接图
第3章程序设计
3.1设计步骤
根据设计要求的功能,程序主要分为三部分,即:
(1)计时显示部分;
(2)秒计时部分;
(3)按键控制部分。
(4)程序主流程主要完成键盘扫描、计时处理、键值分支控制的任务,流程图3-1所示:
图3-1主程序流程图
显示部分是在IRQ4的1KHz中断中控制显示的,采用动态扫描的方式,1KHz的时基中断每1ms进一次中断,在中断中对2ms计数器i进行累加,当i从0累加到2时,则刚好为2ms,此时更新一个位的LED显示,并对i进行清零;当下一次累计到2ms时,则会再更新显示下一位LED数码管,当更新到最后一位时,返回重第一位开始更新;依此循环更新显示,而更新显示的数据保存在缓冲区当中,用户需要更新显示的数据时,只需要改变对应的缓冲区中的数据即可。
具体流程图如下。
秒计时采用IRQ5的2Hz时基中断进行计时,流程图如图3-3所示。
键盘输入利用61单片机开发板自带的三个按键,输入的端口为IOA0—IOA2。
图3-2IRQ41KHz时基中断流程图3-3IRQ52Hz时基中断流程图
3.2程序代码
见附录
第4章调试结果及分析
4.1调试结果
本装置将实现0-99的计数,每次改变,计数器将加0.5,在数码管上显示当前计数值,并可用键盘按制计数的起始,以及归零。
具体要求如下:
1.开机时数码管显示00.0。
2.每次改变,计数器自动加0.5。
3.按键控制计数,分别控制开始计时、停止计时和归零,功能分配如下:
按KEY1开始计时数码管显示从00.0开始计时到99.5结束再从00.0开始循环;
按KEY2停止计时数码管显示当前数值;按KEY3归零;按KEY4复位.
4.2结果分析
本设计应该熟悉凌阳十六位单片机系统板-61单片机开发板的基本构成,掌握LED数码管原理及使用方法,掌握61单片机开发板的使用方法,初步掌握SPCE061A单片机汇编语言一般编程技巧,初步掌握61单片机开发板系统调试的一般步骤及方法。
设计结构现实:
开机时数码管显示为00.0,每次改变计数器自动加一,按KEY1键开始计时,按KEY2键停止计时并现实当前数值,按KEY3键归零。
第5章结论与体会
设计结论:
1.在设计中我遇到了对单片机汇编语言不熟悉程序编写困难以及显示小数点位显示等问题。
原本希望能够实现0.1秒的精度,但是最终还是没有实现,后来总结是因为数据发生了溢出,所以只能求其次实现了0.5秒的精度。
2.此设计的优点是思路清晰、连接简单。
3.我建议在LED引脚应先标志出来,增加单片机软件程序智能的对进制进行转换,除去繁冗的进制计算。
心得体会:
单片机课程设计结束了,最初的目的是想学到一些对将来就业很有实质性帮助的东西。
结果还算可以接受,虽然说与预期的有少许的出入,但锻炼自己这个主要目标算是达到了。
通过这次课程设计,我对如何完成一项实际的计划有了进一步的认识,对如何加强自己的合作能力有了更进一步的思考。
通过这次课程设计,我想下学期的毕业设计会少点困难,以后在工作中也能够有更多的经验好借鉴。
在这段日子里,我实践、思考、反思、总结,所得收获都已经成为大学生涯中的宝贵财富。
或许大学生活中的片断随着岁月的流逝难免被遗忘,但是这段课程设计的日子相信仍会是记忆深刻,它作为我们走向社会的第一步,承载了即将面对现实和挑战的心情,必将难忘。
参考文献
[1]于海生.微型计算机控制技术[M].清华大学出版社,1999-6.
[2]孙涵芳.MCS-51系列单片机原理及应用[J].北京航天大学出版社,1996-4.
[3]黄正瑾.综合电子设计与实践[M].东南大学出版社,2002-3.
[4]罗亚非.凌阳16位单片机应用基础[M].北京航空航天大学出版社,2005.
[5]周立功.单片机实验与实践[M].北京:
北京航空航天大学出版社,2004.
附录
//========================================================
//工程名称:
counter.spj
//适应芯片:
SPCE061A
//实现功能:
课程设计2,用61板和LED板子实现99秒计数器
//涉及的库:
(a)C-Lib:
(CMacro.lib);
//(b)SACM-Lib:
SacmV26.lib;
//组成文件:
//main.c/ISR.c/numLED.c
//boot.asm/hardware.asm/key.asm
//hardware.h/hardware.inc
//========================================================
intiShow[3],key=0;
intiCounter=0;//在2Hz中断里面计时
#defineP_Watchdog_Clear(volatileunsignedint*)0x7012
//以下是键盘扫描程序,在key.asm中定义
externvoidF_Key_Scan_Initial(void);
externvoidF_Key_Scan_ServiceLoop(void);
externunsignedintSP_GetCh(void);
intmain(void)
{
inti,j,iCounter1;
F_IrqInti();//中断初始化
F_Key_Scan_Initial();//键盘初始化,在key.asm中定义
while
(1)
{
key=SP_GetCh();//按键扫描,并获取键值,在key.asm中定义
switch(key)
{
case0x0001:
//按键1则开始计数
F_Irq5_2HzOn();//打开2Hz中断,则开始计数
break;
case0x0002:
//按键2则停止计数
F_Irq5_2HzOff();//关掉2Hz中断,即停止计数
break;
case0x0004:
//按键3则计数器清零
iCounter=0;
break;
default:
break;
}
//计算要显示的值,显示程序写在中断中,以便播放语音时能及时更新显示//数据
iCounter1=iCounter>>1;
iShow[0]=(iCounter1/10)%10;
iShow[1]=iCounter1%10;
iShow[2]=(iCounter1*5)%10;
*P_Watchdog_Clear=0x0001;//清看门狗
F_Key_Scan_ServiceLoop();//键盘扫描的后台循//环服务程序,在key.asm中定义
}
}
//======================================================
//文件名称:
numLED.c
//描述:
建立数码管显示模块
//=======================================================
#defineClearWDog(*((volatileunsignedchar*)0x7012))=1
#defineP_IOA_Data(volatileunsignedint*)0x7000
#defineP_IOA_Buffer(volatileunsignedint*)0x7001
#defineP_IOA_Dir(volatileunsignedint*)0x7002
#defineP_IOA_Attrib(volatileunsignedint*)0x7003
#defineP_IOA_Latch(volatileunsignedint*)0x7004
#defineP_IOB_Data(volatileunsignedint*)0x7005
#defineP_IOB_Buffer(volatileunsignedint*)0x7006
#defineP_IOB_Dir(volatileunsignedint*)0x7007
#defineP_IOB_Attrib(volatileunsignedint*)0x7008
#definebitset(var,bitno)((var)|=(1<<(bitno)))
#definebitclr(var,bitno)((var)&=((1<constintciNum[10]={0x3f00,0x0600,0x5b00,0x4f00,0x6600,0x6d00,0x7c00,0x0700,0x7f00,0x6f00};
//constintciNum[10]={0x003f,0x0086,0x00db,0x00cf,//0x00e6,0x00ed,0x00fc,0x0087,0x00ff,0x00ef};
//========================================================
//函数名称:
F_numLED_Ctrl(intiBit,intiNum)
//描述:
控制数码管显示
//入口参数:
iBit:
选择第几位亮;iNum:
显示数字几
//IOB2--IOB5选择第几位亮
//IOB8---IOB15显示数字
//========================================================
voidF_numLED_Ctrl(intiBit,intiNum)
{
inti,j,k=0;
*P_IOB_Dir=0x00ff|*P_IOB_Dir;
*P_IOB_Attrib=0x00ff|*P_IOB_Attrib;
*P_IOB_Data=0xFF00&*P_IOB_Data;
*P_IOB_Data=0;
*P_IOB_Data=(0x1<*P_IOB_Dir=0xff00|*P_IOB_Dir;
*P_IOB_Attrib=0xff00|*P_IOB_Attrib;
*P_IOB_Data=0x00ff&*P_IOB_Data;
*P_IOB_Data=ciNum[iNum]|*P_IOB_Buffer;
ClearWDog;
}
//========================================================
//文件名称:
key.c
//描述:
建立数码管显示模块
//========================================================
#defineClearWDog(*((volatileunsignedchar*)0x7012))=1
#defineP_IOA_Data(volatileunsignedint*)0x7000
#defineP_IOA_Buffer(volatileunsignedint*)0x7001
#defineP_IOA_Dir(volatileunsignedint*)0x7002
#defineP_IOA_Attrib(volatileunsignedint*)0x7003
#defineP_IOA_Latch(volatileunsignedint*)0x7004
#defineP_IOB_Data(volatileunsignedint*)0x7005
#defineP_IOB_Buffer(volatileunsignedint*)0x7006
#defineP_IOB_Dir(volatileunsignedint*)0x7007
#defineP_IOB_Attrib(volatileunsignedint*)0x7008
//========================================================
//函数名称:
F_Key_Ctrl()
//描述:
控制数码管显示
//出口:
键值
//========================================================
intF_Key_Ctrl()
{
inti=0,j=100,k[3],key=0;
//for(i=0;i<200;i++);
k[0]=*P_IOA_Dir;
k[1]=*P_IOA_Attrib;
k[2]=*P_IOA_Buffer;
*P_IOA_Dir=0x00ff|*P_IOA_Dir;
*P_IOA_Attrib=0x00ff|*P_IOA_Attrib;
*P_IOA_Data=0x0000|*P_IOA_Buffer;
for(i=0;i<10;i++);
key=*P_IOA_Data&0x00ff;
while(j)
{
}
*P_IOA_Dir=k[0];
*P_IOA_Attrib=k[1];
*P_IOA_Data=k[2];
returnkey;
}
//========================================================
//文件名称:
ISR.c
//描述:
建立中断服务程序
//========================================================
#defineP_INT_Clear(volatileunsignedint*)0x7011
#defineP_INT_Ctrl(volatileunsignedint*)0x7010
#defineClearWDog(*((volatileunsignedchar*)0x7012))=1
externstructclock*clkset;
externstructclocka;
#include"hardware.h"
unsignedinti=0,j=0,k=0,sensor2=0,flag,minute=0,guest=0;
externPlayFlag,iShow[4],key,iCounter;
voidBREAK(void)__attribute__((ISR));
voidBREAK(void)
{
}
voidFIQ(void)__attribute__((ISR));
voidFIQ(void)
{
if(*P_INT_Ctrl==0x2000)
{
*P_INT_Clear=0x2000;
}
}
voidIRQ0(void)__attribute__((ISR));
voidIRQ0(void)
{
}
voidIRQ1(void)__attribute__((ISR));
voidIRQ1(void)
{
}
voidIRQ2(void)__attribute__((ISR));
voidIRQ2(void)
{
}
voidIRQ3(void)__attribute__((ISR));
voidIRQ3(void)
{
}
voidIRQ4(void)__attribute__((ISR));
voidIRQ4(void)
{
i++;
if(i>=3)
{
F_numLED_Ctrl(j,iShow[j]);
j++;
if(j==3)j=0;
i=0;
}
*P_INT_Clear=0x0040;
}
voidIRQ5(void)__attribute__((ISR));
voidIRQ5(void)
{
if(*P_INT_Ctrl&0x0004)
{
*P_INT_Clear=0x0004;
iCounter++;//计数
if(iCounter>=200)iCounter=0;//超出范围则清零
}
}
voidIRQ6(void)__attribute__((ISR));
voidIRQ6(void)
{
}
voidIRQ7(void)__attribute__((ISR));
voidIRQ7(void)
{
}