laoliang3064的笔记 https://bbs.21ic.com/?589657 [收藏] [复制] [RSS]

日志

第一个汇编程序

已有 858 次阅读2010-6-15 00:59 |系统分类:单片机

   我很庆幸,我的第一个51程序是从汇编开始的。


      说来惭愧,本来应该是上学的时候该做的事,现在才捡起来。


      这是个简单的51程序,ds1302时钟加定时控制继电器开关,过几天再加上红外遥控。程序还不完善,真处在调试阶段。


     以下是程序片段:


 


;********************************************************************************
;*  标题:定时控制继电器开关                                                  *
;*  文件:powercontroller.asm                                                 *
;*  日期:  2010-05-12                                                        *
;*  版本:  1.0                                                               *
;*  作者 :laoliang3064@sina.com                                              *                
;*  网站:                                                                   *
;********************************************************************************
;*  描述:                                                                       *
;*        显示实时时间;指定时间继电器合,指定时间继电器分;                     *
;*        按K1一次显示ON,随后小时位闪烁,再按K1一次,分钟位闪烁                *
;         按K1两次显示OFF,随后小时位闪烁,再按K1一次,分钟位闪烁                *


;*        按K2一次设定小时位,按K2两次设定分钟位;                              *   
;*        按K3确定;                                                             *
;*        K4----加                                                              *
;*        K5----减                                                              *
;*                                                                              *
;********************************************************************************
;* 【声明】 此程序仅用于学习与参考,引用请注明版权和作者信息!                  *
;********************************************************************************
IO_DATA     BIT      P1.1  
SCLK          BIT      P1.0
RST            BIT      P1.2
BitCnt         DATA     30H        ; 数据位计数器
ByteCnt      DATA     31H        ; 数据字节计数器
Command   DATA     32H        ; 命令字节地址
RcvDat       DATA     40H        ; 接收数据缓冲区
XmtDat       DATA     50H        ; 发送数据缓冲区


USERDATA    DATA     20H


TIMER1      DATA     21H
TIMER2      DATA     22H
TIMER3      DATA     23H
TIMER4      DATA     24H
TIMER5      DATA     25H


TIMER_ON_H  DATA     28H        ;定时开时间寄存器高位
TIMER_ON_L  DATA     29H        ;定时开时间寄存器低位
TIMER_OFF_H DATA     33H        ;定时关时间寄存器高位
TIMER_OFF_L DATA     34H        ;定时关时间寄存器低位


DATA_KEY    DATA     35H        ;按键编码位
MIN_KEY01   DATA     36H        ;01按键计数
MIN_KEY02   DATA     37H        ;02按键计数


BCD4A       EQU      26H
BCD4B       EQU      27H


 



     ORG 0000H
     JMP MAIN


     ORG   0030H
MAIN:
     CLR   P1.3
     CLR   P1.4
     CLR   P1.5
     CLR   P1.6
     CLR   P1.7
     MOV   SP,#7FH
     MOV   MIN_KEY01,#00H
     MOV   MIN_KEY02,#00H
     MOV   TIMER_ON_H,#07H
     MOV   TIMER_ON_L,#25H
     MOV   TIMER_OFF_H,#00H
     MOV   TIMER_OFF_L,#00H


;*********************设置时钟****************************
Write_Enable:
            MOV Command,#8Eh         ;命令字节为8E
            MOV ByteCnt,#1           ;单字节传送模式
            MOV R0,#XmtDat           ;数据地址覆给R0
            MOV XmtDat,#00h          ;数据内容为0 写入允许
            LCALL Send_Byte          ;调用写入数据子程序
;*******************************当把秒寄存器的第7 位时钟停止位设置为0 时起动时钟开始          


           MOV Command,#80h           ; 命令字节为80
           MOV ByteCnt,#1              ; 单字节传送模式
           MOV R0,#XmtDat               ;数据地址覆给R0
           MOV XmtDat,#00h              ;数据内容为0 振荡器工作允许
           LCALL Send_Byte              ;调用写入数据子程序


;******************************************
Write_Multiplebyte:
           MOV Command,#0BEh            ;命令字节为BEh
           MOV ByteCnt,#8               ;多字节写入模式此模块为8 个
           MOV R0,#XmtDat               ;数据地址覆给R0
           MOV XmtDat,  #58h            ;秒单元内容为59h
           MOV XmtDat+1,#25h            ;分单元内容为59h
           MOV XmtDat+2,#23h            ;时单元内容为19h
           MOV XmtDat+3,#21h            ;日期单元内容为13h
           MOV XmtDat+4,#05h            ;月单元内容为04h
           MOV XmtDat+5,#03h            ;星期单元内容为02h
           MOV XmtDat+6,#10h            ;年单元内容为10h
           MOV XmtDat+7,#0              ;写保护单元内容为00h
           LCALL Send_Byte              ;调用写入数据子程序


;******************时间显示****************
TIME_START:MOV    R2,#100
           MOV    R3,#100
LOOP1:     LCALL  HOU_DIS
        
           LCALL  MIN_DIS
           DJNZ   R2,LOOP1                              
LOOP2:     LCALL  HOU_DIS     
           LCALL  POT_DIS
           LCALL  MIN_DIS
           DJNZ   R3,LOOP2
;LJMP TIME_START
           LCALL  HOU_DIS
           MOV    A,RcvDat                
           CJNE   A,TIMER_ON_H,KEY
           LCALL  MIN_DIS
           MOV    A,RcvDat
           CJNE   A,TIMER_ON_L,KEY
           LCALL BUZZER2
;*******************判断按键**********************
KEY:
    JB   P1.3,TIMER
    JB   P1.4,TIME0
    JB   P1.5,SUR1_1
    JB   P1.6,TIME_ADD_1
    JB   P1.7,TIME_SUB0_1
    LJMP TIME_START


SUR1_1:JMP SUR
TIME_ADD_1:LJMP TIME_ADD
TIME_SUB0_1:LJMP TIME_SUB
;***************************定时*****************************
TIMER:   LCALL BUZZER1                        ;定时
         MOV   R5,MIN_KEY01                   ;按1次
         CJNE  R5,#00H,TER1                        
         MOV   MIN_KEY01,#01H                 ;置按键计数位为01H
         MOV   DATA_KEY,#01H                  ;置按键编码位为01H
         LCALL DIS_ON                         ;显示"ON"
  ;       LCALL FLASH_HOU                     ;小时位闪烁
LCALL TIMER_ON_DIS
       ;  JMP   KEY
         JMP   SUR1


TER1:    CJNE  R5,#01H,TER2                   ;按2次     
         MOV   MIN_KEY01,#02H                 ;置按键计数位为02H
         MOV   DATA_KEY,#01H                  ;置按键编码位为01H
         LCALL TIMER_ON_DIS                   ;分钟位闪烁
         JMP   SUR1


TER2:    CJNE  R5,#02H,TER3                   ;按3次
         MOV   MIN_KEY01,#03H                 ;置按键计数位为03H
         MOV   DATA_KEY,#01H                  ;置按键编码位为01H
         LCALL DIS_OFF                        ;显示OFF
         LCALL TIMER_OFF_DIS                  ;小时位闪烁
         JMP   SUR
TER3:    CJNE  R5,#03H,TER4                   ;按4次
         MOV   MIN_KEY01,#04H                 ;置按键计数位为04H
         MOV   DATA_KEY,#01H                  ;置按键编码位为01H
         LCALL TIMER_OFF_DIS                  ;分钟位闪烁
         JMP   SUR


TER4:    MOV   MIN_KEY01,#00H
         MOV   DATA_KEY,#00H
         JMP   OUT_KEY
;***************************调时*****************************
TIME0:   LCALL BUZZER1                       ;调时
         MOV  R5,MIN_KEY02                   ;按1次小时位闪烁
         CJNE R5,#00H,TIME1
         MOV  MIN_KEY02,#01H                 ;置按键计数位为01H
         MOV  DATA_KEY,#02H                  ;置按键编码位为02H
         LCALL FLASH_HOU  


TIME1:  ; MOV   R5,MIN_KEY
         CJNE  R5,#01H,TIME2                 ;按2次分钟位闪烁
         MOV   MIN_KEY02,#02H                ;置按键计数位为02H
         MOV   DATA_KEY,#02H                 ;置按键编码位为02H
         LCALL FLASH_MIN      
         JMP   SURE


TIME2:   MOV   MIN_KEY02,#00H
         MOV   DATA_KEY,#00H
         JMP   OUT_KEY
        
         LJMP OUT_KEY


 


SUR1:LJMP SURE



TIME_SUB0:LJMP TIME_SUB
;**************************加******************************
TIME_ADD:LCALL BUZZER1
         MOV   R5,DATA_KEY
         CJNE  R5,#02H,TIMER_ADD
         MOV   R5,MIN_KEY02
         CJNE  R5,#01H,TIME_ADD_MIN        
         LCALL HOU_ADD
         LCALL FLASH_HOU
         LJMP  TIME_START


TIME_ADD_MIN:CJNE R5,#02H,SUR
             LCALL MIN_ADD
             LCALL FLASH_MIN
             LJMP  TIME_START


TIMER_ADD:CJNE  R5,#01H,SUR
          MOV   R5,MIN_KEY01
          CJNE  R5,#01H,TIMER_ADD_MIN
          LCALL HOU_ADD_TIMER
          LJMP  TIME_START


TIMER_ADD_MIN:CJNE  R5,#02H,SUR
              LCALL MIN_ADD_TIMER
              LJMP  TIME_START
             


SUR:LJMP SURE
;**************************减******************************
TIME_SUB:LCALL  BUZZER1
         MOV    R5,DATA_KEY
         CJNE   R5,#02H,TIMER_SUB
         MOV    R5,MIN_KEY02
         CJNE   R5,#01H,TIME_SUB_MIN
         LCALL  HOU_SUB
         LCALL  FLASH_HOU
         LJMP   TIME_START
TIME_SUB_MIN:CJNE  R5,#02H,SUR
             LCALL MIN_SUB
             LCALL FLASH_MIN
             LJMP  TIME_START


TIMER_SUB:CJNE  R5,#01H,SUR
          MOV   R5,MIN_KEY01
          CJNE  R5,#01H,TIMER_SUB_MIN
          LCALL HOU_SUB_TIMER
          LJMP  TIME_START


TIMER_SUB_MIN:CJNE   R5,#02H,SUR
              LCALL  MIN_SUB_TIMER
              LJMP   TIME_START


;****************定时  小时加******************************
HOU_ADD_TIMER:;LCALL DELAY_100MS


              INC   TIMER_ON_H
              MOV   RcvDat,TIMER_ON_H
              LCALL BCD8_1
              MOV   A,TIMER_ON_H
              CJNE  A,#24H,HOU_ADD_TIMER1
              MOV   TIMER_ON_H,#00H
             
     
HOU_ADD_TIMER1:
               MOV     A,BCD4B
               CJNE    A,#0AH,TIMER_HOU_WR            ;小时个位大于10
               ANL     RcvDat,#0F0H             ;个位清零
               MOV     A,#10H                   ;十位加1
               ADD     A,RcvDat
               MOV     TIMER_ON_H,A
                   


TIMER_HOU_WR: LCALL  TIMER_ON_DIS


                  
           RET


HOU_SUB_TIMER:
;****************定时  分钟加******************************
MIN_ADD_TIMER:INC    TIMER_ON_L
              MOV    RcvDat,TIMER_ON_L
              LCALL  BCD8_1
              MOV    A,TIMER_ON_L
              CJNE   A,#5AH,MIN_ADD1_TIMER
              MOV    TIMER_ON_L,#00H
              JMP    MIN_WR_TIMER
               
MIN_ADD1_TIMER:  MOV     A,BCD4B 
           CJNE    A,#0AH,MIN_WR_TIMER          
           ANL     RcvDat,#0F0H              ;个位清零
           MOV     A,#10H                    ;十位加1
           ADD     A,RcvDat
           MOV     RcvDat,A  
           JMP     MIN_WR_TIMER
            
MIN_WR_TIMER:MOV    TIMER_ON_L,RcvDat
             LCALL  TIMER_ON_DIS
             RET
 


MIN_SUB_TIMER:


            
;****************调时  小时加******************************
HOU_ADD:                                   ;显示小时
           MOV     Command,#85h            ;命令字节为85h
           MOV     ByteCnt,#1              ;单字节传送模式
           MOV     R1,#RcvDat              ;数据地址赋给R1
           LCALL   Receive_Byte            ;调用读出数据子程序               
           INC     RcvDat
           LCALL   BCD8_1          
           MOV     A,RcvDat
           CJNE    A,#24H,HOU_ADD1
           MOV     RcvDat,#00H
   
HOU_ADD1:  MOV     A,BCD4B
           CJNE    A,#0AH,HOU_WR            ;小时个位大于10
           ANL     RcvDat,#0F0H             ;个位清零
           MOV     A,#10H                   ;十位加1
           ADD     A,RcvDat
           MOV     RcvDat,A
           JMP     HOU_WR   


HOU_WR:   
           MOV Command,#0BEh            ;命令字节为BEh
           MOV ByteCnt,#8               ;多字节写入模式此模块为8 个
           MOV R0,#XmtDat               ;数据地址覆给R0
           MOV XmtDat+2,RcvDat   
           LCALL Send_Byte
         
           RET
;****************调时  小时减******************************
HOU_SUB:                                   ;显示小时
           MOV     Command,#85h            ;命令字节为85h
           MOV     ByteCnt,#1              ;单字节传送模式
           MOV     R1,#RcvDat              ;数据地址赋给R1
           LCALL   Receive_Byte            ;调用读出数据子程序               
           DEC     RcvDat
           LCALL   BCD8_1
           MOV     A,BCD4B
           CJNE    A,#0FH,HOU_SUB_WR                     
           MOV     A,RcvDat
           CJNE    A,#0FFH,HOU_SUB1          
           MOV     RcvDat,#23H
HOU_SUB1:
           MOV     A,RcvDat
           CJNE    A,#1FH,HOU_SUB2
           MOV     RcvDat,#19H
HOU_SUB2: 
           MOV     A,RcvDat
           CJNE    A,#0FH,HOU_SUB_WR
           MOV     RcvDat,#09H   


HOU_SUB_WR:   
           MOV Command,#0BEh            ;命令字节为BEh
           MOV ByteCnt,#8               ;多字节写入模式此模块为8 个
           MOV R0,#XmtDat               ;数据地址覆给R0
           MOV XmtDat+2,RcvDat   
           LCALL Send_Byte
           RET


 



;****************调时  分钟加******************************
MIN_ADD:   MOV     Command,#83h              ;显示分钟
           MOV     ByteCnt,#1              
           MOV     R1,#RcvDat             
           LCALL   Receive_Byte           
           INC     RcvDat
           LCALL   BCD8_1              
           MOV     A,RcvDat
           CJNE    A,#5AH,MIN_ADD1
           MOV     RcvDat,#00H
           JMP     MIN_WR
MIN_ADD1:  MOV     A,BCD4B 
           CJNE    A,#0AH,MIN_WR          
           ANL     RcvDat,#0F0H              ;个位清零
           MOV     A,#10H                    ;十位加1
           ADD     A,RcvDat
           MOV     RcvDat,A  
           JMP     MIN_WR   


MIN_WR:    MOV Command,#0BEh            ;命令字节为BEh
           MOV ByteCnt,#8               ;多字节写入模式此模块为8 个
           MOV R0,#XmtDat               ;数据地址覆给R0
           MOV XmtDat+1,RcvDat
           LCALL Send_Byte
           RET


SURE:     LCALL BUZZER1
          MOV  DATA_KEY,#00H
          MOV  MIN_KEY01,#00H
          MOV  MIN_KEY02,#00H
          JMP  OUT_KEY


;*********************调时  分钟减*************************
MIN_SUB:   
           MOV     Command,#83h              ;显示分钟
           MOV     ByteCnt,#1              
           MOV     R1,#RcvDat             
           LCALL   Receive_Byte           
           DEC     RcvDat
           LCALL   BCD8_1           
           MOV     A,RcvDat
           CJNE    A,#0FFH,MIN_SUB0
           MOV     RcvDat,#59H
           JMP     MIN_SUB_WR


MIN_SUB0:  CJNE    A,#5FH,MIN_SUB1
           MOV     RcvDat,#59H
           JMP     MIN_SUB_WR
MIN_SUB1:  MOV     A,RcvDat
           CJNE    A,#4FH,MIN_SUB2
           MOV     RcvDat,#49H
           JMP     MIN_SUB_WR
MIN_SUB2:     
           CJNE    A,#3FH,MIN_SUB3 
           MOV     RcvDat,#39H
           JMP     MIN_SUB_WR
MIN_SUB3:  
           CJNE    A,#2FH,MIN_SUB4 
           MOV     RcvDat,#29H
           JMP     MIN_SUB_WR
MIN_SUB4:
           CJNE    A,#1FH,MIN_SUB5 
           MOV     RcvDat,#19H
           JMP     MIN_SUB_WR
MIN_SUB5:
           CJNE    A,#0FH,MIN_SUB_WR 
           MOV     RcvDat,#09H                  
          
           JMP     MIN_SUB_WR   


MIN_SUB_WR:MOV Command,#0BEh                  ;命令字节为BEh
           MOV ByteCnt,#8                     ;多字节写入模式此模块为8 个
           MOV R0,#XmtDat                     ;数据地址覆给R0
           MOV XmtDat+1,RcvDat  


    


           MOV XmtDat+7,#0                    ;写保护单元内容为00h
           LCALL Send_Byte                    ;调用写入数据子程序                 
           RET


 


;***************小时位闪烁**********************
FLASH_HOU: MOV   R4,#10             ;闪烁次数
FLASH_1:   MOV   R2,#100            ;数码管亮时间        
           MOV   R3,#100            ;数码管灭时间
      
FLASH_2:  SETB  P0.0
          SETB  P0.1
          LCALL POT_DIS
          LCALL MIN_DIS
          DJNZ  R3,FLASH_2


FLASH_3:  LCALL  HOU_DIS
          LCALL  POT_DIS
          LCALL  MIN_DIS
          DJNZ   R2,FLASH_3
          LCALL    KEY_SEC
          DJNZ   R4,FLASH_1
          JMP    OUT_KEY


KEY_SEC: JB   P1.3,P13
         JB   P1.4,P14
         JB   P1.5,P15
         JB   P1.6,P16
         JB   P1.7,P17
         RET


P13:     LJMP TIMER
P14:     LJMP TIME0
P15:     LJMP SURE
P16:     LJMP TIME_ADD
P17:     LJMP TIME_SUB


OUT_KEY: LJMP TIME_START
;***************分钟位闪烁**********************


FLASH_MIN:MOV   R4,#10             ;闪烁次数
FLASH_11: MOV   R2,#100            ;数码管亮时间        
          MOV   R3,#100            ;数码管灭时间
      
FLASH_22: SETB  P0.2
          SETB  P0.3
          LCALL POT_DIS
          LCALL HOU_DIS
          DJNZ  R3,FLASH_22


FLASH_33: LCALL  HOU_DIS
          LCALL  POT_DIS
          LCALL  MIN_DIS
          DJNZ   R2,FLASH_33
          LCALL  KEY_SEC1
          DJNZ   R4,FLASH_11
          JMP    OUT_KEY


KEY_SEC1:JB   P1.3,P13
         JB   P1.4,P14
         JB   P1.5,P15
         JB   P1.6,P16
         JB   P1.7,P17
         RET


OUT_KEY1:LJMP TIME_START



 


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)