求用单片机设计一个秒表AT89C51

要求1、按开关K1 秒表开始计时 再按开关K1计时暂停,按开关K2秒表复位
2,如果可以的话顺便发一下电路图
3、最好是用汇编编写程序(本人看不懂C)
谢谢

;汇编程序如下。

;使用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, #99H            ;0~99计数.

        MOV  R7, #1              ;50ms计数.

        MOV  P0, #0C0H

        MOV  P2, #0C0H

LOOP:

        SJMP LOOP

;-----------------------------------------------------------

DELAY:                           ;延时子程序.

AA4:    MOV  R4,  #0

        DJNZ R4,  $

        DJNZ R4,  $

        RET

;-----------------------------------------------------------

X0_INT:                          ;启动/停止

        CPL  F0

        RETI

;-----------------------------------------------------------

X1_INT:                          ;清零

        MOV  R1, #0

        MOV  P0, #0C0H

        MOV  P2, #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, #20

        JNB  F0, T0_END

        MOV  A,  R1

        ADD  A,  #1

        DA   A

        MOV  R1, A

        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

;===========================================================

;仿真截图如下:

温馨提示:内容为网友见解,仅供参考
第1个回答  2010-05-29

对不起,我不会用汇编做,所以用c语言编了一个,希望对你有帮助

#include <reg51.h>

#define uchar unsigned char

sbit start=P3^6;

sbit stop=P3^5;

uchar code dulatab[]={0x3f,0x06,0x5b,0x4f,0x66,

       0x6d,0x7d,0x07,0x7f,0x6f,0x40}; //数字编码0-9

uchar code welatab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位控制字

uchar msec,sec,min; 

void delay(uchar time)  //延时

{

 uchar i,j;

 for(i=0;i<time;i++)

 {

  for(j=0;j<110;j++)

  ;

 }

}

void writeled(uchar num,uchar addr)

{  

 //关显示

 P2=0xff;

 //送数据

 P0=dulatab[num];

 //开显示

 P2=welatab[addr];   

 delay(4);  

}

void display(uchar msec,uchar sec,uchar min)

{

 uchar msech,msecl,sech,secl,minh,minl;

 msech=msec/10;

 msecl=msec%10;

 sech=sec/10;

 secl=sec%10;

 minh=min/10;

 minl=min%10;

 writeled(minh,0);

 writeled(minl,1);

 writeled(10,2);

 writeled(sech,3);

 writeled(secl,4);

 writeled(10,5);

 writeled(msech,6);

 writeled(msecl,7);

}

void init()

{

 TMOD=0x10;

 TH1=0xd8;

 TL1=0xf0;

// TR1=1;

 EA=1;

 ET1=1;

}

void keyscan()

{

 if(start==0)

 {

  delay(2);

  if(start==0)

  {

   TR1=~TR1;

   while(start==0)

   {

    display(msec,sec,min); 

   }

  }

 }

 if(stop==0&&TR1==0)

 {

  delay(2);

  if(stop==0)

  {

   msec=0;

   sec=0;

   min=0;

   while(stop==0)

   {

    display(msec,sec,min); 

   }

  }

 }

}

void main()

{

 init();

 while(1)

 {

  display(msec,sec,min);

  keyscan(); 

 }  

}

void timer1() interrupt 3

{

 TH1=0xd8;

 TL1=0xf0;

 msec++;

 if(msec==100)

 {

  msec=0;

  sec++;

  if(sec==60)

  {

   sec=0;

   min++;

   if(min==60)

   {

    min=0;

   } 

  }

 }

 

}

相似回答