单片机编程设计一个秒表_单片机按键触发式数字秒表编程 - CSDN
  • 利用51单片机制作一个秒表的详细过程 前面的话: 和很多朋友一样,在学51单片机的过程中我们肯定会涉及到制作一个秒表,牵涉到把单片机的多个部分组合起来使用,这对于我们初学者来说可能显得有些困难,我同大家...
    利用51单片机制作一个秒表的详细过程

    前面的话:

    和很多朋友一样,在学51单片机的过程中我们肯定会涉及到制作一个秒表,牵涉到把单片机的多个部分组合起来使用,这对于我们初学者来说可能显得有些困难,我同大家一样,百思不得其解,最后头都弄大了才把这个秒表制作出来,为了给以后的朋友们一些思路,一些参考,所以在这里我把自己制作的整个详细过程整理出来供大家参考。我调试出来是没有问题的,各方面都稳定运行,由于我水平有限,中间可能会有不对的地方,欢迎大家指正,我们一起学习,一起进步!

    我将分为三个部分来介绍:1.整体思路,2.硬件电路方面,3.软件编程方面。


    1.整体思路

    利用51单片机制作秒表时,我介绍精确到十分位(即0.1s)的制作,并让其拥有启动,暂停,复位三个功能。
    用到的单片机部分:定时器部分,独立按键的检测与应用,数码管的显示,并结合一些简单的程序即可实现。
    用5位数码管来进行显示,分别显示秒的十分位,秒的个位,秒的十位,分的个位,分的十位。用定时器定时50ms,2个定时器中断即是0.1s,即秒的十分位,20个定时器中断即是1s,60个1s即是1分钟,通过程序将5位数码管的值分离出来,并进行显示。这就是我在数码管显示方面的思路,如果不是太清楚,结合我下面软件编程方面的程序来看你可能就会明白,我会在那部分做详细介绍,看完了可能你就懂了。
    利用独立按键设置启动/暂停键和清零键,利用独立按键的检测,若启动/暂停按键按下,秒表则启动或者暂停,按下复位键,秒表清零复位。我在程序后面全都有注释,不用担心。看完你就会明白了。
    这是我制作的的流程图:




    “ms100”表示秒的十分位,"s"表示秒的个位,“s1”表示秒的十位,“min”表示分的个位,“min1”表示分的十位。
    “cnt”表示秒的计数位,即多少个一秒,定时满一秒加1,“minu”表示分的计数位,即多少个一分钟,一分钟加1,
    这个流程图提供了大致思路,要结合下面的程序部分一起看。可能有些简陋,请多多包涵!


    看起来是不是好简单?有木有?请继续往下看。

    2.硬件电路方面

    每个人的硬件可能都不一样,(哪些控制数码管的位选,哪些控制数码管的段选,哪些控制独立按键等等),大家在自己制作过程中都要仔细考虑,我在这里就用我自己的硬件进行介绍。

    这是我的数码管的电路图:(将J12用杜邦线接到对应的P0口,将J16用杜邦线接到对应的P1口)


    位选端我用P1口控制,段选端我用P0口控制。在图中我已标明秒的个位s,秒的十位s1,分的个位min,分的十位min1所对应的数码管。该数码管是共阴极。
    秒的十分位我用的是另一个共阳数码管。我用P3口控制该数码管的段选,其图如下:



    而独立按键我用的P2^7控制“启动/暂停键”,P2^6控制复位键:电路图如下:(将JP5通过杜邦线接到P3口)

    硬件电路基本上就是这些,由于分和秒之间要用小数点分隔开,所以分的个位对应的数码管的段码要用带小数点的段码,其余的数码管则不用。

    硬件方面是为看懂软件程序做准备,下面我们就开始我们的软件程序方面吧!  

    3.软件程序方面


    #include <REGX51.H>
    #define uchar unsigned char
    #define uint unsigned int
    
    #define PIN0 P0  //数码管段选端
    #define PIN1 P1  //数码管位选端
    #define PIN3 P3	 //十分位数码管的段码端
    
    sbit start=P2^7;  //启动/暂停按钮
    sbit reset=P2^6;  //复位按钮
    
    uint cnt=0;   //1s的次数的计数值
    uint num=0;     //进入中断次数的计数值(一次50ms)
    uint num1=0;		//0.1s的次数的计数值
    
    uchar code table[]={0x3f,0x06,0x5b,
    0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f};
    //不带小数点的共阴极数码管段码0-9
    
    
    uchar code table1[]={0xbf,0x86,
    0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
    //带小数点的共阴极数码管段码0-9
    
    char code table2[]={0xc0,0xf9,0xa4,
    0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
    //不带小数点的共阳极数码管段码0-9
    
    void Display(uint w,uint a,uint b,uint c,uint d);  //声明显示函数
    void InitTimer0();  //声明定时器初始化函数
    void Delayms(uint x);  //声明延时函数
    
    void main()
    {
    	uint ms100=0;	//秒的十分位
    	uint s,s1,min,min1,minu=0; 
    	//依次是秒的个位,秒的十位,分的个位,分的十位
    	InitTimer0();	  //初始化定时器
    	while(1)			//进入死循环
    {	
    	if(start==0)   //检测启动/暂停键是否按下
    			Delayms(20); //延时消抖
    	{
    		if(start==0)  //消抖之后再次检测
    		{
    			TR0=!TR0;		//定时器的控制位取反
    			while(!start);  //等待按键释放
    		}
    	}
    	
    if(reset==0)  //检测复位键是否按下
    {
    	Delayms(20);	//延时消抖
    	if(reset==0)  	//消抖之后再次检测
    	{
    		num=0;		
    		num1=0;		//进入中断次数值清0
    		ms100=0;	//十分位的计数值清0
    		cnt=0;		//秒的计数值清0
    		minu=0;		//分的计数值清0
    		while(!reset);		 //等待按键释放
    	}
    }
    	if(num1>=2)		//检测是否达到0.1s,(两个50ms)
    	{
    		num1=0;  		//进入中断次数值清零
    		ms100++;		//秒的十分位的计数值加1
    		if(ms100>=10)  //若秒的十分位计数值达到10
    		{
    			ms100=0;  //清零秒的十分位的计数值
    			num1=0;	//进入中断次数值置0
    		}
    	}
    	
    	if(num>=20)  //判断计时时间是否达到1s(20个50ms)
    	{
    		num=0;     //进入中断次数值置0
    		cnt++;		 //秒的计数值加1
    		if(cnt>=60) //判断是否达到60s
    	{
    		cnt=0;		//若达到60s,将秒的计数值置零
    		minu++;			//分的计数值加1
    		if(minu>=60)  //判断是否达到60分钟,一般秒表是用不到60分的,这是为了程序的严谨性
    
    		{
    			TR0=!TR0;			//达到60分钟则关闭定时器并清零所有的计数值
    			num1=0;				
    			num=0;
    			ms100=0;
    			cnt=0;		
    			minu=0;
    			
    		}
    	}
    	}	
    	s=cnt%10;  	//从秒的计数值里面分离秒的个位
    	s1=cnt/10; 	//从秒的计数值里面分离秒的十位
    	min=minu%10;	//从分的计数值里面分离分的个位
    	min1=minu/10;	//从分的计数值里面分离分的十位
    	
    	Display(ms100,s,s1,min,min1);  //显示这5个数
    }	
    }
    
    void InitTimer0() //定时器初始化函数
    {
    	
    	TMOD=0x01; //选择定时器0的工作方式1
    	TH0=(65536-45872)/256;  //装初值(定时50ms),晶振11.0592MHz
    	TL0=(65536-45872)%256;
    	EA=1;		//打开总中断
    	ET0=1;	//打开定时器中断
    	TR0=0;	//先不要启动定时器
    	
    }
    
    void TIMER0()  interrupt 1  //定时器中断服务函数
    {
    	TH0=(65536-45872)/256;  //重装初值
    	TL0=(65536-45872)%256;
    	num++;		//让进入中断次数值加1,用于判断是否达到1s
    	num1++;		//让进入中断次数值加1,用于判断是否达到0.1s
    }
    
    void Delayms(uint x)   //延时xms
    {
    	uint i,j;
    	for(i=x;i>0;i--)
    		for(j=110;j>0;j--);
    }
    
    void Display(uint w,uint a,uint b,uint c,uint d) //定义显示函数
    {
    	PIN3=table2[w];		//秒的十分位的段选
    	Delayms(5);
    	
    	PIN0=table[a]; //秒的个位的段选
    	PIN1=0x7f;		 //秒的个位的位选
    	Delayms(5);			
    	
    	PIN0=table[b];  //秒的十位的段选
    	PIN1=0xbf;			//秒的十位的位选
    	Delayms(5);
    	
    	PIN0=table1[c];  //分的个位的段选(带小数点)
    	PIN1=0xdf;			 //分的个位的位选
    	Delayms(5);
    		
    	PIN0=table[d];		//分的十位的段选
    	PIN1=0xef;				//分的十位的位选
    	Delayms(5);		
    		
    }
    

    由于在打字时可能不小心会弄错一丁点程序,我都是一个字母一个字母手打的,所以请大家理解思路即可,根据这个思路自己去写,这样得到的知识才是属于自己的。毕竟 “读别人的故事,悟自己的人生”。
    下面来几张实物图给大家看一下我这个秒表的实际效果。

    编译结果:





    烧写进单片机的效果:(没有按启动按钮之前)






    按了启动按钮之后,秒表将会自动开始计时,由于无法演示动态过程,只能在中间按下暂停键给大家看看效果:











    按下复位键后:



    由于我用的是一个比较完整的51开发板,所以里面有很多部分,大家只需要注意观察数码管部分就好。
    下面再来一个完整的图:





    结束语

    至此,利用51单片机制作的秒表就已经完成了!若是文章中有什么不懂的地方或者是自己在制作过程中遇到什么问题都可以联系我,或者给我留言,我一定竭尽全力帮助大家!我们一起学习,一起进步!希望大家都能在看完这篇文章后自己动手成功制作出一个秒表,祝愿大家学好单片机!当然,由于自身水平有限,文章中肯定会存在错误或者是考虑不周的的地方,恳请不吝赐教!谢谢大家!

    (PS:我写了一整天了,反复的看,反复的改,现在头昏眼花,但是只要能对大家有所帮助,一切都是值得的。)




    展开全文
  • 求用单片机设计一个秒表AT89C51要求1、按开关K1秒表开始计时,再按开关K1计时暂停,按开关K2秒表复位。 2、如果可以的话顺便发一下电路图 3、最好是用汇编编写程序谢谢 悬赏分:100 - 解决时间:2010-5-30 08:33 ...

    求用单片机设计一个秒表AT89C51
    要求1、按开关K1秒表开始计时,再按开关K1计时暂停,按开关K2秒表复位。
        2、如果可以的话顺便发一下电路图
        3、最好是用汇编编写程序
    谢谢
    悬赏分:100 - 解决时间:2010-5-30 08:33
    最佳答案:
    ;--------------------------------------------------------
    ;说明:为了提高精度,下列给出的程序和电路图,比楼主提出的要求
    ;      增加了一位0.1秒的计数和显示功能,所以计时范围是00.0~99.9s。
    ;      想得到以00~99形式计秒的网友,可到原题的网址去看原文。
    ;--------------------------------------------------------
    ;汇编程序如下。
    ;使用T0定时方式1,每隔50ms中断一次,用于修改时间及显示
    ;使用外部中断0、1,用于控制启动和清零
    ;========================================================
            ORG 0000H
            AJMP MAIN
            ORG 0003H
            AJMP X0_INT
            ORG 000BH
            AJMP T0_INT
            ORG 0013H
            AJMP X1_INT
    MAIN:
            MOV TMOD,#01H            ;T0定时方式1
            MOV TH0, #(65536-50000) / 256    ;50ms@12MHz
            MOV TL0, #(65536-50000) MOD 256;
            SETB TR0
            SETB ET0                 ;开启定时中断
            SETB EX0
            SETB EX1
            SETB EA                  ;开中断
            MOV R1, #0              ;0~99秒计数
            MOV R2, #0              ;0.1秒数
            MOV R7, #1              ;50ms计数

            MOV P0, #0C0H           ;显示00.0
            MOV P2, #0C0H
            mov p1, #0C0H
    LOOP:
            SJMP LOOP
    ;-----------------------------------------------------------
    DELAY:                           ;延时子程序.
            MOV R4, #0
            DJNZ R4, $
            DJNZ R4, $
            RET
    ;-----------------------------------------------------------
    X0_INT:                          ;启动/停止
            CPL F0
            RETI
    ;-----------------------------------------------------------
    X1_INT:                          ;清零
            MOV R1, #0
            MOV P0, #0C0H
            MOV P2, #0C0H
            mov p1, #0C0H
            RETI
    ;-----------------------------------------------------------
    T0_INT:                          ;50ms中断执行一次.
            MOV TL0, #(65536-50000) MOD 256;
            MOV TH0, #(65536-50000) / 256    ;50ms@12MHz
            DJNZ R7, T0_END          ;中断不到20次.
            MOV R7, #2              ;#20
            JNB F0, T0_END
            mov a, r2
            add a, #1
            da   a
            anl a, #0fh
            mov r2, a
            jnz disp
            MOV A, R1
            ADD A, #1
            DA   A
            MOV R1, A
    disp:
            mov a, r2
            anl a, #0fh
            movc a, @a+dptr          ;查出段码
            mov p1, a               ;显示0.1秒
            MOV A, R1
            ANL A, #0FH
            MOV DPTR, #TAB
            MOVC A, @A+DPTR          ;查出段码
            MOV P2, A               ;显示个位
            MOV A, R1
            SWAP A
            ANL A, #0FH
            MOVC A, @A+DPTR          ;查出段码
            MOV P0, A               ;显示十位
    T0_END:
            RETI
    ;-----------------------------------------------------------
    TAB:
            DB   0c0H,0f9H,0a4H,0b0H,99H,92H,82H,0f8H,80H, 90H
            END
    ;===========================================================
    ;PROTEUS仿真截图如下:

    用AT89C51单片机设计一个秒表:00.0~99.9 - 非著名博主 - 电子信息角落
    图片链接:http://hi.baidu.com/%D7%F6%B6%F8%C2%DB%B5%C0/album/item/761522c99ac2782c7e3e6f05.html
    ;-----------------------------------------------------------
    提问者对于答案的评价:非常感谢
    原题网址:http://zhidao.baidu.com/question/156237554.html?push=core
    ;-----------------------------------------------------------

    ;===========================================================
    基于单片机89C51的计时器或秒表
    AT89C51单片机秒表程序和电路图要求就是这样的了:
    1. 设计中采用的单片机以及显示器件,用AT89C51设计一个2位LED数码显示秒表,有开始,停止,清零就行。
    2. 设计实现的基本功能,系统显示时间为00~99秒,每秒自动加1,设计越简单越好。
    求电路图和相应的C程序,过程最好能详细些,因为要写实验报告~~希望高手帮忙
    悬赏分:50 - 解决时间:2010-6-1 15:51
    原题网址:http://z.baidu.com/question/156668106.html
    就是那个秒表问题,你给我的设计,汇编程序能改成C吗?
    悬赏分:0 - 解决时间:2010-6-1 18:25
    原题网址:http://z.baidu.com/question/156679381.html
    //---------------------------------------------
    下面是00-99秒计数的语言C程序。

    #include<reg52.h>
    #include<intrins.h>
    unsigned char i, j;
    unsigned char code table[] = {
        0xc0, 0xf9, 0xa4, 0xb0, 0x99,
        0x92, 0x82, 0xf8, 0x80, 0x90
    };
    bit k;
    //---------------------------------------------
    void main( )
    {
        TMOD = 0x01;                       //;T0定时方式1
        TH0 = (65536-50000) / 256;         //;50ms@12MHz
        TL0 = (65536-50000) % 256;
        TR0 = 1;                           //;定时器初始化结束
        ET0 = 1;                           //;开启定时中断
        EX0 = 1;
        EX1 = 1;
        EA = 1;
        i = 0;
        j = 0;
        P0 = 0xC0;
        P2 = 0xC0;
        while(1);
    }
    //---------------------------------------------
    void timer0(void) interrupt 1
    {
        TL0 = (65536-50000) % 256;
        TH0 = (65536-50000) / 256;         //;50ms@12MHz
        if (k) {
          j++;
          if (j == 20) {
            j = 0;
            i++;
            if (i == 100) i = 0;
            P0 = table[i / 10];
            P2 = table[i % 10];
    }   } }
    //---------------------------------------------
    void x0(void) interrupt 0
    {
        k = ~k;
    }
    //---------------------------------------------
    void x1(void) interrupt 2
    {
        i = 0;
        j = 0;
        P0 = 0xC0;
        P2 = 0xC0;
    }
    //---------------------------------------------
    提问者对于答案的评价:谢谢啦

    展开全文
  • 4、通过独立完成一个小的数字秒表系统设计,从硬件设计到软件设计,增强分析问题、解决问题的能力,为日后的毕业设计及科研工作奠定良好的基础。 5、掌握51单片机软件编程知识、实现功能、设计方法,及KEIL软件使用...
  • 下午自学了一下单片机的前几章的知识,理解了数码管的显示原理以及静态显示和动态扫描的编程方法。...上周单片机实验课的内容是编一个秒表,在4位数码管中分别显示分和秒还有分秒,即最多可显示“9:59.9”。这里我...

    下午自学了一下单片机的前几章的知识,理解了数码管的显示原理以及静态显示和动态扫描的编程方法。其中,比较重要的几个概念有:数码管公共端类型(共阴极、共阳极)、位选(决定多位数码管中哪一位显示)、段选(决定数码管显示的数字),另外还有锁存器(教材P36,可通过控制锁存端来改变数据输出的状态)。

    上周单片机实验课的内容是编一个秒表,在4位数码管中分别显示分和秒还有分秒,即最多可显示“9:59.9”。这里我用两个键实现了秒表的启动/暂停和清零功能,代码如下:

    1. #include <reg51.h>  
    2. #define uint unsigned int  
    3. #define uchar unsigned char  
    4. sbit S1 = P1^3;  
    5. sbit S2 = P1^1;  
    6. sbit S3 = P1^2;  
    7. sbit S4 = P1^0;  
    8. sbit beep = P2^7;  
    9. sbit a = P0^0;  
    10. sbit b = P0^1;  
    11. sbit c = P0^2;  
    12. sbit d = P0^3;  
    13. sbit e = P0^4;  
    14. sbit f = P0^5;  
    15. sbit g = P0^6;  
    16. sbit p = P0^7;  
    17. sbit key1 = P1^4;  
    18. sbit key2 = P1^5;  
    19. sbit key3 = P3^6;  
    20. sbit key4 = P3^7;  
    21. uchar num,kms,sec,min;  
    22. uchar code N[10] = {0xc0, 0xf9 ,0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90}; //0, 1, 2, 3, ...8, 9  
    23. uchar code Z[10] = {0x40, 0x79 ,0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00, 0x10}; //0., 1., 2., ... 8., 9.  
    24.   
    25. void delayms(uint xms)  
    26. {  
    27.     uint i,j;  
    28.     for(i = xms; i > 0; i--)  
    29.         for(j = 110; j > 0; j--);  
    30. }  
    31.   
    32. void init()  
    33. {  
    34.     TMOD = 0x01;  
    35.     TH0 = 0x3c;  
    36.     TL0 = 0xb0;  
    37.     S3 = 1;  
    38.     S1 = S2 = S4 = 0;  
    39.     P0 = N[0];  
    40.     delayms(5);  
    41.   
    42.     S3 = 0;  
    43.     S1 = S2 = S4 = 1;  
    44.     P0 = Z[0];  
    45.     delayms(5);  
    46.   
    47.     EA = 1;  
    48.     TR0 = 0;  
    49.     ET0 = 1;      
    50.     kms = sec = min = 0;  
    51. }  
    52.   
    53. void display()  
    54. {  
    55.     uchar shi, ge;  
    56.     if(kms >= 0)  
    57.     {  
    58.         S4 = 0;  
    59.         S1 = S2 = S3 = 1;  
    60.         P0 = N[kms];  
    61.     }  
    62.     delayms(5);  
    63.     if(sec >= 0)  
    64.     {  
    65.         shi = sec/10;  
    66.         ge = sec%10;  
    67.   
    68.         S3 = 0;  
    69.         S1 = S2 = S4 = 1;  
    70.         P0 = Z[ge];  
    71.         delayms(5);  
    72.   
    73.         S2 = 0;  
    74.         S1 = S3 = S4 = 1;  
    75.         P0 = N[shi];  
    76.     }  
    77.     delayms(5);  
    78.     if(min >= 0)  
    79.     {  
    80.         S1 = 0;  
    81.         S2 = S3 = S4 = 1;  
    82.         P0 = N[min];  
    83.     }  
    84.     delayms(5);  
    85. }  
    86.   
    87. void keyscan()  
    88. {  
    89.     if(key1 == 0)  
    90.     {  
    91.         delayms(10);  
    92.         if(key1 == 0)  
    93.         {  
    94.             while(!key1);  
    95.             TR0 = ~TR0;  
    96.         }  
    97.     }  
    98.     if(key2 == 0)  
    99.     {  
    100.         delayms(10);  
    101.         if(key2 == 0)  
    102.         {  
    103.             min = sec = kms = 0;  
    104.             while(!key1);  
    105.         }  
    106.     }  
    107. }  
    108.   
    109. main()  
    110. {  
    111.     init();  
    112.     while(1)  
    113.     {  
    114.         keyscan();  
    115.         display();        
    116.     }  
    117. }  
    118.   
    119. void T0_time() interrupt 1  
    120. {  
    121.     TH0 = 0x3c;  
    122.     TL0 = 0xb0;  
    123.         num++;  
    124.     if(num == 2)  
    125.     {  
    126.         num = 0;  
    127.         kms++;  
    128.         if(kms == 10)  
    129.         {  
    130.             kms = 0;  
    131.             sec++;  
    132.             if(sec == 60)  
    133.             {  
    134.                 sec = 0;  
    135.                 min++;  
    136.                 if(min == 10)  
    137.                 {  
    138.                     TR0 = 0;  
    139.                     min = 9;  
    140.                     sec = 59;  
    141.                     kms = 9;  
    142.                 }  
    143.             }  
    144.         }  
    145.     }  
    146. }   

    程序通过“Keil uVision4”调试,大家也可以在板子上运行一下试试。

    注意:需要根据板子的端口定义相关变量,不要不分青红皂白就直接使用我的程序哈。

    最后上个图,第一次做单片机,希望以后还有时间可以做更深入的更好玩的东西。


    展开全文
  • ic单片机计时秒表程序设计(时钟显示范围00.00~99.99秒,分辨度为0.01秒)
  • 采用51单片机设计一个计时器前期准备 一、所执行的功能  1、可以计时; 2、可以存储时间; 3、可以查看存储的时间; 二、器材 1、51单片机(STC89C52RC)及单片机最小系统; 2、7段数码管及74HC573锁存器2个...

    采用51单片机设计一个计时器前期准备

    一、所执行的功能

        1、可以计时;

    2、可以存储时间;

    3、可以查看存储的时间;

    二、器材

    1、51单片机(STC89C52RC)及单片机最小系统;

    2、7段数码管及74HC573锁存器2个;

    3、按键;

    4、电源;

    三、硬件电路的设计

        1、51单片机最小系统:电源、复位电路、晶振电路、下载电路、51单片机

    2、显示电路

    3、按键电路

    四、分析单片机编程的内部资源

    1、I/O口的使用;

    2、定时/计数器的使用;

    五、软件编写流程的设计

    1、定义端口(数码管显示端口,定义按键输入的端口,每个端口分配不同的名字)

    2、硬件资源的初始化(初始化定时计数器,初始化LED数码管、初始化按键)

    3、定时计数器:用于精确计时的产生;

    4、I/O口:LED数码管显示;按键检测;

    5、功能的初始化(工作状态初始化、显示器初始化);

    6、工作状态:a、等待状态;b、计数状态;c、存储状态;

    六、程序代码

    #include<reg52.h>

    /*****************端口定义****************/

    typedef unsignedint UINT16;

    typedef unsignedchar UINT8;

    #define DATA P0

    sbitseg_sel=P2^0;   //段选

    sbitbit_sel=P2^1;   //位选

    sbitstart=P2^2;  //开始

    sbitstore=P2^3;  //存储

    sbitdiskey=P2^4;  //回显

    sbitreset=P2^5;   //复位

    UINT8 codeseg_table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40};

    UINT8 codebit_table[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};

    UINT8n_ten_ms,n_second,n_minute;

    UINT8 run_flag;

    UINT8temp_buf[5][3];

    UINT8 arry_point;

    /************延时函数*************/

    void delayms(UINT8ms)

    {

           UINT8 x,y;

            for (x=ms;x>0;x--)

              for(y=112;y>0;y--);

    }

    /********定时器初始化**********/

    voidInitTimer0(void) 

    {

        TMOD = 0x01;  //定时器模式寄存器设置

        TH0 = 0x0DC;  //定时器赋初值时间50微秒

        TL0 = 0x000;

        EA = 1;   //打开总开关

        ET0 = 1;  //打开中断

        //TR0 = 1;  //打开定时器

    }

    /**********数码管的初始化********/

    voiddisplay_led(UINT8 which_bit,UINT8 which_number)

    {

            bit_sel=1;        

            DATA=bit_table[which_bit];

            bit_sel=0;

             seg_sel=1;

            DATA=0x00;

            seg_sel=0;

            seg_sel=1;

            DATA=seg_table[which_number];

            seg_sel=0;  

    }

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

    void display(UINT8which_bit,UINT8 which_number)

    {

      UINT8 ge,ten;

      ten=which_number/10;

      ge=which_number%10;

      display_led(5,16);

      delayms(5);

      display_led(2,16);

      delayms(5);

      if(which_bit==1)

      {

        display_led(6,ten);

        delayms(5);

        display_led(7,ge);

        delayms(5);

      }

      if(which_bit==2)

      {

        display_led(3,ten);

        delayms(5);

        display_led(4,ge);

        delayms(5);

      }

      if(which_bit==3)

      {

        display_led(0,ten);

        delayms(5);

        display_led(1,ge);

        delayms(5);

      }

    }

     

     

    /*************回显按键函数***************/

    voiddiskey_keyscan()

    {

      if(diskey==0)

      {

        delayms(5);

        if(diskey==0)

        {

          arry_point--;

          n_ten_ms=temp_buf[arry_point][0];

          n_second=temp_buf[arry_point][1];

          n_minute=temp_buf[arry_point][2];

        }

        while(!diskey);

      }

     

    }

    /*************开始键函数*************/

    voidstart_keyscan()

      if(start==0)

      {

        delayms(5);

         if(start==0)

           {

             run_flag=~run_flag;

           }

           while(!start);

      }

     

      if(run_flag)

      {

        TR0=1;

      }

      else if(!run_flag)

      {

        TR0=0;

        diskey_keyscan();

      }

    }

    /*************复位按键函数***********/

    void reset_keyscan()

    {

       if(reset==0)

       {

         delayms(5);

         if(reset==0)

         {

           n_ten_ms=0;

           n_second=0;

           n_minute=0;

           run_flag=0;

          

         }

         while(!reset);

       }

      

    }

    /************存储按键函数************/

    voidstore_keyscan()

    {

       if(store==0)

       {

         delayms(5);

         if(store==0)

         {

            if((arry_point>=0)&&(arry_point<5))

             {

               temp_buf[arry_point][0]=n_ten_ms;

               temp_buf[arry_point][1]=n_second;

               temp_buf[arry_point][2]=n_minute;

               arry_point++;

             }

         }

         while(!store);

       }

      

    }

     

    /*************按键扫描函数***********/

    void keyscan()

    {

      start_keyscan();

      delayms(5);

      reset_keyscan();

      delayms(5);

      store_keyscan();

      delayms(5);

    }

    /**********扫描函数************/

    void reflash()

    {

      display(1,n_ten_ms);

      display(2,n_second);

      display(3,n_minute);

    }

    /**********主函数**************/

    int main(void)

    {

            InitTimer0();

       while(1)

       {

         keyscan();

         reflash();

       }

    }

     

     

    /**********中断***************/

    voidTimer0Interrupt(void) interrupt 1

    {

        TH0 = 0x0DC;

        TL0 = 0x000;

        n_ten_ms++;

         if(n_ten_ms>=100)

         {

           n_ten_ms=0;

           n_second++;

           if(n_second>=60)

           {

             n_second=0;

             n_minute++;

             if(n_minute>=60)

             {

                n_minute=0;

             }

           }

         }

    }


    展开全文
  • 一个51单片机系统,实现电子秒表功能,程序控制4个数码管的显示,秒表精度为0.1秒,通过按钮可控制秒表启动、停止、清零,最大计时9分59.9秒
  • 单片机实现秒表功能

    2017-04-25 19:16:21
    单片机实现秒表功能,通过一个按键控制秒表的启动、暂停、清零
    最近学习到单片机,老师要求我们用单片机实现一个秒表。在求助了各种网上的资源后发现还是一脸mb,所以决定自己动手,丰衣足食。

    以下就是具体的代码实现及运行结果。 

    #include "reg52.h" 
    #include <stdio.h>  

    typedef unsigned int u16;  
    typedef unsigned char u8;

    sbit LSA=P2^2;
    sbit LSB=P2^3;
    sbit LSC=P2^4;


    sbit k2=P3^2; 


    u8 code smgduan[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
         0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值

    u8 code num[10]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};

    u8 ssec,sec,flag=0,wan=0;
    u8  DisplayData[4];

    u8 val0;   //最高位
    u8 val1; //次高位
    u8 val2;
    u8 val3;



    void delay(u16 i)
    {
     while(i--); 
    }


    void Timer0Init()
    {
     TMOD|=0X01;

     TH0=0Xd8; 
     TL0=0Xf0; 
     ET0=1;
     EA=1;
     TR0=0;   
    }



    void DigDisplay()
    {
     u8 i;
     for(i=0;i<4;i++)
     {
       
      switch(i) 
      {
       case(0):
        LSA=1;LSB=1;LSC=1; break;//显示第0位
       case(1):
        LSA=0;LSB=1;LSC=1; break;//显示第1位
       case(2):
        LSA=1;LSB=0;LSC=1; break;//显示第2位
       case(3):
        LSA=0;LSB=0;LSC=1; break;//显示第3位
     
      }  
      P0=DisplayData[i];
      delay(100);
      P0=0x00;  
      
     }
    }


    void datapros()
    {
     
     DisplayData[0]=smgduan[ssec%10];

     

     DisplayData[1]=smgduan[ssec%100/10];


     DisplayData[2]=smgduan[sec%10]+0x80;

     DisplayData[3]=smgduan[sec/10];
    // val=smgduan[sec/10];
    }
    void trans(u8 x)
    {
     u8 i;
     for(i=0;i<10;i++)
     {
      if(x==i)
      {
       SBUF=num[i];
      }
     }
     while(!TI);
     TI=0;  


    }

    void send()
    {
     
     TI=0;
     if(TR0=1)
     {
      
      trans(val0);
      trans(val1);
       

      trans(val2);
      trans(val3);
      SBUF=0x0a;
      while(!TI);
      TI=0;
      
     }


    }



    void Timer0() interrupt 1
    {
       u8 i;
     TH0=0Xd8; 
     TL0=0Xf0; 
     ssec++;
     i++;

     
     val2=i%100/10;
     val3=i%10;
      
     if(ssec==100) 
     {
      
      ssec=0;
      
      sec++;
      val0=sec/10;
      val1=sec%10;
      send();
      
      if(sec>=60)
      {
       sec=0;
      
      } 
      
     }
     
    }



    void keypros()
    {
     if(k2==0)   
     { 
      delay(1000); 
      flag++;
      if(k2==0) 
      {
      // TR0=1;
       while(!k2);
       switch(flag)
       {
        case 1:TR0=1;break;
        case 2:TR0=0;break;
        case 3:ssec=0;sec=0;TR0=0;flag=0;break;
       }
       
      } 
     
     }

    }
    void UsartInit()
    {
     SCON=0x50;  // SCON: 模式 1, 8-bit UART, 使能接收 
        TMOD |= 0x20;       // TMOD: timer 1, mode 2, 8-bit 重装
        TH1=0xFD;       // TH1:  重装值 9600 波特率 晶振 11.0592MHz 
     TL1=0xFD;

        TR1=1;          // TR1:  timer 1 打开    
    }




    void main()

     Timer0Init();
     UsartInit();
      


     
     while(1)
     {

      datapros();
      keypros(); 
        
      DigDisplay();
     
      
     }
     
    }






       
    展开全文
  • 用定时器做一个秒表,精确到0.1,S7按下,开始计时,S6按下清零 #include <stc15f2k60s2.h> #include <intrins.h> void Timer0Init(); void Timer1Init(); unsigned char abile[]={0XC0,0XF9,0XA4,0XB0,...
  • 今天微机原理实验老师布置了一道课后作业,就是利用51单片机一个秒表,本来单片机是有P0,P1,P2,P3共计32个I/O口可以用的,但是因为实验箱内单片机做了外部扩展,所以端口不够用,改成利用C51单片机外扩8255实现...
  • 51单片机秒表程序

    2019-09-03 22:18:38
    这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、...
  • /************************************************************************************** 秒表实验做简易秒表,从0加至60,再返回为0,循环往复(即每秒加一,不需要考虑进位) ...
  • 设计两个按键,启动和暂停是一个按键,按下进行秒表计时或者暂停;④还有一个是复位按键,按下秒表清零;8点全部完成整体程序学习,读代码全部读懂,每个子函数知道内部功能。如果放在以前,我可能...
  • 秒表设计程序的改进和完善   今日任务完成情况 (详细说明本日任务是否按计划完成,开发的代码量。)   针对昨日没有完成的一些类如数码管最后两位不能显示、清零后不能...
  • STC89C52_51单片机_ 秒表程序_高精度秒表_精确到小数点后两位_精确到10ms_C语言代码_分享首码代码的BGM 代码及文件下载链接 文件审核通过后挂上 高精度秒表 可以精确到小数点后两位,也就是10ms 用到...
  • //以前写过一个计时程序,是用汇编语言写的,只用了一个按键实现计时器的启动、暂停和复位。//有位网友要求用C语言写一遍,并提供了部分程序,在下面的博文留言中可以看到://...
  • 1.一个精度为0.1s的秒表系统。 2.有启动按钮、暂停按钮及清零按钮。 3每到一秒钟有声音提醒功能,可通过按钮打开及关闭该提醒音。 压缩包中包含proteus仿真图、hex文件和C语言源代码,代码中写有详尽的注释,一看就...
  • 单片机c语言编写的秒表程序,精确到1ms
  • /*********************************...秒表 计时秒表,显示格式:**.** Author:Vivien *******************************************************/ #include &lt;reg51.h&gt; #define DataPort P0 //数据端...
1 2 3 4 5 ... 16
收藏数 309
精华内容 123
关键字:

单片机编程设计一个秒表