这个程序错在哪了,求大神指教

2019-08-03 18:33发布

KEY1      BIT   P3.2  
KEY2      BIT   P3.3
KEY3          BIT   P3.5
DISPRAM   DATA  30H                   ;显示数字的暂存
HOUR_REG  DATA  38H  
MINU_REG  DATA  39H
SECO_REG  DATA  3AH
T0_COUNT  DATA  3BH
DISP_COUNT  DATA  3CH

          ORG   0000H                     ;主程序的入口
          LJMP  MAIN
          ORG   000BH                     ; 定时//器T0中断程序入口
          LJMP  T0_TIME
          ORG   0030H
MAIN:     MOV   SP, #3FH                   ;//堆栈指针设置堆栈地址存放
          MOV   HOUR_REG, #0
          MOV   MINU_REG, #0
          MOV   SECO_REG, #0
          MOV   TMOD, #11H;    //选择工作方式1  
          MOV   IE, #82H;  // EA=1,CPU开放中断 ET0=1,使能定时器T0溢出中断
          SETB  TR0           // 开定时计数器
MAIN1:   LCALL TIME2STR   // 调用时间数据显示
          MOV   R0, #DISPRAM
          LCALL DISPLAY
          JB    KEY1, MAIN1
          LCALL TIME_SET
          SJMP  MAIN1
;---------------------------------------
;时间数据显示字符串功能
;---------------------------------------
TIME2STR: MOV   R0, #DISPRAM       //时间数据显示
          MOV   A, HOUR_REG   
          MOV   B, #10
          DIV   AB
          MOV   @R0, A
          MOV   A, B
          INC   R0
          MOV   @R0, A
          MOV   A, MINU_REG
          MOV   B, #10
          DIV   AB
          INC   R0
          MOV   @R0, A
          MOV   A, B
          INC   R0
          MOV   @R0, A
          MOV   A, SECO_REG
          MOV   B, #10
          DIV   AB
          INC   R0
          MOV   @R0, A
          MOV   A, B
          INC   R0
          MOV   @R0, A
          RET
;
;---------------------------------------
;设定的时间功能
;---------------------------------------
TIME_SET: CLR   TR0                          //关定时计数器
          MOV   SECO_REG, #0                  //把秒清零
          LCALL TIME2STR
TIME_S1:  MOV   R0, #DISPRAM
          LCALL DISPLAY
          JNB   KEY1, TIME_S1
          MOV   R2, #2
TIME_S2:  MOV   A, R2
          JZ    TIME_S3
          LCALL TIME2STR
          CJNE  R2, #2, TIME_S21
          ORL   DISPRAM, #80H
          ORL   DISPRAM+1, #80H
          SJMP  TIME_S22
TIME_S21: ORL   DISPRAM+2, #80H
          ORL   DISPRAM+3, #80H
TIME_S22: MOV   R0, #DISPRAM
          LCALL DISPLAY
          JB    KEY1, TIME_S23
          DEC   R2
TIME_S221:MOV   R0, #DISPRAM
          LCALL DISPLAY
          JNB   KEY1, TIME_S221
TIME_S23: JB    KEY2, TIME_S2
          CJNE  R2, #2, TIME_S231
          INC   HOUR_REG
          MOV   A, HOUR_REG
          CJNE  A, #24, TIME_S232
          MOV   HOUR_REG, #0
          SJMP  TIME_S232
TIME_S231:INC   MINU_REG
          MOV   A, MINU_REG
          CJNE  A, #60, TIME_S232
          MOV   MINU_REG, #0
TIME_S232:MOV   R3, #20
TIME_S233:MOV   R0, #DISPRAM
          LCALL DISPLAY
          DJNZ  R3, TIME_S233
          SJMP  TIME_S2
TIME_S3:  SETB  TR0
          RET
;
;---------------------------------------
;  显示功能
;6个LED数码管
;---------------------------------------
DISPLAY:  PUSH  ACC           // 把ACC(累加器)中的数字压入堆栈
          PUSH  DPH          //  把16位指针高8位压入堆栈
          PUSH  DPL
          PUSH  PSW       // 状态字入栈保护【保护现场】
          MOV   A, R4
          PUSH  ACC      // 保存寄存器的数字R4、R5、R6、R7
          MOV   A, R5
          PUSH  ACC
          MOV   A, R6
          PUSH  ACC
          MOV   A, R7
          PUSH  ACC
          INC   DISP_COUNT  
          ANL   DISP_COUNT, #7FH   //相与,闪烁,让灯可以由亮转为灭
          MOV   R5, #8
          MOV   R4, #01H
          MOV   DPTR, #DISPTABLE
DISPL1:   MOV   A, @R0
          PUSH  ACC
          MOV   P2, R4
          ANL   A, #80H
          JZ    DISPL11
          MOV   A, DISP_COUNT
          SUBB  A, #32
          JNC   DISPL11
          MOV   P2, #0
DISPL11:  POP   ACC
          ANL   A, #7FH
          MOVC  A, @A+DPTR
          MOV   P0, A
          MOV   R6, #00H
          MOV   R7, #01H
          LCALL DELAY
          MOV   P0, #0FFH      
          INC   R0
          MOV   A, R4
          RL    A
          MOV   R4, A
          DJNZ  R5, DISPL1
          POP   ACC
          MOV   R7, A
          POP   ACC
          MOV   R6, A
          POP   ACC
          MOV   R5, A
          POP   ACC
          MOV   R4, A
          POP   PSW
          POP   DPL
          POP   DPH
          POP   ACC
          RET
DISPTABLE:DB    0C0H,0F9H,0A4H,0B0H, 99H, 92H, 82H,0F8H, 80H, 90H, 88H, 83H,0C6H,0A1H, 86H, 8EH,0BFH, 89H,0C7H, 8CH,0FFH
          ;      "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "-", "H", "L", "P", " "
;
;--------------------------------------
延迟功能。
;延迟时间=(R6R7)(ms)
;--------------------------------------
DELAY:    PUSH  ACC
          MOV   A, R4
          PUSH  ACC
          MOV   A, R5
          PUSH  ACC
          MOV   A, R7
          JZ    DELAY01
          INC   R6
DELAY01:  MOV   R4, #02H
          MOV   R5, #0F4H
DELAY02:  DJNZ  R5, $
          DJNZ  R4, DELAY02
          DJNZ  R7, DELAY01
          DJNZ  R6, DELAY01
          POP   ACC
          MOV   R5, A
          POP   ACC
          MOV   R4, A
          POP   ACC
          RET
;
;--------------------------------------
;用T0的中断功能
;--------------------------------------
T0_TIME:  MOV   TL0, #0B0H
          MOV   TH0, #3CH
          PUSH  PSW
          PUSH  ACC
          INC   T0_COUNT
          MOV   A, T0_COUNT
          SUBB  A, #20
          JC    T0_OUT
          MOV   T0_COUNT, #0
          INC   SECO_REG
          MOV   A, SECO_REG
          SUBB  A, #60
          JC    T0_OUT
          MOV   SECO_REG, #0
          INC   MINU_REG
          MOV   A, MINU_REG
          SUBB  A, #60
          JC    T0_OUT
          MOV   MINU_REG, #0
          INC   HOUR_REG
          MOV   A, HOUR_REG
          SUBB  A, #24
          JC    T0_OUT
          MOV   HOUR_REG, #0
T0_OUT:   POP   ACC
          POP   PSW
          RETI
;
END
2.7.2.        C语言程序编译
#include<reg51.h>
#define uchar unsigned char
#define uint  unsigned int
#define ulong unsigned long
sbit BUZZ=P3^7;
sbit KEY1=P1^0;
sbit KEY2=P1^1;
uchar hour_reg,minute_reg,second_reg;
void delay(uint);
void display(uchar*);
void time2str(uchar*);
void time_set(void);

void main(void)
{
  uchar dispram[8];
  TMOD=0x11;                 选择工作方式1
  IE=0x82;                     EA=1,CPU开放中断 ET0=1,使能定时器T0溢出中断
  TR0=1;                      开定时计数器
  while(1)
  {
    time2str(dispram);
    display(dispram);
    if(KEY1==0) time_set();
   }
}

void time2str(uchar*ch)
{
   ch[0]=hour_reg/10;           显示小时的高位
   ch[1]=hour_reg%10;          显示小时的低位
   ch[2]=minute_reg/10;                   显示分钟的高位
   ch[3]=minute_reg%10;                  显示分钟的低位
   ch[4]=second_reg/10;                    显示秒的高位
   ch[5]=second_reg%10;                  显示秒的低位
   }

void time_set(void)
{
  uchar ch[6];
  uchar i,c;
  TR0=0;                                 关定时计数器
  second_reg=0;                           秒钟清零
  time2str(ch);
do
  { display(ch);}
while(KEY1==0);
c=2;
while(c)
{
  time2str(ch);
  if(c==2) {ch[0]|=0x80;ch[1]|=0x80;}        最高位补1
  else { ch[2]|=0x80;ch[3]|=0x80;}
  display(ch);
  if(KEY1==0)
  {
    c--;
    do{  display(ch);
         }
  while(KEY1==0);
  }
if(KEY2==0)
{
  if(c==2) hour_reg=(hour_reg+1)%24;                恢复显示小时
     else minute_reg=(minute_reg+1)%60;             恢复显示分钟
  for(i=0;i<50;i++) display(ch);
}
}
TR0=1;                                            开定时计数器
}
void delay_ms(unsigned int dt)
{
  register unsigned char bt ,ct;            
  for(;dt;dt--)
  for(ct=2;ct;ct--)
  for(bt=250;--bt;);                          延时2*2*250=1ms
  }

void display(uchar*disp_ram)
{
static uchar disp_count;
unsigned char i,j;
unsigned char code table[]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0xff};
disp_count=(disp_count+1)&0x7f;      
for(i=0;i<6;i++)
{
   j=disp_ram[i];
   if(j&0x80) P0=(disp_count>32)? table[j&0x7f]:0xff;    32/128=1/4,1/4的时间灯灭
    else P0=table[j];
        P2=0x01<<i;
        delay_ms(1);
        P0=0xff;
        P2=0;
        }
        }

void T0_time(void) interrupt 1
  {
    static uchar T0_count=0;
        TL0=0xb0;                                  2^16-15536=50000us=50ms
        TH0=0x3c;
        T0_count++;
        if(T0_count>=20)                             循环20次延时1s
        {
          T0_count=0;                                当1s延时到,秒钟数字加1
          second_reg++;
          if(second_reg>=60)
          {
            second_reg=0;                             秒清零,分加1
                minute_reg++;
                if(minute_reg>=60)
                {
                  minute_reg=0;
                  hour_reg=(hour_reg+1)%24;                24小时的记数
                  }
        }
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。