单片机课程设计电子秒表设计.docx
《单片机课程设计电子秒表设计.docx》由会员分享,可在线阅读,更多相关《单片机课程设计电子秒表设计.docx(11页珍藏版)》请在冰豆网上搜索。
![单片机课程设计电子秒表设计.docx](https://file1.bdocx.com/fileroot1/2022-10/8/b99ae258-49b1-46a0-a2b2-0e87b207724c/b99ae258-49b1-46a0-a2b2-0e87b207724c1.gif)
单片机课程设计电子秒表设计
单片机原理及系统课程设计
摘要
本设计是一个基于单片机的电子秒表设计。
设计采用AT89C51单片机和四位一体的LED数码管,通过单片机内部定时器/计数器定时的原理来达到秒表的计时功能。
设计中秒表的开始,暂停功能是通过控制单片机内部定时器的打开与关闭来实现的。
最后采用proteus仿真软件将软件与硬件相结合来模拟实现秒表的各项功能。
关键词:
单片机;秒表;功能
Abstract
Thisdesignisamicrocontroller-basedelectronicstopwatchdesign.DesignusingAT89C51microcontrollerandfour-in-oneLEDdigitaltube,throughthemicrocontrollerinternaltimer/countertimingprincipletoachieveastopwatchtimingfunction.Designofthestopwatchtostart,pausefunctionisachievedbyopeningandclosingofthecontrolmicrocontrollerinternaltimer.Finally,proteussimulationsoftwaretosoftwareandhardwarecombinationtosimulatethevariousfunctionsofthestopwatch.
Keyword:
SCM,Stopwatch,functions
基于单片机的秒表设计
1引言
随着现代科技的发展,自动化理念已经深入到了人们生活的各个领域。
本课程设计是在学习先修课程《单片机原理与系统设计》之后,为加强对学生系统设计和应用能力的培养而开设的综合设计训练环节。
本设计是一个基于单片机的电子秒表设计,要求实现开始,暂停与复位功能。
精确度为0.1s,最大计时时间为999.9s。
设计结合了软件和硬件的一些相关知识。
通过软件编写,硬件调试及仿真来实现。
提高了大家的动手能力,做到了学以致用。
2设计方案及原理
2.1设计方案
本设计通过单片机内部定时计数的原理来实现电子秒表的功能。
首先将计数初值设定为19664,当计数溢出后便会产生一个中断,继而执行中断程序,当中断次数达到两次则表示0.1秒时间到,以此类推便可扩展到1秒,10秒等。
三个按键功能用软件查询即可实现,通过对定时器的打开和关闭来实现秒表的开始和暂停,在设计中我用一个键来控制开始和暂停,方法是每次扫描到该按键按下后便对TR位取反。
用另一个按键来控制秒表的清零功能,方法是当检测到该按键被按下后便使num=0,从而使数码管显示为零。
2.2系统框图
系统框图如图1所示。
图1系统结构框图
2.3系统原理
该系统在工作时从头开始执行程序,首先扫描是否有键按下,如果没有扫描到按键信号,则系统一直执行循环函数;当扫描到有按键信号输入后单片机便开始执行按键子程序,然后依次由P0口和P2口送出相应的段选信号和位选信号,从而点亮数码管,显示当前的计数值。
3硬件设计
3.1芯片选择
在本设计中我采用了AT89C51单片机。
3.2硬件连接方法
由于该设计要求数码管显示,所以我选用P0口作为段选端,但是P0口内部没有上拉电阻,因此不能输出正常的高低电平,所以外接了一个九脚10K的排阻,排阻的公共端接单片机Vcc。
用P2.4~P2.7分别接数码管的1,2,3,4四个位选端。
用P3.4,P3.5口分别接两个开关,开关另一端接低电平(地),当按下后便会有一个低电平输入。
用XTAL1与XTAL2外接一个11.0592MHZ的晶振电路,为单片机工作提供时钟脉冲。
在RST口外接一个复位电路,实现单片机的复位功能。
硬件原理连接图如图2所示。
3.3硬件原理图
硬件连接图如图2所示。
图2硬件连接原理图
由图可知这个系统由单片机最小系统,四位一体数码管,排阻以及限流电阻等元件组成。
其中单片机外部晶振为单片机提供11.0592MHZ的时钟脉冲。
单片机的P0口为数码管提供段选信号,P2.4~P2.7口为数码管提供位选信号。
两个按钮一端分别接单片机的P3.4与P3.5口,另一端接地,按下时为单片机输入低电平。
4软件设计
4.1程序流程图
在本设计中程序部分是由主程序和子程序构成的,主程序流程图如图3所示。
子程序流程图如图4所示。
图3主程序流程图图4显示子程序流程图
4.2程序结构
本设计在软件方面我用C语言编程,程序共分为了三大模块:
按键模块,显示模块与计数模块。
其中按键模块与显示模块是用软件查询的方式来完成的,计数模块是用中断的方式来完成的。
按键模块是一用个keyscan()函数来实现的,其中用了两个按键key1与key2,key1用来给秒表清零,key2用来控制秒表的开始和暂停功能。
显示模块式用一个display()函数来实现的,在程序开头定义了一个codetable[]数组,内部元素为0到9的共阴极数码管代码,通过查询数组的方式来点亮数码管。
计数模块是用一个中断服务程序来完成的,用单片机内部的定时器/计数器来计数,设定一个合适的初值即可实现计数功能。
5仿真调试
5.1问题分析
在仿真过程中遇到了很多问题,这些问题主要集中在软件方面。
首先是数码管的显示错误,经测试发现数码管的显示代码输入有误。
然后在扩展的小数点不会一直显示,后来将烧亮小数点的程序放入循环中问题就解决了。
5.2仿真结果
设计完成后我在proteus中进行了仿真,仿真结果如图4所示。
图4仿真结果
6实物调试
6.1问题分析
由于电路板是自己焊接的,所以在刚开始调试的时候出现了很多问题。
首先是数码管B段始终不亮,因此我猜测是线路接触不良,然后我用万用表将连接B段的每一条线路都测了一遍,最后发现是控制数码管B段的单片机接口与限流电阻未接触而导致的,经过重新焊过以后问题就解决了。
然后还有一个问题是数码管的E段与F段总是显示混乱,后经过万用表测试发现是这两段在焊接是发生了短路。
6.2调试结果
仿真成功后通过仿真结果焊接了一个实物,实物调试结果如图5所示。
图5实物调试
7总结
本设计结合了软件和硬件的一些相关知识。
在硬件方面,用到了一个单片机最小系统板,一个四位一体的七段LED数码管,一个九脚10K的排阻,八个460欧姆的电阻。
其中数码管用来作为显示工具;九脚10K的排阻作为P0口的上拉电阻;八个460欧姆的电阻作为限流电阻,以防通过数码管电流过大而被被烧坏。
在软件方面我用C语言编程,程序共分为了三大模块:
按键模块,显示模块与计数模块。
其中按键模块与显示模块是用软件查询的方式来完成的,计数模块是用中断的方式来完成的。
按键模块是一用个keyscan()函数来实现的,其中用了两个按键key1与key2,key1用来给秒表清零,key2用来控制秒表的开始和暂停功能。
显示模块式用一个display()函数来实现的,在程序开头定义了一个codetable[]数组,内部元素为0到9的共阴极数码管代码,通过查询数组的方式来点亮数码管。
计数模块是用一个中断服务程序来完成的,用单片机内部的定时器/计数器来计数,设定一个合适的初值即可实现计数功能。
参考文献
[1]王思明,张金敏,苟军年等.单片机原理及应用系统设计[M].北京:
科学出版社,2012.
[2]郭天祥.51单片机C语言教程[M].北京:
电子工业出版社,2009.
附录A源程序
#include//52系列单片机头文件
#defineucharunsignedchar//宏定义
#defineuintunsignedint
sbitN0=P2^4;
sbitN1=P2^5;//申明U1锁存器的锁存端
sbitN2=P2^6;
sbitN3=P2^7;
sbitkey1=P3^4;
sbitkey2=P3^5;
ucharcodetable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
voiddelayms(uint);//声明延时函数
voiddisplay(uchar,uchar,uchar,uchar);//声明显示函数
voidkeyscan();//声明按键函数
uintnum,num3;
ucharnum1,num2,qian,bai,shi,ge;//变量声明
voidmain()//主函数入口
{
TMOD=0x11;//设置T0,T1定时器
TH1=(65536-45872)/256;
TL1=(65536-45872)%256;
EA=1;//开总中断
ET1=1;//开启定时器T1中断
TR1=0;
while
(1)//程序停在这里等待中断的发生,这个大循环也是实现数据显示的主体循环
{
keyscan();
qian=num3/1000;
bai=(num3-qian*1000)/100;
shi=(num3-1000*qian-100*bai)/10;
ge=num1;
P0=0x80;
N2=0;
delayms(5);
N2=1;
P0=0x00;
display(qian,bai,shi,ge);
}
}
voiddisplay(ucharqian,ucharbai,ucharshi,ucharge)//数码管显示子函数
{
P0=table[qian];
N0=0;
delayms(5);
N0=1;
P0=0x00;
P0=table[bai];
N1=0;
delayms(5);
N1=1;
P0=0x00;
P0=table[shi];
N2=0;
delayms(5);
N2=1;
P0=0x00;
P0=table[ge];
N3=0;
delayms(5);
N3=1;
P0=0x00;
}
voiddelayms(uintxms)//延时子函数
{
uinti,j;
for(i=xms;i>0;i--)//i=xms即延时约xms毫秒
for(j=110;j>0;j--);
}
voidT1_time()interrupt3//定时器T1,中断序号为3
{
TH1=(65536-45872)/256;//重装初值
TL1=(65536-45872)%256;
num2++;
if(num2==2)//如果到了2次,说明0.1秒的时间到
{
num2=0;//然后把num2清零重新再计2次
num1++;
if(num1==10)
num1=0;
num++;
if(num==1000)
num=0;
num3++;
if(num3==10000)
num3=0;
}
}
voidkeyscan()//按键子函数
{
if(key1==0)//清零
{
delayms(5);//延时去抖
if(key1==0)
{
while(!
key1)//等待按下
{
TR1=1;//定时器TR1打开
num3=0;
num1=0;//送数据num=0
TR1=0;//定时器