微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 求助!一个51单片机长按键调整定时时钟,调节位闪烁的一...

求助!一个51单片机长按键调整定时时钟,调节位闪烁的一...

时间:10-02 整理:3721RD 点击:
我写了一个程序,是单片机P2.4按键复用,长按可以开始使设定位(R6)闪烁,其余正常显示,短按则不管,正常显示4位数码管。昨天调了一天,今天早上又调了,仍然没有找到最根本的问题!真心求助!
这段程序思想是,长按键则启动定时器1,使得每到一定时间闪烁标志位取反,为0时正常显示我设定的MIN,SEC,为1时除设定位R6灭,其余都正常显示,数码管在设定某计时位时就可以闪烁了
这是程序:
MIN EQU 34H                                  ;分钟显示
SEC EQU 35H                                  ;秒显示
BUF EQU 36H                          ;MIN,SEC加载进buf
FLASHFLAG EQU F0                  ;闪烁标志位
COUNT EQU 37H                      ;中断计数器,计满100次则取反闪烁标志位
COUNTER EQU 38H                  ;按键计数器,大于此值为长按,小于为短按    
FN EQU P2.4                                    ;功能键,长按后进入闪烁显示
ORG 0000H
AJMP MAIN
ORG 001BH
AJMP T1_SURV
ORG 0100H
MAIN:
   MOV R1,#40H                        ;把字模表放在R1为地址的内部ram里
   MOV @R1,#3fH
   INC R1
   MOV @R1,#06H
   INC R1
   MOV @R1,#5bH
   INC R1
   MOV @R1,#4fH
   INC R1
   MOV @R1,#66H
   INC R1
   MOV @R1,#6dH
   INC R1
   MOV @R1,#7dH
   INC R1
   MOV @R1,#07H
   INC R1
   MOV @R1,#7fH
   INC R1
   MOV @R1,#6fH
   INC R1
   MOV @R1,#77H
   INC R1
   MOV @R1,#7cH
   INC R1
   MOV @R1,#39H
   INC R1
   MOV @R1,#5EH
   INC R1
   MOV @R1,#79H
   INC R1
   MOV @R1,#71h
   MOV R1,#40H
   CLR C
   MOV MIN,#21    ;这为了调试方便,直接设要显示的为21,56
   MOV SEC,#56
   MOV R6,#3                         ;为了方便,设要调的是第3位,也就是要闪烁的一位
MAIN_LOOP:   
          ACALL CONV1           ;调用加载函数
          ACALL DISP1                ;调用显示函数
         JNB FN,FUN2
          AJMP MAIN_LOOP
     FUN2:
          INC COUNTER           ;COUNTER计数中
          ACALL DELAY1
          JB FN,FUN1
        AJMP FUN2
    FUN1:                                                ;计数完判断长按/短按
              CLR C
              PUSH ACC
              MOV A,COUNTER
              MOV COUNTER,#0
              CJNE A,#50,UNEQUAL
              POP ACC
             ACALL MODULATE
UNEQUAL:  JC MAIN_LOOP                                          
MODULATE: ACALL INT_TIMER1                ;长按启动定时器1
                AJMP MAIN_LOOP
/*时间加载函数*/
CONV1:                                                          
   MOV R1,#40H
   MOV A,MIN
   MOV B,#10
   div AB
   ADD A,R1
   MOV R1,A
   MOV A,@R1
   MOV BUF,A
   MOV R1,#40H
   MOV A,B
   ADD A,R1
   MOV R1,A
   MOV A,@R1
   MOV BUF+1,A
   MOV R1,#40H
   MOV A,SEC
   MOV B,#10
   div AB
   ADD A,R1
   MOV R1,A
   MOV A,@R1
   MOV BUF+2,A
   MOV R1,#40H
   MOV A,B
   ADD A,R1
   MOV R1,A
   MOV A,@R1
   MOV BUF+3,A
   MOV R1,#40H
   RET
/*显示函数*/
DISP1:
   MOV R0,#buf                   
   PUSH 36H
   S1:
   JNB FLASHFLAG,STABLE_DISP           ;如果FLASHFLAG=0,则越过闪烁部分
FLASH_DISP:       
   CJNE R6,#1,GOTO1                           ;R6记录调整位
   FLASH_BIT1:
   MOV BUF,#00H             ;第一位灭时段码0x00
   AJMP        STABLE_DISP
GOTO1:
   CJNE R6,#2,GOTO2
   FLASH_BIT2:
   MOV BUF+1,#00H
   AJMP STABLE_DISP
GOTO2:
   CJNE R6,#3,GOTO3
   FLASH_BIT3:
   MOV BUF+2,#00H
   AJMP STABLE_DISP
GOTO3:
   CJNE R6,#4,STABLE_DISP
   FLASH_BIT4:
   MOV BUF+3,#00H
STABLE_DISP:                                  
   MOV R2,#4
   MOV ACC,#0F7H
   S0: PUSH ACC
       MOV A,@R0
           MOV P0,#0        ;避免叠影,先清端口
           MOV P0,A       
           POP ACC
           MOV P2,ACC
           ACALL DELAY1
           RR A
           INC R0
           DJNZ R2,S0
           POP 36H
           RET       
/*延时子程序*/                              
DELAY1:        MOV R3,#1                                   ;延时2ms
         D2:MOV R4,#10
         D1:MOV R5,#100
         DJNZ R5,$
         DJNZ R4,D1
         DJNZ R3,D2
                RET       
/*定时器1初始化*/
INT_TIMER1:                                        //中断后,闪烁标志位取反
        MOV TMOD,#10H                         //定时器1的工作方式1
        MOV TH1,#0F8H
                MOV TL1,#2fH
                MOV COUNT,#0
                SETB EA
        SETB ET1       
                SETB TR1
                RET
/*定时器1中断服务程序*/
T1_SURV:                                                          //50ms中断
         PUSH ACC
     MOV  TH1,#0F8H         
     MOV  TL1,#2FH      
     INC COUNT
     MOV A,COUNT
     CJNE A,#250,RNT
     CPL FLASHFLAG    ;取反调时闪烁标志位      
RNT: POP ACC
     MOV COUNT,#0
     RETI    ;中断返回
END


Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top