微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 51单片机智能时控开关

51单片机智能时控开关

时间:10-02 整理:3721RD 点击:
下面这段程序实现不了需要的功能,为什么:

                               ;系统晶振是 11.0592 MHz

Z8279   EQU    0FF82H    ;8279 状态/命令口地址

D8279   EQU    0FF80H    ;8279 数据口地址

LEDMOD  EQU    00H     ;左边输入 八位字符显示

                            ;外部译码键扫描方式,双键互锁

LEDFEQ  EQU    2FH     ;扫描速率

LEDCLS  EQU    0C1H    ;清除显示 RAM

LEDWR0  EQU    80H     ;设定的将要写入的显示RAM地址

READKB  EQU    40H     ;读 FIFO RAM 地址 0 的命令字

SIGN     EQU     08H     ;00H设置为输入合法标志位

FLAG    EQU    09H           

KEY0    EQU    00H            ;开关1状态

KEY1    EQU    01H            ;开关2状态

KEY2    EQU    02H            ;开关3状态

KEY3    EQU    03H            ;开关4状态

KEY4    EQU    04H            ;开关5状态

ORG     0000H

AJMP    START

ORG     000BH               ;T0中断程序入口地址

LJMP    INT_T0

ORG     001BH            ;T1 中断程序入口地址

LJMP    INT_T1

ORG     0040H

START:

        MOV    SP,#60H

        LCALL  INIT8279        ;初始化8279

        MOV    R4,#12H         ;时

        MOV    R3,#33H         ;分

        MOV    R2,#54H         ;秒

        MOV    R1,#20          ;秒

        MOV     R0 ,#30H        ;开关定时时间存储器其始地址

              MOV     R7 ,#10

        CLR      KEY0           ;清楚开关状态标志

        CLR     KEY1

        CLR     KEY2

        CLR     KEY3

        CLR      KEY4

LOOP:   MOV    @R0,#0FFH

            INC       R0

            DJNZ     R7 ,LOOP

         MOV     P1,#00H

         SETB     SIGN              ;标志

         MOV    TMOD,#11H         

         MOV     TL1,#00H                                                               

         MOV     TH1,#4CH

            MOV    TL0,#8FH

            MOV    TH0,#0FCH

            SETB    ET0                 ;中断允许

            SETB    PT1

         SETB     ET1

         SETB     EA                 ;允许断

WAIT:    LCALL    GETKEY          ;读键盘

         CJNE      A,#0FFH,CONT    ;判断是否有键输入

         MOV      A,B              ;有键输入

         CJNE     A,#3CH,KEY_A      ;输入键是'C',转CLEAR_T

         LCALL    CLEAR_T

KEY_A:  CJNE     A,#3AH,KEY_D   ;输入键是'A',转START_T

         LCALL    START_T

KEY_D:  CJNE   A,#3DH,KEY_B     ;输入键是'D',转STOP_T

         LCALL    STOP_T

KEY_B:  CJNE   A,#3BH,KEY_F      ;输入键是'B',转SET_T

         LCALL    SET_T

KEY_F:  CJNE   A,#3FH,KEY_E      ;输入键是'F',转DINGSHI_T

         LCALL    DINGSHI_T      

KEY_E:  CJNE   A,#3EH,CONT       ;输入键是'E',转MONITOR

         LCALL   MONITOR

CONT:   JNB     SIGN,WAIT       ;若无秒标志则循环

         LCALL    DISPLAY         ;显示时间

         CLR      SIGN              ;清标志

         SJMP     WAIT               ;循环

;实现外部干预子程序

MONITOR:NOP                     

       JNB KEY0,L77

             CLR P1.0

             CLR KEY0

L77:   JNB KEY1,L80

          CLR P1.1

             CLR KEY1

L80:   JNB KEY2,L83

          CLR P1.2

             CLR KEY2

L83:   JNB KEY3,L86

          CLR P1.3

             CLR KEY3

L86:   JNB KEY4,L91

         CLR P1.4

          CLR KEY4

L91:   CLR TR0

       CLR P1.5

         RET

       SJMP $

;时间清零子程序

CLEAR_T:CLR     TR1             ;关计数器

        MOV    R4,#0H          ;小时清零

        MOV    R3,#0H          ;分钟清零

        MOV    R2,#0H          ;秒清零

        SETB   SIGN            ;置秒标志

        RET

        

;电子钟计时子程序        

START_T:SETB    TR1             ;开计时中断

        RET

        

;电子钟停止计时子程序        

STOP_T: CLR     TR1             ;关计时中断

        RET

                                 

;设置初值子程序        

SET_T:  CLR    TR1             ;关计数器

        MOV    R5,#7

        LCALL  GETWORD         ;读小时数

        CJNE   A,#0FFH,INVALID ;判断输入合法性

        MOV    A,B

        ADD    A,#232

        JC     INVALID         ;判断输入小时值 < 24

        MOV    A,B

        MOV    B,#10

        div    AB

        SWAP   A

        ADD    A,B

        MOV    R4,A            ;保存输入的值

        MOV    R5,#4           ;读分钟数

        LCALL  GETWORD         

        CJNE   A,#0FFH,INVALID ;判断输入合法性

        MOV    A,B

        ADD    A,#196

        JC     INVALID         ;判断输入分钟数 < 60

        MOV    A,B

        MOV    B,#10

        div    AB

        SWAP   A

        ADD    A,B

        MOV    R3,A            ;保存输入的值

        MOV    R5,#1           ;读秒数

        LCALL  GETWORD         

        CJNE   A,#0FFH,INVALID ;判断输入合法性

        MOV    A,B

        ADD    A,#196

        JC     INVALID         ;判断输入分钟值 < 60

        MOV    A,B

        MOV    B,#10

        div    AB

        SWAP   A

        ADD    A,B

        MOV    R2,A            ;保存输入的值

        MOV    R5,#1           ;读秒数

               

        AJMP   SET_TOK

INVALID:LCALL   CLEAR_T         ;不合法则时间清零      

SET_TOK:LCALL   DISPLAY         ;显示时间

        SETB   TR1

             RET

;设置定时时间子程序      

DINGSHI_T:

             SETBFLAG

              MOV    R0,#30H

                MOV     DPTR ,#Z8279

          MOV    A,#LEDCLS          ;清除 LED 显示     

                MOVX   @DPTR,A

          MOV    R5,#1         

          LCALL  GETWORD           ;选择设置定时开关通道

          CJNE   A,#0FFH,DINGSHI_T ;判断输入合法性

          MOV    A,B

          ADD    A,#251

          JC     DINGSHI_T         ;判断输入小时值 < 5

          MOV    A,B                        

          MOV    B,#10

          div    AB

          SWAP   A

          ADD    A,B

               MOV     B,#2

               MUL     AB

               ADD    A,R0

               MOV    R0,A

               MOV     R5,#7

          LCALL  GETWORD         

          CJNE   A,#0FFH,DINGSHI_T ;判断输入合法性

          MOV    A,B

          ADD    A,#232

          JC     DINGSHI_T        ;判断输入分钟数 < 24

          MOV    A,B

          MOV    B,#10

          div    AB

          SWAP   A

          ADD    A,B

          MOV    @R0,A            ;保存输入的值

             INC    R0

          MOV    R5,#4            ;读秒数

          LCALL  GETWORD        

          CJNE   A,#0FFH,DINGSHI_T ;判断输入合法性

        MOV    A,B

        ADD    A,#196

        JC     DINGSHI_T        ;判断输入分钟值 < 60

        MOV    A,B

        MOV    B,#10

        div    AB

        SWAP   A

        ADD    A,B

        MOV     @R0,A           ;当通道选中时,LED亮提示通道被

;中

          MOV    A,30H

              CJNE    A,#0FFH,L196

              CLR     P1.0               ;如果开关0选中则LED0亮

              AJMP   L198

L196:   SETB   P1.0

L198:   MOV    A,32H

              CJNE   A,#0FFH,L199

              CLR    P1.1

              AJMP   L203

L199:   SETB   P1.1                 ; 如果开关1选中则LED1亮

L203:   MOV    A,34H

              CJNE   A,#0FFH,L202

              CLR    P1.2

              AJMP   L207

L202:   SETB   P1.2                  ;如果开关2选中则LED2亮

L207:   MOV    A,36H

              CJNE   A,#0FFH,L205

              CLR    P1.3

              AJMP   L213

L205:   SETB   P1.3                   ;如果开关3选中则LED3亮

L213:     MOV    A,38H

              CJNE   A,#0FFH,L208

              CLR    P1.4

              AJMP   SET_TOKD

L208:   SETB   P1.4                   ;如果开关4选中则LED4亮

SET_TOKD:

              CLR FLAG

          RET        

               

;读数子程序        

GETWORD:                        

WKEY1:  LCALL  GETKEY          ;读键盘

         CJNE    A,#0FFH,WKEY1   ;无键输入,则再读

         MOV     A,B

        ADD    A,#0C6H

        JC     ERROR1          ;判断输入是否大于9

        MOV    A,B

        SUBB   A,#30H

        JC     ERROR1          ;判断输入是否小于0

        MOV    R6,A

        LCALL  DISLED          ;显示输入的字符

        MOV    B,#10

        MUL    AB

        PUSH   ACC             ;保存输入的值

WKEY2:  LCALL  GETKEY          ;读键盘

        CJNE   A,#0FFH,WKEY2   ;无键输入则再读

        MOV    A,B

        ADD    A,#0C6H         ;判断输入是否大于9

        JC     ERROR2

        MOV    A,B

        SUBB   A,#30H          ;判断输入是否小于0

        JC     ERROR2

        DEC    R5

        MOV    R6,A

        LCALL  DISLED          ;显示输入的字符

        MOV    B,A

        POP    ACC

        ADD    A,B

        MOV    B,A             ;把得到的值存在B

        MOV    A,#0FFH         ;置合法输入标志

        AJMP   KEYOK

ERROR2: POP     ACC

ERROR1: MOV     A,#0            ;置非法输入标志

KEYOK:  RET

;8279初始化子程序

INIT8279:                       

        PUSH  DPH              ;保存现场

        PUSH  DPL

        PUSH  ACC

        LCALL DELAY            ;延时

        MOV   DPTR ,#Z8279

        MOV   A,#LEDMOD        ;置8279工作方式

        MOVX  @DPTR,A

        MOV   A,#LEDFEQ        ;置键盘扫描速率

        MOVX  @DPTR,A

        MOV   A,#LEDCLS        ;清除 LED 显示

        MOVX  @DPTR,A

        POP   ACC              ;恢复现场

        POP   DPL

        POP   DPH

        RET

        

;读取键盘子程序

;有输入则输出: B: 读到的键码 A: 按键的标志0FFH

GETKEY:PUSH   DPH              ;保存现场

        PUSH  DPL

        PUSH  PSW

        MOV   DPTR,#Z8279

        MOVX  A,@DPTR          ;读8279状态

        ANL   A,#07H           ;屏蔽D7-D3

        JNZ   GETVAL           ;判断是否有键输入

        MOV   A,#0H            ;置标志(无键输入)

        SJMP  NKBHIT

GETVAL: MOV    A,#READKB        ;读 FIFO RAM 命令

        MOVX  @DPTR,A

        MOV   DPTR,#D8279

        MOVX  A,@DPTR          ;读键

        ANL   A,#3FH           ;屏蔽 SHIFT 和 CTRL 键

        MOV   DPTR,#KEYCODE    ;键码表起始地址

        MOVC  A,@A+DPTR        ;查表

        MOV   B,A              ;置返回键值

        MOV   A,#0FFH          ;置标志(有键输入)

NKBHIT: POP    PSW              ;恢复现场

        POP   DPL

        POP   DPH

        RET

        

;显示字符子程序

;输入: R5,位置 R6,值

DISLED:  PUSH  DPH             ;保存现场

         PUSH  DPL

         PUSH  ACC

         MOV   A,#LEDWR0       ;置显示起始地址

         ADD   A,R5            ;加位置偏移量

         MOV   DPTR,#Z8279

         MOVX  @DPTR,A         ;设定显示位置

         MOV   DPTR,#LEDSEG    ;置显示常数表起始位置                                             

         MOV   A,R6

         MOVC  A,@A+DPTR       ;查表

         MOV   DPTR,#D8279

         MOVX  @DPTR,A         ;显示数据

         POP   ACC             ;恢复现场

         POP   DPL

         POP   DPH

         RET

;延时子程序                        

DELAY: PUSH   7               ;保存现场

        PUSH   1

        MOV    R7,#0H

DELAY1: MOV     R1,#0H

        DJNZ   R1,$

        DJNZ   R7,DELAY1

        POP    1               ;恢复现场

        POP    7

        RET

;定时器中断服务子程序

INT_T1:                        

                                 ;保护现场

      PUSH   PSW

      PUSH   ACC

             PUSH    DPL

             PUSH    DPH

      CLR    TR1              ;关中断

             MOV     TMOD,#11H

      MOV    TL1,#00H        ;50ms毫秒定时常数

      MOV    TH1,#4CH

             DJNZ    R1,JUDGE

             MOV     R1,#20

             CJNE    R2,#59H,SEC

             CJNE    R3,#59H,MIN

             CJNE    R4,#23H,HOUR

             MOV     R2,#00

             MOV     R3,#00

             MOV     R4,#00

             AJMP    JUDGE

SEC:    MOV A,R2

        ADD A,#1

              DA  A

              MOV R2,A

        AJMP JUDGE

MIN:    MOV A,R3

        ADD A,#1

              DA  A

              MOV R3,A

        MOV   R2,#00

        AJMP  JUDGE

HOUR:  MOV A,R4

        ADDA,#1

              DA  A

              MOV R4,A

        MOV R2,#00

              MOV R3,#00

;判断定时是否到

JUDGE:                                   ;判断开关1

             MOV   A,R4

             CJNE  A,30H,JUDGE_KEY1

             MOV   A,R3

             CJNE  A,31H,JUDGE_KEY1

             SETB  KEY0

             MOV   30H,#0FFH

             MOV   31H,#0FFH

             SETB  TR0

      

JUDGE_KEY1: MOV  A,R4              ;判断开关2

                CJNE  A,32H,JUDGE_KEY2

              MOV  A,R3

                CJNE  A,33H,JUDGE_KEY2

                SETB  KEY1

                MOV   32H,#0FFH

                MOV   33H,#0FFH

                SETB  TR0

      

JUDGE_KEY2: MOV  A,R4               ;判断开关3

                CJNE  A,34H,JUDGE_KEY3

                MOV  A,R3

                CJNE A,35H,JUDGE_KEY3

                SETB KEY2

                MOV  34H,#0FFH

                MOV  35H,#0FFH

                SETB  TR0

      

JUDGE_KEY3:MOVA,R4                   ;判断开关4

            CJNE A,36H,JUDGE_KEY4

               MOV A,R3

               CJNE A,37H,JUDGE_KEY4

               SETB KEY3

               MOV 36H,#0FFH

               MOV 37H,#0FFH

               SETB TR0

JUDGE_KEY4: MOV A,R4                  ;判断开关5

                CJNE A,38H,EXIT_INT

                MOV  A,R3

                CJNE A,39H,EXIT_INT

                SETB KEY4

                MOV 38H,#0FFH

                MOV 39H,#0FFH

                SETB TR0

                RET   

;显示时间

EXIT_INT:

        JB FLAG ,L431

        LCALL DISPLAY

;恢复现场

L431:     

        SETB  TR1

        POP   DPH            

        POP   DPL

        POP   ACC

        POP   PSW  

        RETI                         ;中断返回

;定时器0产生蜂鸣器的频率

INT_T0:

        CLR TR0

             MOV TMOD ,#11H

             MOV TL0,#67H

             MOV TH0,#0FCH

             SETB TR0

             CPL P1.5                        ;

             RETI

;显示时分秒

DISPLAY:

        MOV    A,R4

        ANL    A,#0FH

        MOV    R6,A

        MOV    R5,#6

        LCALL  DISLED          ;显示小时低位

        MOV    A,R4

        SWAP   A

        ANL    A,#0FH

        MOV    R6,A

        MOV    R5,#7

        LCALL  DISLED          ;显示小时高位

        MOV    A,R3

        ANL    A,#0FH

        MOV    R6,A

        MOV    R5,#3

        LCALL  DISLED          ;显示分钟低位

        MOV    A,R3

        SWAP   A

        ANL    A,#0FH

        MOV    R6,A

        MOV    R5,#4

        LCALL  DISLED          ;显示分钟高位

        MOV    A,R2

        ANL    A,#0FH

        MOV    R6,A

        MOV    R5,#0

        LCALL  DISLED          ;显示秒低位

        MOV    A,R2

        SWAP   A

        ANL    A,#0FH

        MOV    R6,A

        MOV    R5,#1

        LCALL  DISLED          ;显示秒高位

             JNB KEY0,L478

CPL P1.0                    ;如果开关0的定时时间到,

;50ms是p1.0的电压反转

L478:   JNB KEY1,L480

             CPL P1.1

L480:   JNB KEY2,L482

             CPL P1.2

L482:   JNB KEY3,L484

             CPL P1.3

L484:   JNB KEY4,L486

             CPL P1.4

L486:   RET

;LED显示常数表

LEDSEG: DB      3FH,06H,5BH,4FH,66H,6DH,7DH,07H;'0,1,2,3,4,5,6,7'

        DB     7FH,6FH,77H,7CH,39H,5EH,79H,71H ;'8,9,A,B,C,D,E,F'

        DB     0BFH,86H,0DBH,0CFH,0E6H,0EDH,0FDH,087H ;'0.,1.,2.,3.,4.,5.,6.,7.'

        DB     0FFH,0EFH,0F7H,0FCH,0B9H,0DEH,0F9H,0F1H ;'8.,9.,A.,B.,C.,D.,E.,F.'

        DB     6DH,02H,08H,00H,59H,0FH,76H    ;'U,-,_, ,I,O,P, '

;键盘键码表

KEYCODE:DB      30H,31H,32H,33H,34H,35H,36H,37H;'1,2,Q,W,A,S,+,Z'

        DB     38H,39H,3AH,3BH,3CH,3DH,3EH,3FH ;'3,4,E,R,D,F,X,C'

        END


看见源码就头疼 还是汇编。

实验课的综合设计

用C语言好多年,汇编忘得差不多了~~~~汗颜~~~~~

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

网站地图

Top