51单片机秒表计时器课程设计报告(含C语言程序)

XXXXXX学院

 51单片机系统设计 课程设计报告

题     目:          秒表系统设计         

专业、班级:                               

学生姓名:                                 

学    号:                                 

指导教师:                                

分    数 :                                

[摘要]本设计是一个秒表计时器,采用51单片机实现。电路包括以下几部分:单片机最小系统部分,数码管显示部分,摁键开关部分部分。电路选用共阴型4位数码管组成时钟显示电路;时钟的增减控制以及清零部分主要由轻触开关构成的摁键系统组成;信号接收和处理部分主要由单片机来执行。接通电源后,秒表计时器处于初始状态,4位数码管显示000.0。当摁下“开始”开关时,秒表开始计时,数码管显示当前状态的时间。当再次摁下开关时,数码管停止计时。摁下“清零”键后,系统重新回到初始状态。

[关键词]   单片机最小系统  秒表  计时  摁键控制

任务书

1、任务

    设计一个秒表计时器,在51单片机的控制作用下,采用4个LED数码管显示时间,计时范围设置为00.0~60.0秒,即精确到0.1秒,用按键控制秒表的“开始”、“暂停”、“复位”,按“开始”按键,开始计时;按“暂停”按键,系统暂停计时;再按“开始”键,系统继续计时;数码管显示当前计时值;按“复位”按键,系统清零。

2、设计要求

(1)开始时显示00.0。每按下S1键一次,数值加1s;

(2)每按下S2键一次,数值减1s;

(3)每按下S3键一次,数值清零;

(4)每按下S4键一次,启动定时器使数值开始自动每秒加1,

再次按下S4键,数值停止自动加1,保持显示原数。

3、发挥部分

(1)开关按键3:“复位 60.0” 按键(用来60秒倒计时)。按键按下去时数码管复位为“60.0”(用于倒计时)。

(2)开关按键4:倒计时“逐渐自减”按键。按键按下去则是数码管开始“逐渐自减”倒计时。

(3)开关按键5:倒计时初始值“增加”按键。

(4)开关按键6:倒计时初始值“减小”按键。

4、课程设计的难点  

单片机电子秒表需要解决三个主要问题,一是有关单片机定时器(一个控制顺序计时,一个控制倒计时)的使用;二是如何实现 LED 的动态扫描显示;三是如何对键盘输入进行编程。

5、课程设计仪器

集成电路芯片STC89C52,八段数码管,MCS-51系列单片机微机仿真课程系统中的软件(keil uvision2)。

目  录

摘要 ……………………………………………………………………………2

关键词 …………………………………………………………………………2

任务书 …………………………………………………………………………3

1、 设计任务目的 ……………………………………………………………5

2、 设计方案选取与论证 ……………………………………………………5

2.1 系统总体设计方案 ……………………………………………………5

2.2 系统整体框图 …………………………………………………………5

3、 电路设计 …………………………………………………………………6

3.1  单片机最小系统设计 ……………………………………………6

3.2  数码管显示模块设计 ……………………………………………6

3.3  摁键控制系统模块设计 …………………………………………6

     3.4  程序设计 …………………………………………………………6

4、 制作及调试过程 …………………………………………………………11

5、 结果分析和总结 …………………………………………………………12

参考文献 ………………………………………………………………………12

附录a 秒表计时器原理图  …………………………………………………13

附录b 元器件清单  …………………………………………………………14

附录c 秒表计时器实物图  …………………………………………………15

1、设计任务目的

1.   根据单片机课程所学内容,结合其他相关课程知识,设计电子秒表,以加深对单片机知识的理解,锻炼实践动手能力,为以后的毕业设计和工作打下坚实基础;

2.   熟悉汇编语言或C语言的程序设计方法,熟悉51系列单片机的使用;

3.   掌握单片机的内部功能模块的应用,如定时器/计数器、中断、I/O口、串行口通讯等功能;

4.   掌握单片机应用系统的软硬件设计过程、方法及实现。

2、 设计方案选取与论证

2.1系统总体设计方案

使用STC89C51单片机作为核心控制部件,采用12M晶体振荡器及30PF微小电容构成振荡电路;用1个四位一体共阴极数码显示管作为显示部分,构成数字式秒表的主体结构,配合独立式键盘和复位电路完成此秒表的计时、清零、停止、增减初始时间等各项功能。

2.2 系统总体整体框图

 


图2.2 系统设计框图

3、 电路设计

3.1 单片机最小系统设计

图3.1 单片机最小系统

1. 时钟电路 

在XTAL1、XTAL2 的引脚上外接定时元件(一个石英晶体和两个电容),内部振荡器便能产生自激振荡。在本设计中采用的12M 的石英晶振。和晶振并联的两个电容的大小对振荡频率有微小影响,可以起到频率微调作用。当采用石英晶振时,电容可以在20 ~ 40pF 之间选择。 

2. 复位电路 

复位操作通常有两种基本形式:上电自动复位和开关复位。上电瞬间,电容两端电压不能突变,此时电容的负极和RESET 相连,电压全部加在了电阻上, RESET 的输入为高,芯片被复位。随之+5V电源给电容充电,电阻上的电压逐渐减小,最后约等于0,芯片正常工作。并联在电容的两端为复位按键,当复位按键没有被按下的时候电路实现上电复位,在芯片正常工作后,通过按下按键使RST管脚出现高电平达到手动复位的效果。

3. EA/VPP(31 脚) 的功能和接法 

51 单片机的EA/VPP(31 脚) 是内部和外部程序存储器的选择管脚。当EA 保持高电平时,单片机访问内部程序存储器; 对于现今的绝大部分单片机来说,其内部的程序存储器(一般为flash)容量都很大,因此基本上不需要外接程序存储器,而是直接使用内部的存储器。 

4. P0 口外接上拉电阻 

51 单片机的P0 端口为开漏输出,内部无上拉电阻。所以在当做普通I/O 输出数据时,由于V2 截止,输出级是漏极开路电路,要使“1”信号(即高电平)正常输出,必须外接上拉电阻。

3.2  数码管显示模块设计

显示部分采用动态显示。数码管动态显示接口是单片机中应用最为广泛的一种显示方式之一,动态驱动是将所有数码管的8个显示笔划"a,b,c,d,e,f,g,dp"的同名端连在一起,另外为每个数码管的共阴极增加位选通控制电路,位选通由各自独立的I/O线控制,当单片机输出字形码时,所有数码管都接收到相同的字形码,但究竟是那个数码管会显示出字形,取决于单片机对位选通端电路的控制,所以我们只要将需要显示的数码管的选通控制打开,该位就显示出字形,没有选通的数码管就不会亮。通过分时轮流控制各个数码管的位选通端,就使各个数码管轮流受控显示,这就是动态驱动。动态显示是利用人眼视觉暂留特性来实现显示的。事实上,显示器上任何时刻只有一个数码管有显示。由于各数码管轮流显示的时间间隔短、节奏快,人的眼睛反应不过来,因此看到的是连续显示的现象。为防止闪烁延时的时间在1ms左右,不能太长,也不能太短。

3.3  摁键控制系统模块设计

由P1口作为独立摁键信号的输入端控制时钟的加1s、减1s、复位60.0s等操作。用外部中断0作为秒表计时器的开启和暂停的操作。且所有摁键均为低电平有效。其中部分摁键为单刀双掷开关用于控制增计时或减计时以及限60.0s计时和60.0s外计时。

3.4 程序设计如下:

#include<reg52.h>   //包含52单片机寄存器定义的头文件

unsigned char Tab1[ ]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};  //段码表

unsigned char Tab2[ ]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};     //个位段码表

unsigned int x;

unsigned char k;

sbit int0=P3^2;

sbit int1=P3^3;

sbit SUB60=P1^1;

sbit S60=P1^2;

sbit K5=P1^3;

sbit K6=P1^4;

sbit K7=P1^5;

sbit K8=P1^6;

/***************************延时1ms基准******************************************/

void delay1ms(unsigned int i)

{

 unsigned char j;

 while(i--)

 {

 for(j=0;j<125;j++)      //1ms基准延时程序 12MHZ晶振

 {

  ;

 }

 }

}

/********************************************************************************

******************数码管显示程序 ***********************************************/

void Display(unsigned int x)

{       

       P2=0xfe;        //P2.0引脚输出低电平,DS6点亮

    P0=Tab1[x/1000];   //显示百位

    delay1ms(6);

      

       P2=0xfd;        //P2.1引脚输出低电平,DS6点亮

    P0=Tab1[x%1000/100];   //显示十位

    delay1ms(6);

      

       P2=0xfb;        //P2.2引脚输出低电平,DS6点亮

    P0=Tab2[x%100/10];   //显示个位

    delay1ms(6);

    P2=0xf7;      //P2.3引脚输出低电平,DS7点亮

    P0=Tab1[x%10];  //显示0.1位

     delay1ms(6);

       P2=0xff;

 }

/*******************************************

函数功能:主函数

******************************************/     

void main(void)

{    

          x=0;

          TMOD=0x01;    // TMOD=0000 0001B,使用计数器T0的工作方式1

       EA=1;         //开起总中断

          ET0=1;        //允许定时器T0的中断

          EX0=1;       //允许外中断INT0

          IT0=1;        //INT0为下负脉冲触发方式

         

          TH0=(65536-50000)/256;       //计数器T0高8位赋初值

          TL0=(65536-50000)%256;              //计数器T0低8位赋初值

          TF0=0;          //溢出标志位清零

while(1)

{

/************************************************************

****************K5 P1.3按一次加1开关S1***************************/     

         if(K5==0)

         {

          delay1ms(20);

          if(K5==0)

          {

           x=x+10;        

          }

         while(!K5);      //摁键关断    摁一次触发一次

         }  

/***********************************************************

************K6 P1.4按一次减1开关S2**************************/ 

         if(K6==0)

         {

          delay1ms(20);

          if(K6==0)

              {

                 if(x==0)

                 {

                 x=10;               //在00.0的时候停止

                 }                      

               x=x-10;                    

                 }

         while(!K6);             //摁键关断      摁一次触发一次

              }                

/*********************************************************************

******************K7 P1.5初始值 赋值为60.0秒开关S5********************/

      if(K7==0)

         {

          delay1ms(20);

          if(K7==0)

          {

              x=600;                               //赋初值60.0秒

              }

         while(!K7);             //摁键关断      摁一次触发一次

           }       

/*********************************************************************

******************S60 控制60S停止开关 P1.2****************************/

if(x==600)

              {

               if(S60==0)   //如果P1.2口是低电平,秒表变化范围00.0~60.0

               {

               TR0=0;

               }

              }

/********************************************************************

******************K8 P1.6清零clear0摁键开关S3************************/

if(K8==0)

 {

  delay1ms(20);                      //延时消震

  if(K8==0)

  {  

  x=0;                                      //数据清0 数码管显示000.0

  TR0=0;                                //溢出标志位清0

  }

 }

/************数码管显示***************************************/     

         Display(x);       

         }

}

/**********INT0中断函数 用于开始或暂停开关S4******************

**************************************************************/

void begin_stop() interrupt 0

{

 if(int0==0)

 {

  delay1ms(30);   //延时消震

 if(int0==0)

  {

  TR0=~TR0;              //按键摁一次 读秒开始或暂停

   if(x==0&&SUB60==0)

         {

          TR0=0;     

       }

  }

 }

}

/*********************************************************

******T0 计数器中断 控制每隔加0.1秒***********************/

 void add_one0() interrupt 1

 {

  k++;

  if(k==2)

        {    

         k=0;

         TF0=0;

         if(SUB60==1)          //当P1.1口是高电平时秒表加0.1s

                                         //当P1.1口是低电平时秒表减0.1s

          {

          x=x+1;                   //秒表加0.1s

          }

         else

         {

          x=x-1;                     //秒表减0.1s

         }

         if(x==0)

         {

          TR0=0;     

         }

         if(x==9999)

         {

          TR0=0;

         }

        }

   TH0=(65536-50000)/256;       //计数器T0高8位赋初值

   TL0=(65536-50000)%256;              //计数器T0低8位赋初值

 }

4、 制作及调试过程

4.1 电路的制作

(1) 分析各单元电路图,并分析其各部分的功能;

(2) 用仿真软件仿真电路的功能,并检查是否有错,无误后进行下步工作;

(3) 查找有关文献了解各元件的功能及引脚和有关的资料;

(4) 分别焊接单片机最小系统、数码管显示电路和摁键控制电路,与此同时检查各元器件是否可用,并分辨其引脚;

(5) 对照事先设计好的原理图仔细检查在实物中是否有接错的地方(主要检查集成电路的引脚与导线是否出错接错和是否出现了短路),若发现有,就立即改正。以防给实物通电之后,出现意外。然后,用数字万用表检测实物中是否有不导通的地方,若有,应立即修正。以防通电后不能工作,而怀疑其他地方出错。

(6) 给实物通电,并进行调试。看电路工作是否正常。若有误,则检查并思考错误原因,然后进行修改直至电路工作正常为止。

4.2 电路的调试

起初我打算用PCB板来做秒表计时器,由于一些条件也不允许(如腐蚀液和钻孔机等器件没有),经过再三考虑,我选择了用万用板来制作秒表计时器。但在制作的过程中我也遇到了许多问题。问题以及解决办法如下:

(1) 问题1:由于在焊电子元件及芯片时没有注意到元件的排布以及芯片的引脚问题,使得电路板上的跳线很密,这给查线带来了很大的困难,使得最后电路错线、搭线太多。

解决办法:我把元件以及跳线重新都焊了下来,认真反复的研究原理图的每个芯片的引脚,先用油性笔在电路板上把元件画好,然后在进行焊接。

(2)问题3:芯片引脚分布的比较紧密,所以在焊接时出现焊锡把相邻引脚连接在一起的情况。

解决办法:吸焊器取掉部分焊锡,或用小刀划开芯片引脚的分界。

(5)问题5:倒计时不能够正常的工作,且减计时混乱。

     解决办法:重新检查程序,检查电路是否搭线。

    

5、 结果分析和总结

单片机课程设计,是对单片机知识的验证,可以帮助我们理解巩固所学知识,激发我们对单片机课程的兴趣,更锻炼了我们独立思考、开拓创新的能力。通过这次课程设计我也发现了自身存在的不足之处,虽然感觉理论上已经掌握,但在运用到实践的过程中仍有意想不到的困惑,经过一番努力才得以解决。这也激发了我今后努力学习的兴趣,我想这将对我以后的学习产生积极的影响。 其次,这次课程设计让我充分认识到合作的重要性,只有合作才能保证整个项目的有条不絮。在设计过程中,非常感谢同学们的指导,才使设计进展的比较顺利。 另外在课程设计的过程中,当我们碰到不明白的问题时,指导老师总是耐心的讲解,给我的设计以极大的帮助,使我获益匪浅。因此非常感谢张慧老师的教导。 通过这次设计,我懂得了学习的重要性,了解到理论知识与实践相结合的重要意义,学会了坚持、耐心和努力,这将为自己今后的学习和工作做出了最好的榜样。

6、参考文献 

[1] 郭天祥.51单片机C语言教程.北京:电子工业出版社,2009

[2] 胡汉才.单片机原理及系统设计.北京:清华大学出版社,2002

[3] 何希才.新型集成电路应用实例[M].北京:电子工业出版社,2002. 

[4] 公茂法.单片机接口实例集.北京:西安电子科技大学出版社,2004 

[5]51系列单片机设计实例:北京航空航天大学出版社,2003.3

附录a 电路原理图

附录b:元器件清单

附录c:秒表计时器实物图

相关推荐