找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2943|回复: 3
打印 上一主题 下一主题
收起左侧

单片机汇编语言里面的一个循环,有中断时退不出循环

[复制链接]
跳转到指定楼层
楼主
;功能,串口中断接收5个字节的上位机数据,如果底个字节是04H就执行循环
TmpData  EQU    01H
AUXR     EQU    08EH


P5   DATA 0C8H
P1M1 DATA 091H
P1M0 DATA 092H
P3M1 DATA 0B1H
P3M0 DATA 0B2H
P5M1 DATA 0C9H
P5M0 DATA 0CAH
T2H  DATA 0D6H
T2L  DATA 0D7H
Busy BIT 20H.0;呼吸模式循环标志


    ORG 0000H
    LJMP MAIN                         ;上电,转向主程序
    ORG 0023H                        ;串行口的中断入口地址
    LJMP Uart1_Int_Recceive     ;转向中断服务程序
    ORG 0100H
;=======主程序开始=====================================================================
       MAIN:  LCALL Uart1_Initial     ;串口初始化                 
                 MOV R3,#0                  ;亮度档位标识清零
       Waitdata: SETB ES                 ;允许串行口中断
                 SETB EA                     ;CPU开中断
                 MOV R0,#40H            ;存放接受的数据首地址---------------------
                 MOV R2,#0                ;存放接受的数据长度---------------------         
;----------单字节16进制数转为3字节的ASCII码-------------------------------           
   Save_UartData:
            LOP:MOV A,TmpData     ;等待新的数据
                 CJNE R2,#5,LOP      ;判断是否收到5个字节
                 CLR ES                     ;所有数据接收完毕,禁止串行中断
                 CLR EA               
;------------------------------------------------------------------------
;======根据语音模块命令控制对应灯具亮度(命令字放在43H的地址中?==========                          
              MOV A,43H                 ;查看地址43H(接收到的5个字节的第四个字节内容做相应的功能判断,为04H就执行LOOP1循环)
              CJNE A,#04H,Waitdata
              setb busy
     LOOP1:;循环执行LOPP1
              jnb Busy,Waitdata;标志位位0就退出循环
              MOV  DPTR,#LED_AC1     ; 调光3档
              LCALL SendString        ; UART发送
              LCALL Dly300ms
              MOV  DPTR,#LED_AC2     ; 调光3档
              LCALL SendString        ; UART发送
              LCALL Dly300ms
              MOV  DPTR,#LED_AC3     ; 调光3档
              LCALL SendString        ; UART发送
              LCALL Dly300ms
              MOV  DPTR,#LED_AC4     ; 调光3档
              LCALL SendString        ; UART发送
              LCALL Dly300ms
              MOV  DPTR,#LED_AC5     ; 调光3档
              LCALL SendString        ; UART发送
              LCALL Dly500ms
         
              
              MOV  DPTR,#LED_AC5     ; 调光3档
              LCALL SendString        ; UART发送
              LCALL Dly300ms
              MOV  DPTR,#LED_AC4     ; 调光3档
              LCALL SendString        ; UART发送
              LCALL Dly300ms
              MOV  DPTR,#LED_AC3     ; 调光3档
              LCALL SendString        ; UART发送
              LCALL Dly300ms
              MOV  DPTR,#LED_AC2     ; 调光3档
              LCALL SendString        ; UART发送
              LCALL Dly300ms
              MOV  DPTR,#LED_AC1     ; 调光3档
              LCALL SendString        ; UART发送
              LCALL Dly300ms
              JMP   LOOP1
         RET
;串口初始化-----------------------------------
Uart1_Initial:
         CLR A
         CLR EA
         MOV SP, #3FH
         MOV SCON,#50H  ;8位数据,可变波特率
         ORL AUXR,#01H  ;串口1选择定时器2为波特率发生器
         ORL AUXR,#04H  ;定时器2时钟为Fosc,即1T
         MOV T2L,#0E0H  ;设定定时初值
         MOV T2H,#0FEH  ;设定定时初值
        ORL AUXR,#10H  ;启动定时器2
        SETB ES                 ;允许串行口中断
        SETB EA                 ;CPU开中断
       RET
;-------串口中断接收数据-------------------------
UART1_Int_Recceive:
                    PUSH ACC
             U1REC1:JBC RI,GetData1 ;是接收中断,清除此标志,转向GetData1接收
                    CLR TI          ;是发送中断,清除此标志,中断返回
                    SJMP U1REC1
           GetData1:MOV A,SBUF      ;接收(读入)数据
                    MOV @R0,A       ;存放数据到30H开头的RAM-----------
                    MOV TmpData,A
                    INC R0          ;修改数据区指针-------------
                    INC R2          ;是否接收到5个字节 ,数据长度为5个字节
                    MOV FagHX,#00H
                    Clr busy
                    POP ACC                 
                 RETI;中断返回               
;=====串口发送字符串信息函数========================================
      SendString:CLR A
                 MOVC A,@A+DPTR             ; 到TABLE取码
                 MOV  SBUF,A                ; 载入SBUF发送
          SCONQ2:JBC  TI,SCONQ3             ; 是否发送完?
                 SJMP SCONQ2
          SCONQ3:INC  DPTR                  ; 取下一个码
                 CJNE A,#0AH,SendString     ; 数据块取码未完成继续取码  发送AXXXV  如果发到0AH则结束
                 MOV A,FagHX      
              RET
;=========软件延时函数================================================         
      Dly200ms:  Mov    R1,#20            ; 20X10MS=200ms秒延时子程序
           DL3:  Call   Delay
                    Djnz   R1,DL3
                Ret
   Dly100ms:  Mov    R1,#10            ; 20X10MS=200ms秒延时子程序
           DL2:  Call   Delay
                    Djnz   R1,DL2
               Ret         
         Delay:MOV R7,#01H                ;误差 0.000000000000us  3.6864M 10ms
           DL1:MOV R6,#0DEH
           DL0:MOV R5,#28H
                 DJNZ R5,$
                 DJNZ R6,DL0
                 DJNZ R7,DL1
            RET
;====PWM对应亮度的可控硅电压设置=============================
LED_OFF:DB 'A020V',0DH,0AH     ;关机控制命令
LED_ON:DB 'A030V',0DH,0AH      ;开机默认亮度
LED_AC1:DB 'A030V',0DH,0AH     ;第一档亮度控制
LED_AC2:DB 'A080V',0DH,0AH     ;第二档亮度控制
LED_AC3:DB 'A100V',0DH,0AH     ;第三档亮度控制
LED_AC4:DB 'A140V',0DH,0AH     ;第四档亮度控制
LED_AC5:DB 'A220V',0DH,0AH     ;第五档亮度控制
LED_Sleep:DB 'A030V',0DH,0AH   ;睡眠模式亮度控制
LED_Warm:DB 'A070V',0DH,0AH    ;温馨模式亮度控制
LED_Reading:DB 'A190V',0DH,0AH ;阅读模式亮度控制
LED_Bright:DB 'A220V',0DH,0AH  ;明亮模式亮度控制
LED_Moon:DB 'A040V',0DH,0AH    ;夜灯模式亮度控制

  END

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:421538 发表于 2018-11-9 09:25 | 只看该作者
现在是如果第4字节是#04H,可以执行LOOP1循环,当下次数据第4字节不是#04H时,要退出LOOP1循环,不不知道错在哪里。BUSY是判断是否执行循环的,为1执行LOOP1循环,为0不执行LOOP1循环
回复

使用道具 举报

板凳
ID:401564 发表于 2018-11-10 00:32 | 只看该作者
从这之后中断就关了,BUSY就一直是1,不会再再有中断去改变了,所以,就一直在LOOP1这循环了,检测字节的条件满足之后,应该是要重新打开中断的吧
回复

使用道具 举报

地板
ID:421538 发表于 2018-11-10 11:54 | 只看该作者
感谢帮助,修改了一下,程序正常运行,达到我的功能
在发送一帧数据前关闭中断,发完一帧数据后重新打开中断
;=====串口发送字符串信息函数========================================
      SendString:
                 CLR ES                     ; 禁止串行口中断
                 CLR EA                     ; 禁止CPU中断
                 CLR A
                 MOVC A,@A+DPTR             ; 到TABLE取码
                 MOV  SBUF,A                ; 载入SBUF发送
          SCONQ2:JBC  TI,SCONQ3             ; 是否发送完?
                 SJMP SCONQ2
          SCONQ3:INC  DPTR                  ; 取下一个码
                 CJNE A,#0AH,SendString     ; 数据块取码未完成继续取码  发送AXXXV  如果发到字母V(ACSII码56H)则结束
                 SETB ES                    ; 允许串行口中断
                 SETB EA                    ; CPU开中断
            RET
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表