51单片机电子秒表设计Proteus.docx
- 文档编号:12570563
- 上传时间:2023-04-20
- 格式:DOCX
- 页数:10
- 大小:32.20KB
51单片机电子秒表设计Proteus.docx
《51单片机电子秒表设计Proteus.docx》由会员分享,可在线阅读,更多相关《51单片机电子秒表设计Proteus.docx(10页珍藏版)》请在冰豆网上搜索。
51单片机电子秒表设计Proteus
51单片机电子秒表设计(Proteus)
简易秒表设计
单片机硬件设计结课论文
专业:
计算机科学与技术
学生姓名:
学号:
1307064248
完成时间:
2020年12月28日
一、简述
此秒表主要实现的功能是利用单片机内部定时计数器实现计时,然后通过LED组件显示出来。
因为这次设计时使用的是并排的6个数字显示LED,所以在计时时精确到10ms,最大即时59分59秒99。
实现过程中的主要部分包含显示和定时。
因为该LED与单片机相接的引脚只有14个,其中8个接在P0口上实现字形的显示,剩下的6个接在P2口用于选择6个数字型LED中的一个显示,所以每次只能显示一个数字。
要实现多个数字的显示需要快速显示每个LED,利用人的视觉差来实现多个数字同时显示。
计时只用到定时计数器T1(因为需要配合中断优先级,故没有使用T0,下文会详细讲到)。
另外还用到了两个按键,和两个LED灯(红、绿)。
按键用于控制开始计时和暂停、重置,LED灯用于指示当前工作状态。
二、主要工具
KeiluVision3,ISIS7Professional,AT89C51基础组件(试验箱)。
三、线路连接图(ISIS7Professional环境)
四、实现细则
显示电路
数字型LED的实现原理为每个单元(共6个单元)含8个发光独立的LED灯,其中7个构成“8”字形,剩下的一个为小数点。
6个单元的每个相同位置引脚并联起来,最后通过8根线连接到单片机的P0口。
因此如果不把另外6根线连接上,每次通过P0口输出值时6个显示单元都会显示相同的图形(数字)。
LED单元组中另外6根引脚连接到单片机上,实现“按位显示”,并且是低电平选择,例如“111101”对应显示的是从右到左的第5个LED单元。
为了同时显示多个数字,需要快速地将六个单元中的内容轮流显示,重复这个过程直到产生中断,即定时中断和外部中断。
为了配合人的视觉误差,我在程序中的实现方式是:
每个单元显示2ms,然后熄灭1ms。
具体代码详见(五、程序)。
定时计数器
定时计数器T1的初值是D8F0H,对应计时时间是10ms,即该秒表能显示计时的最小单位。
当产生中断时程序显示10ms的那一个LED单元会不断的重复显示0~9,而程序会根据该值来判断是否需要进位,依次类推,每一位变化时程序都会判断高位显示的数字是否需要变化。
简易秒表上有两个按键,分别表示开始/暂停/继续当前计时和重置秒表,在按下第一个按键时会触发INT0中断,随即通过改变程序中的一个参数来改变程序的走向。
例如当在初始状态下按下开始按钮,系统会将k1_count赋值为1,表示为需要秒表开始运行,当程序检测到该值变化时会立即执行该操作。
另外一个按键的实现原理与一致。
因此在设置中断的时候计时器中断优先级最低,为的是两个外部中断能打断计时。
五、程序
#include
unsignedinttable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//0~9数字字样对应十六进制数
unsignedintplace[]={0x1f,0x2f,0x37,0x3b,0x3d,0x3e};//对应六个LED位置0~5
unsignedintdoc[]={0x3f,0x3f,0x3f,0x3f,0x3f,0x3f};//存放每个位置需要显示的数
unsignedchart=0;
unsignedintcount[6]={0,0,0,0,0,0};//用于每个位的计数,实现满10进位或者满6进位
unsignedintk1_count=0;//对按键k1计数,用于识别按下按键所需要进行的操作
//各个函数的声明
voidreset();
voidinitDoc();
voidinitCount();
voidsuspend();
voidinit();
voidtimerRun();
voiddelay1ms(void)//延迟一毫秒
{
unsignedchara,b;
for(a=199;a>0;a--)
for(b=1;b>0;b--);
}
voidinitDoc()//初始化doc,使每个LED都初始显示数字0
{
unsignedinti;
for(i=0;i<6;i++)
doc[i]=table[0];
}
voidinitCount()//初始化计数器,每一位初始值为0
{
unsignedinti;
for(i=0;i<6;i++)
count[i]=0;
}
voiddisplay()//将当前doc中存放的数组显示出来
{
unsignedinti;
for(i=0;i<6;i++)
{
P0=doc[i];
P2=place[i];
delay1ms();
delay1ms();
P0=0x00;
delay1ms();
}
}
voidrun()//实现计数值进位的函数
{
unsignedchari;
if(count[0]<9)
count[0]++;
else
{
count[0]=0;
count[1]++;
if(count[1]>9)
{
count[1]=0;
count[2]++;
if(count[2]>9)
{
count[2]=0;
count[3]++;
if(count[3]>6)
{
count[3]=0;
count[4]++;
if(count[4]>9)
{
count[4]=0;
count[5]++;
if(count[5]>6)
count[5]=0;
}
}
}
}
}
for(i=0;i<6;i++)
{
doc[i]=table[count[i]];
}
}
voidt1(void)interrupt3//为T2定时计数器设置中断
{
TH1=0xd8;
TL1=0xf0;
run();
}
voidint_int0(void)interrupt0//为INT0设置中断
{
if(k1_count==0)
k1_count=1;
else
k1_count=0;
}
voidint_int1(void)interrupt2//为INT1设置中断
{
k1_count=2;
}
voidtimerRun()//使秒表继续运行,初值为此时doc和count中存放的值
{
P1=0x02;
TMOD=0x10;
TR1=1;
ET1=1;
EA=1;
while(k1_count==1)
{
display();
}
if(k1_count==0)
suspend();
if(k1_count==2)
{
reset();
}
}
voidinit()//初始化秒表
{
P1=0x01;
initDoc();
IT0=1;
EA=1;
EX0=1;
IT1=1;
EX1=1;
while(k1_count==0)
{
display();
}
if(k1_count==1)
{
timerRun();
}
}
voidsuspend()//当按下暂停键时需要执行的挂起操作
{
P1=0x01;
TR1=0;
while(k1_count==0)
{
display();
}
if(k1_count==1)
{
timerRun();
}
elseif(k1_count==2)
{
reset();
}
}
voidreset()//当按下重置键是执行的重置操作
{
P1=0x01;
TR1=0;
initDoc();
initCount();
IT0=1;
EA=1;
EX0=1;
IT1=1;
EX1=1;
k1_count=0;
while(k1_count==0)
{
display();
}
if(k1_count==1)
{
timerRun();
}
if(k1_count==2)
reset();
}
voidmain()//主函数,从初始化秒表开始执行
{
init();
}
六、模拟运行截图
七、心得体会
本次课程设计我选择的题目较为简单,所用到的组件也不多,但是实现起来的难度超出了我的想象,一方面是不熟悉Proteus的环境和使用方法,另一方面是自己对单片机内部的工作方式不够了解。
因此,这次硬件设计让我发现了自己学科知识的不足,知道了自己以后将如何巩固知识、查缺补漏。
同时,这次硬件设计也给我提供了一些宝贵的经验,相信以后再面临类似的课题时会容易许多。
另外,简易秒表在运行过程中会产生一定的误差,这与轮换扫描LED显示有关,要改进这个程序可以使用独立的LED数字显示单元,并且使用更多的端口。
实现程序以及线路连接都会较现有的复杂许多,以后我会在其他课题中加以尝试。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 51 单片机 电子 秒表 设计 Proteus