您的位置:控制工程论坛网论坛 » 电机与运动控制 » 3步进马达控制系统程序源代码

dhmhl

dhmhl   |   当前状态:离线

总积分:360  2025年可用积分:0

注册时间: 2007-12-17

最后登录时间: 2009-06-25

空间 发短消息加为好友

3步进马达控制系统程序源代码

dhmhl  发表于 2007/12/20 15:03:00      1161 查看 1 回复  [上一主题]  [下一主题]

手机阅读

;*************************************
;File name           :  sanjiaotiaoshi
;chip type           :  atmel mega8
;programe type       :  application
;clock frequency     :  4MHZ
;memory model        :  small
;External SRAM size  :  0
;*************************************
;此程序是调试机头三角用程序
;共有三个马达,分别由PB,PC的IO口控制
;
;
.include "m8def.inc"         ;包含器件定义头文件


;---------------------------------------------------------
;管脚定义


.EQU        P_MOTOR_1           =PORTB     ;PB0,1,6,7   为左边步进电机的驱动口
.EQU        P_MOTOR_2           =PORTB     ;PB2,3,4,5   为右边步进电机的驱动口
.EQU        P_MOTOR_3           =PORTC     ;PC0,1,2,3   为中间步进电机的驱动口


.EQU        P_INDUCTOR1         =PIND
.EQU        P_INDUCTOR2         =PINC      ;PIND&PINC   作感应器输入检测IO
.EQU        B_L                 =5         ;PD5         为左边感应器输入检测口
.EQU        B_R                 =6         ;PD6         为右边感应器输入检测口
.EQU        B_M                 =7         ;PD7         为中间感应器输入检测口
.EQU        B_M2                =5         ;PC4         为中间另一感应器输入检测口


.EQU        P_KEY               =PIND      ;PIND        作按键检测IO
.EQU        B_ZERO              =0         ;PD0         为归零按键检测口
.EQU        B_SLR               =1         ;PD1         为左右马达单次左右转动控制按键检测口
.EQU        B_SM                =2         ;PD2         为中间马达单次左右转动控制按键检测口
.EQU        B_CLR               =3         ;PD3         为左右马达循环左右转动控制按键检测口
.EQU        B_CM                =4         ;PD4         为中间马达循环左右转动控制按键检测口



;-----------------------------------------------------------
;寄存器定义
.DEF        TEMP                =R16
.DEF        P_CONTROL_MOTOR     =R17        ;马达控制寄存器
.EQU        B_lMOTOR            =0
.EQU        B_rMOTOR            =1
.EQU        B_mMOTOR            =2
.EQU        B_lM_TL             =3           ;马达转动方向控制寄存器位
.EQU        B_rM_TL             =4
.EQU        B_mM_TL             =5


.DEF        TEMP_MOTOR          =R18


.DEF        P_STEP_MARK         =R19          ;马达是否应转动寄存器
.EQU        B_MARK_L_MOTOR      =0
.EQU        B_MARK_R_MOTOR      =1
.EQU        B_MARK_M_MOTOR      =2


 


.DEF        COUNT_STEP          =R20          ;马达转动步数计数器
.DEF        np                  =R21          ;马达转动时,数据表位置计数器


.DEF        TEMP2               =R22
.DEF        FIRST_COUNT         =R23


;-----------------------------------------------------------
;数值定义
.EQU        ARITH_MOTOR_1       =0B00111100      ;计算左边马达输出数据中间用数值
.EQU        ARITH_MOTOR_2       =0B11000011      ;计算右边马达输出数据中间用数值
.EQU        ARITH_MOTOR_3       =0B11110000      ;计算中间马达输出数据中间用数值


.EQU        L_MOTOR_ANGLE       =100
.EQU        R_MOTOR_ANGLE       =100
.EQU        M_MOTOR_ANGLE1      =50
.EQU        M_MOTOR_ANGLE2      =150


.EQU        DIRECT_L_MOTOR_EOR    =0B00001000             ;马达转动方向取反位
.EQU        DIRECT_R_MOTOR_EOR    =0B00010000
.EQU        DIRECT_M_MOTOR_EOR    =0B00100000


.EQU        DIRECT_MARK_TIME      =0B00001000
;-----------------------------------------------------------
;宏定义
.macro      MAC_SEND_MOTOR                ;从表中取数送至相应的步进电机驱动控制口     


            LPM
   IN               TEMP,@0
   ANDI             TEMP,@1
   OR               TEMP,R0
   OUT              @0,TEMP
.endmacro
.macro      MAC_TRAN_MOTOR                ;从表中取数转化成可以送到步进电机驱动口的数据存入至电机数据寄存器     


            LPM
   IN               TEMP,@0
   ANDI             TEMP,@1
   OR               TEMP,R0
   MOV              @2,TEMP
.endmacro


.macro      MAC_TRAN_DATA
           
   IN               TEMP,@0
   ANDI             TEMP,@1
   LDI              TEMP2,@2
   OR               TEMP,TEMP2
   OUT              @0,TEMP
.endmacro
.CSEG
;-----------------------------------------------------------
;程序复位起始地址
.ORG        0X00
                 RJMP       RESET
.ORG        0X0020


RESET:
            LDI             ZL,LOW(RAMEND)     ;设置堆栈指针为RAM底部
   OUT             SPL,ZL
   LDI             ZL,HIGH(RAMEND)
   OUT             SPH,ZL
           RCALL     CLEAR_RAM          ;清RAM
;----------
;IO初始化


            LDI             TEMP,0XFF       ;IO方向初始化
   OUT             DDRB,TEMP
   LDI             TEMP,0X0F
   OUT             DDRC,TEMP
   LDI             TEMP,0X00
   OUT             DDRD,TEMP      



            LDI             TEMP,0X00       ;IO数据初始化
   OUT             PORTB,TEMP
   LDI             TEMP,0X70
   OUT             PORTC,TEMP
   LDI             TEMP,0XFF
   OUT             PORTD,TEMP


   LDI             TEMP,0X00                    ;?????????????待定
   STS             L_MOTOR_POSITION,TEMP
   LDI             TEMP,0X00
   STS             R_MOTOR_POSITION,TEMP
   LDI             TEMP,0X00
   STS             M_MOTOR_POSITION,TEMP



;---------
;按键检测
KEY_CHECK:
            LDI             TEMP,0X00
   OUT             P_MOTOR_1,TEMP
            MAC_TRAN_DATA   P_MOTOR_3,0XF0,0X00    ;所有成达驱动口全部输出"0"即停止所有马达转动
KEY_CHECK2:
            SBIS            P_KEY,B_ZERO
   RJMP     ALL_TO_ZERO2      ;转入归零程序处
      SBIS            P_KEY,B_SLR
   RJMP     LR_MOV_ONCE2      ;转入左右马达转动一个行程程序处
   SBIS            P_KEY,B_SM
   RJMP     M_MOV_ONCE2       ;转入中间马达转动一个行程程序处
   SBIS            P_KEY,B_CLR
   RJMP     LR_MOV_CIRCLE2    ;转入左右马达循环转动程序处
;   SBIS            P_KEY,B_CM
;   RJMP     M_MOV_CIRCLR2     ;转入中间马达循环转动程序处
           
            RJMP     KEY_CHECK2  ;继续检测按键
;-----------
;等待按键释放程序                                    
KEY_ZERO:
            SBIS            P_KEY,B_ZERO
   RJMP     KEY_ZERO
   RJMP     KEY_CHECK
KEY_SLR:
            SBIS            P_KEY,B_SLR
   RJMP     KEY_SLR
   RJMP     KEY_CHECK
KEY_SM:
            SBIS            P_KEY,B_SM
   RJMP     KEY_SM
   RJMP     KEY_CHECK
KEY_CLR:
            SBIS            P_KEY,B_CLR
   RJMP     KEY_CLR
   RJMP     KEY_CHECK
KEY_CM:
            SBIS            P_KEY,B_CM
   RJMP     KEY_CM
   RJMP     KEY_CHECK
;----------
;按键延时消抖
ALL_TO_ZERO2:                                 ;----归零按键检测延时消抖程序
            RCALL    DELAY 
   RCALL    DELAY          
      SBIC            P_KEY,B_ZERO
   RJMP     KEY_CHECK
      RCALL    DELAY
      RJMP     ALL_TO_ZERO
LR_MOV_ONCE2:                                 ;----左右马达转动一个行程控制按键检测延时消抖程序
            RCALL    DELAY 
   RCALL    DELAY          
      SBIC            P_KEY,B_SLR
   RJMP     KEY_CHECK
      RCALL    DELAY
      RJMP     LR_MOV_ONCE
M_MOV_ONCE2:                                  ;----中间马达转动一个行程控制按键检测延时消抖程序
            RCALL    DELAY
   RCALL    DELAY           
      SBIC            P_KEY,B_SM
   RJMP     KEY_CHECK
      RCALL    DELAY
      RJMP     M_MOV_ONCE
LR_MOV_CIRCLE2:                               ;----左右马达循环转动控制按键检测延时消抖程序
            RCALL    DELAY  
   RCALL    DELAY         
      SBIC            P_KEY,B_CLR
   RJMP     KEY_CHECK
      RCALL    DELAY
   RJMP     LR_MOV_CIRCLE
;M_MOV_CIRCLE2:                                ;----中间马达循环转动控制按键检测延时消抖程序
; ;           RCALL    DELAY   
;   RCALL    DELAY        
;      SBIC            P_KEY,B_CM
;   RJMP     KEY_CHECK
;      RCALL    DELAY
;   RJMP     M_MOV_CIRCLE
;********--------------                                                                                      -------------\
;归零程序
ALL_TO_ZERO:
            SBIS            P_KEY,B_ZERO                 ;按键是否释放
   RJMP     ALL_TO_ZERO


   CLR             FIRST_COUNT


            MOV             TEMP,P_CONTROL_MOTOR
   ANDI            TEMP,0XF8
   LDI             TEMP2,0X00
   OR              TEMP,TEMP2
   MOV             P_CONTROL_MOTOR,TEMP           ;将马达使能位全部置"0"


            SBIC            P_INDUCTOR1,B_L
   SBR             P_CONTROL_MOTOR,(1<<B_lMOTOR)  ;左边马达若不处在零点,则置位左边马达使能位
   SBIC            P_INDUCTOR1,B_R
   SBR             P_CONTROL_MOTOR,(1<<B_rMOTOR)  ;右边马达若不处在零点,则置位右边马达使能位
   SBIC            P_INDUCTOR1,B_M
   SBR             P_CONTROL_MOTOR,(1<<B_mMOTOR)  ;中间马达若不处在零点,则置位中间马达使能位
;----------
;左边马达归零
L_MOTOR_ZERO:
            LDI             TEMP,0X00
   OUT             P_MOTOR_1,TEMP
            MAC_TRAN_DATA   P_MOTOR_3,0XF0,0X00    ;所有成达驱动口全部输出"0"即停止所有马达转动
L_MOTOR_ZERO2:
            SBRS            P_CONTROL_MOTOR,B_lMOTOR       ;左边马达若不在零点,即使能位为"1"则执行左边马达归零程序
   RJMP     R_MOTOR_ZERO                          ;否则跳至右边马达归零程序处
L_MOV_ZERO_START:
   CLR             np
            SBRS            P_CONTROL_MOTOR,B_lM_TL        ;向左转动控制位是否使能,即是否为"1",若为"1"则向左转动,
   RJMP     L_MOTOR_R_TABLE                       ;否则向右转动
            LDI             ZL,LOW(LmotorLmovTable*2)     
            LDI             ZH,HIGH(LmotorLmovTable*2)     ;左转动表首地址入Z
   RJMP     L_MOVE_ZERO
L_MOTOR_R_TABLE:
            LDI             ZL,LOW(LmotorRmovTable*2)
            LDI             ZH,HIGH(LmotorRmovTable*2)     ;右转动表首地址入Z
L_MOVE_ZERO:
            SBIS            P_INDUCTOR1,B_L
   RJMP      R_MOTOR_ZERO                         ;若到零点,则左边马达停,进入右边马达归零程序


            PUSH            ZL
   ADD             ZL,np
            MAC_TRAN_MOTOR  P_MOTOR_1,ARITH_MOTOR_1,TEMP_MOTOR  ;马达驱动数据存入TEMP_MOTOR
            INC             np
   POP             ZL
            CPI             TEMP_MOTOR,0X00
            BREQ      L_MOV_ZERO_START
            SBRC            P_STEP_MARK,B_MARK_L_MOTOR
            RJMP      SEND_DATA_ZERO
            LDS             TEMP,L_MOTOR_POSITION
            CP              TEMP_MOTOR,TEMP
   BRNE      L_CHECK_ZERO_GOON
   SBR             P_STEP_MARK,(1<<B_MARK_L_MOTOR)
L_CHECK_ZERO_GOON:
            RJMP      L_MOVE_ZERO
SEND_DATA_ZERO:
            STS             L_MOTOR_POSITION,TEMP_MOTOR    ;保存转动位置数据
            OUT             P_MOTOR_1,TEMP_MOTOR           ;送驱动数据到驱动口
   RCALL     DELAY
   SBIS            P_KEY,B_ZERO
   RJMP      KEY_ZERO                            ;归零键是否按下,若按下则停止转动
   INC             COUNT_STEP
            CPI             COUNT_STEP,L_MOTOR_ANGLE        ;是否到转到角度允许范围
   BRLO      L_MOVE_ZERO                           ;未到则继续检测是否归零并转动
   CLR             COUNT_STEP
   LDI             TEMP,DIRECT_L_MOTOR_EOR
   EOR             P_CONTROL_MOTOR,TEMP                ;若到转动范围则将转动方向取反
   CBR             P_STEP_MARK,(1<<B_MARK_L_MOTOR)
            RJMP      L_MOVE_ZERO
;----------
;右边马达归零
R_MOTOR_ZERO:
            LDI             TEMP,0X00
   OUT             P_MOTOR_1,TEMP
            MAC_TRAN_DATA   P_MOTOR_3,0XF0,0X00    ;所有成达驱动口全部输出"0"即停止所有马达转动
R_MOTOR_ZERO2:
            SBRS            P_CONTROL_MOTOR,B_rMOTOR       ;右边马达若不在零点,即使能位为"1"则执行右边马达归零程序
   RJMP     M_MOTOR_ZERO                          ;否则跳至中间马达归零程序处
R_MOV_ZERO_START:
   CLR             np
            SBRS            P_CONTROL_MOTOR,B_rM_TL        ;向左转动控制位是否使能,即是否为"1",若为"1"则向左转动,
   RJMP     R_MOTOR_R_TABLE                       ;否则向右转动
            LDI             ZL,LOW(RmotorLmovTable*2)     
            LDI             ZH,HIGH(RmotorLmovTable*2)     ;左转动表首地址入Z
   RJMP     R_MOVE_ZERO    
R_MOTOR_R_TABLE:
            LDI             ZL,LOW(RmotorRmovTable*2)
            LDI             ZH,HIGH(RmotorRmovTable*2)     ;右转动表首地址入Z 
R_MOVE_ZERO:
            SBIS            P_INDUCTOR1,B_R
   RJMP      M_MOTOR_ZERO                         ;若到零点,则右边马达停,进入中间马达归零程序


            PUSH            ZL
   ADD             ZL,np
            MAC_TRAN_MOTOR  P_MOTOR_2,ARITH_MOTOR_2,TEMP_MOTOR  ;马达驱动数据存入TEMP_MOTOR
            INC             np
   POP             ZL
            CPI             TEMP_MOTOR,0X00
            BREQ      R_MOV_ZERO_START
            SBRC            P_STEP_MARK,B_MARK_R_MOTOR
            RJMP      SEND_DATA_ZERO_R
            LDS             TEMP,R_MOTOR_POSITION
            CP              TEMP_MOTOR,TEMP
   BRNE      R_CHECK_ZERO_GOON
   SBR             P_STEP_MARK,(1<<B_MARK_R_MOTOR)
R_CHECK_ZERO_GOON:
            RJMP      R_MOVE_ZERO
SEND_DATA_ZERO_R:
            STS             R_MOTOR_POSITION,TEMP_MOTOR    ;保存转动位置数据
            OUT             P_MOTOR_2,TEMP_MOTOR           ;送驱动数据到驱动口
   RCALL     DELAY
   SBIS            P_KEY,B_ZERO
   RJMP      KEY_ZERO                            ;归零键是否按下,若按下则停止转动
   INC             COUNT_STEP
            CPI             COUNT_STEP,R_MOTOR_ANGLE        ;是否到转到角度允许范围
   BRLO      R_MOVE_ZERO                           ;未到则继续检测是否归零并转动
   CLR             COUNT_STEP
   LDI             TEMP,DIRECT_R_MOTOR_EOR
   EOR             P_CONTROL_MOTOR,TEMP                ;若到转动范围则将转动方向取反
   CBR             P_STEP_MARK,(1<<B_MARK_R_MOTOR)
            RJMP      R_MOVE_ZERO
;----------
;中间马达归零
M_MOTOR_ZERO:
            LDI             TEMP,0X00
   OUT             P_MOTOR_1,TEMP
            MAC_TRAN_DATA   P_MOTOR_3,0XF0,0X00    ;所有成达驱动口全部输出"0"即停止所有马达转动
M_MOTOR_ZERO2:
            SBRS            P_CONTROL_MOTOR,B_mMOTOR       ;中间马达若不在零点,即使能位为"1"则执行中间马达归零程序
   RJMP      KEY_CHECK                            ;否则跳至按键检测程序处
M_MOV_ZERO_START:
   CLR             np
            SBRS            P_CONTROL_MOTOR,B_mM_TL        ;向左转动控制位是否使能,即是否为"1",若为"1"则向左转动,
   RJMP     M_MOTOR_R_TABLE                       ;否则向右转动
            LDI             ZL,LOW(MmotorLmovTable*2)     
            LDI             ZH,HIGH(MmotorLmovTable*2)     ;左转动表首地址入Z
   RJMP     M_MOVE_ZERO
M_MOTOR_R_TABLE:
            LDI             ZL,LOW(MmotorRmovTable*2)
            LDI             ZH,HIGH(MmotorRmovTable*2)     ;右转动表首地址入Z
M_MOVE_ZERO:
            SBIS            P_INDUCTOR1,B_M
   RJMP      KEY_CHECK                         ;若到零点,则中间马达停,进入按键检测程序


            PUSH            ZL
   ADD             ZL,np
            MAC_TRAN_MOTOR  P_MOTOR_3,ARITH_MOTOR_3,TEMP_MOTOR  ;马达驱动数据存入TEMP_MOTOR
            INC             np
   POP             ZL
            CPI             TEMP_MOTOR,0X00
            BREQ      M_MOV_ZERO_START
            SBRC            P_STEP_MARK,B_MARK_M_MOTOR
            RJMP      SEND_DATA_ZERO_M
            LDS             TEMP,M_MOTOR_POSITION
            CP              TEMP_MOTOR,TEMP
   BRNE      M_CHECK_ZERO_GOON
   SBR             P_STEP_MARK,(1<<B_MARK_M_MOTOR)
M_CHECK_ZERO_GOON:
            RJMP      M_MOVE_ZERO
SEND_DATA_ZERO_M:
            STS             M_MOTOR_POSITION,TEMP_MOTOR    ;保存转动位置数据
            OUT             P_MOTOR_3,TEMP_MOTOR           ;送驱动数据到驱动口
   RCALL     DELAY
   SBIS            P_KEY,B_ZERO
   RJMP      KEY_ZERO                            ;归零键是否按下,若按下则停止转动
   INC             COUNT_STEP
            CPI             COUNT_STEP,M_MOTOR_ANGLE1        ;是否到转到角度允许范围
   BRLO      M_MOVE_ZERO                           ;未到则继续检测是否归零并转动
   CLR             COUNT_STEP
   LDI             TEMP,DIRECT_M_MOTOR_EOR
   EOR             P_CONTROL_MOTOR,TEMP                ;若到转动范围则将转动方向取反
   CBR             P_STEP_MARK,(1<<B_MARK_M_MOTOR)
            RJMP      M_MOVE_ZERO
                                                                                           ;------------------/
;***********-----------
;左右马达动作一个行程程序
LR_MOV_ONCE:
            SBIS            P_KEY,B_SLR
   RJMP      LR_MOV_ONCE                   ;等待按键释放
;--------------
;左边马达动作一个行程
L_MOTOR_ONCE:
   CLR             np
            SBRS            P_CONTROL_MOTOR,B_lM_TL        ;向左转动控制位是否使能,即是否为"1",若为"1"则向左转动,
   RJMP     L_MOTOR_R_ONCE_TABLE                       ;否则向右转动
            LDI             ZL,LOW(LmotorLmovTable*2)     
            LDI             ZH,HIGH(LmotorLmovTable*2)     ;左转动表首地址入Z
   RJMP     L_MOVE_ONCE
L_MOTOR_R_ONCE_TABLE:
            LDI             ZL,LOW(LmotorRmovTable*2)
            LDI             ZH,HIGH(LmotorRmovTable*2)     ;右转动表首地址入Z  
   
L_MOVE_ONCE:


            PUSH            ZL
   ADD             ZL,np
            MAC_TRAN_MOTOR  P_MOTOR_1,ARITH_MOTOR_1,TEMP_MOTOR  ;马达驱动数据存入TEMP_MOTOR
            INC             np
   POP             ZL
            CPI             TEMP_MOTOR,0X00
            BREQ      L_MOTOR_ONCE
            SBRC            P_STEP_MARK,B_MARK_L_MOTOR
            RJMP      SEND_DATA_ONCE_L
            LDS             TEMP,L_MOTOR_POSITION
            CP              TEMP_MOTOR,TEMP
   BRNE      L_CHECK_ONCE_GOON
   SBR             P_STEP_MARK,(1<<B_MARK_L_MOTOR)
L_CHECK_ONCE_GOON:
            RJMP      L_MOVE_ZERO
SEND_DATA_ONCE_L:
            STS             L_MOTOR_POSITION,TEMP_MOTOR    ;保存转动位置数据
            OUT             P_MOTOR_1,TEMP_MOTOR           ;送驱动数据到驱动口
   RCALL     DELAY
   INC             COUNT_STEP
            CPI             COUNT_STEP,L_MOTOR_ANGLE        ;是否到转到角度允许范围
   BRLO      L_MOVE_ONCE                           ;未到则继续转动
   CLR             COUNT_STEP
   LDI             TEMP,DIRECT_L_MOTOR_EOR
   EOR             P_CONTROL_MOTOR,TEMP                ;若到转动范围则将转动方向取反
   CBR             P_STEP_MARK,(1<<B_MARK_L_MOTOR)
            RJMP      R_MOTOR_ONCE
;--------------
;右边马达动作一个行程   
R_MOTOR_ONCE:      
   CLR             np
            SBRS            P_CONTROL_MOTOR,B_rM_TL        ;向左转动控制位是否使能,即是否为"1",若为"1"则向左转动,
   RJMP     R_MOTOR_R_ONCE_TABLE                       ;否则向右转动
            LDI             ZL,LOW(RmotorLmovTable*2)     
            LDI             ZH,HIGH(RmotorLmovTable*2)     ;左转动表首地址入Z
   RJMP     R_MOVE_ONCE
R_MOTOR_R_ONCE_TABLE:
            LDI             ZL,LOW(RmotorRmovTable*2)
            LDI             ZH,HIGH(RmotorRmovTable*2)     ;右转动表首地址入Z  
   
R_MOVE_ONCE:


            PUSH            ZL
   ADD             ZL,np
            MAC_TRAN_MOTOR  P_MOTOR_2,ARITH_MOTOR_2,TEMP_MOTOR  ;马达驱动数据存入TEMP_MOTOR
            INC             np
   POP             ZL
            CPI             TEMP_MOTOR,0X00
            BREQ      R_MOTOR_ONCE
            SBRC            P_STEP_MARK,B_MARK_R_MOTOR
            RJMP      SEND_DATA_ONCE_R
            LDS             TEMP,R_MOTOR_POSITION
            CP              TEMP_MOTOR,TEMP
   BRNE      R_CHECK_ONCE_GOON
   SBR             P_STEP_MARK,(1<<B_MARK_R_MOTOR)
R_CHECK_ONCE_GOON:
            RJMP      R_MOVE_ONCE
SEND_DATA_ONCE_R:
            STS             R_MOTOR_POSITION,TEMP_MOTOR    ;保存转动位置数据
            OUT             P_MOTOR_2,TEMP_MOTOR           ;送驱动数据到驱动口
   RCALL     DELAY
   INC             COUNT_STEP
            CPI             COUNT_STEP,R_MOTOR_ANGLE        ;是否到转到角度允许范围
   BRLO      R_MOVE_ONCE                           ;未到则继续转动
   CLR             COUNT_STEP
   LDI             TEMP,DIRECT_R_MOTOR_EOR
   EOR             P_CONTROL_MOTOR,TEMP                ;若到转动范围则将转动方向取反
   CBR             P_STEP_MARK,(1<<B_MARK_R_MOTOR)
            RJMP      KEY_CHECK            
;***********-----------
;中间马达动作一个行程程序
M_MOV_ONCE:
            SBIS            P_KEY,B_SM
   RJMP      M_MOV_ONCE                   ;等待按键释放
            INC             FIRST_COUNT
M_MOTOR_ONCE_START:
   CLR             np
            SBRS            P_CONTROL_MOTOR,B_mM_TL        ;向左转动控制位是否使能,即是否为"1",若为"1"则向左转动,
   RJMP     M_MOTOR_R_ONCE_TABLE                       ;否则向右转动
            LDI             ZL,LOW(MmotorLmovTable*2)     
            LDI             ZH,HIGH(MmotorLmovTable*2)     ;左转动表首地址入Z
   RJMP     M_MOVE_ONCE
M_MOTOR_R_ONCE_TABLE:
            LDI             ZL,LOW(MmotorRmovTable*2)
            LDI             ZH,HIGH(MmotorRmovTable*2)     ;右转动表首地址入Z  
   
M_MOVE_ONCE:


            PUSH            ZL
   ADD             ZL,np
            MAC_TRAN_MOTOR  P_MOTOR_3,ARITH_MOTOR_3,TEMP_MOTOR  ;马达驱动数据存入TEMP_MOTOR
            INC             np
   POP             ZL
            CPI             TEMP_MOTOR,0X00
            BREQ      M_MOTOR_ONCE_START
            SBRC            P_STEP_MARK,B_MARK_M_MOTOR
            RJMP      SEND_DATA_ONCE_M
            LDS             TEMP,M_MOTOR_POSITION
            CP              TEMP_MOTOR,TEMP
   BRNE      M_CHECK_ONCE_GOON
   SBR             P_STEP_MARK,(1<<B_MARK_M_MOTOR)
M_CHECK_ONCE_GOON:
            RJMP      M_MOVE_ONCE
SEND_DATA_ONCE_M:
            STS             M_MOTOR_POSITION,TEMP_MOTOR    ;保存转动位置数据
            OUT             P_MOTOR_3,TEMP_MOTOR           ;送驱动数据到驱动口
   RCALL     DELAY
   INC             COUNT_STEP


   CPI             FIRST_COUNT,2
   BRSH      COMP_ANGLE2
            CPI             COUNT_STEP,M_MOTOR_ANGLE1       ;是否到转到角度允许范围
   BRLO      M_MOVE_ONCE                           ;未到则继续转动
   RJMP      CLR_COUNT_STEP
COMP_ANGLE2:
            CPI             COUNT_STEP,M_MOTOR_ANGLE2
   BRLO      M_MOVE_ONCE
CLR_COUNT_STEP:
   CLR             COUNT_STEP
   LDI             TEMP,DIRECT_M_MOTOR_EOR
   EOR             P_CONTROL_MOTOR,TEMP                ;若到转动范围则将转动方向取反
   CBR             P_STEP_MARK,(1<<B_MARK_M_MOTOR)
            RJMP      KEY_CHECK  


;***********-----------
;左右马达循环动作程序
LR_MOV_CIRCLE:
            SBIS            P_KEY,B_CLR
   RJMP      LR_MOV_CIRCLE
;-----------------
;左边马达循环动作
L_MOTOR_CIRCLE:
   CLR             np
            SBRS            P_CONTROL_MOTOR,B_lM_TL        ;向左转动控制位是否使能,即是否为"1",若为"1"则向左转动,
   RJMP     L_MOTOR_R_CIRCLE_TABLE                       ;否则向右转动
            LDI             ZL,LOW(LmotorLmovTable*2)     
            LDI             ZH,HIGH(LmotorLmovTable*2)     ;左转动表首地址入Z
   RJMP     L_MOVE_CIRCLE
L_MOTOR_R_CIRCLE_TABLE:
            LDI             ZL,LOW(LmotorRmovTable*2)
            LDI             ZH,HIGH(LmotorRmovTable*2)     ;右转动表首地址入Z  
   
L_MOVE_CIRCLE:


            PUSH            ZL
   ADD             ZL,np
            MAC_TRAN_MOTOR  P_MOTOR_1,ARITH_MOTOR_1,TEMP_MOTOR  ;马达驱动数据存入TEMP_MOTOR
            INC             np
   POP             ZL
            CPI             TEMP_MOTOR,0X00
            BREQ      L_MOTOR_CIRCLE
            SBRC            P_STEP_MARK,B_MARK_L_MOTOR
            RJMP      SEND_DATA_CIRCLE_L
            LDS             TEMP,L_MOTOR_POSITION
            CP              TEMP_MOTOR,TEMP
   BRNE      L_CHECK_CIRCLE_GOON
   SBR             P_STEP_MARK,(1<<B_MARK_L_MOTOR)
L_CHECK_CIRCLE_GOON:
            RJMP      L_MOVE_CIRCLE
SEND_DATA_CIRCLE_L:
            STS             L_MOTOR_POSITION,TEMP_MOTOR    ;保存转动位置数据
            OUT             P_MOTOR_1,TEMP_MOTOR           ;送驱动数据到驱动口
   RCALL     DELAY
   SBIS            P_KEY,B_CLR
   RJMP      KEY_CLR                            ;左右循环动作键是否按下,若按下则停止转动
   INC             COUNT_STEP
            CPI             COUNT_STEP,L_MOTOR_ANGLE        ;是否到转到角度允许范围
   BRLO      L_MOVE_CIRCLE                           ;未到则继续转动
   CLR             COUNT_STEP
   LDI             TEMP,DIRECT_L_MOTOR_EOR
   EOR             P_CONTROL_MOTOR,TEMP                ;若到转动范围则将转动方向取反
   CBR             P_STEP_MARK,(1<<B_MARK_L_MOTOR)
            RJMP      R_MOTOR_CIRCLE
;-----------------
;右边马达循环动作
R_MOTOR_CIRCLE:
   CLR             np
            SBRS            P_CONTROL_MOTOR,B_rM_TL        ;向左转动控制位是否使能,即是否为"1",若为"1"则向左转动,
   RJMP     R_MOTOR_R_CIRCLE_TABLE                       ;否则向右转动
            LDI             ZL,LOW(RmotorLmovTable*2)     
            LDI             ZH,HIGH(RmotorLmovTable*2)     ;左转动表首地址入Z
   RJMP     R_MOVE_CIRCLE
R_MOTOR_R_CIRCLE_TABLE:
            LDI             ZL,LOW(RmotorRmovTable*2)
            LDI             ZH,HIGH(RmotorRmovTable*2)     ;右转动表首地址入Z  
   
R_MOVE_CIRCLE:


            PUSH            ZL
   ADD             ZL,np
            MAC_TRAN_MOTOR  P_MOTOR_2,ARITH_MOTOR_2,TEMP_MOTOR  ;马达驱动数据存入TEMP_MOTOR
            INC             np
   POP             ZL
            CPI             TEMP_MOTOR,0X00
            BREQ      R_MOTOR_CIRCLE
            SBRC            P_STEP_MARK,B_MARK_R_MOTOR
            RJMP      SEND_DATA_CIRCLE_R
            LDS             TEMP,R_MOTOR_POSITION
            CP              TEMP_MOTOR,TEMP
   BRNE      R_CHECK_CIRCLE_GOON
   SBR             P_STEP_MARK,(1<<B_MARK_R_MOTOR)
R_CHECK_CIRCLE_GOON:
            RJMP      R_MOVE_CIRCLE
SEND_DATA_CIRCLE_R:
            STS             R_MOTOR_POSITION,TEMP_MOTOR    ;保存转动位置数据
            OUT             P_MOTOR_2,TEMP_MOTOR           ;送驱动数据到驱动口
   RCALL     DELAY
   SBIS            P_KEY,B_CLR
   RJMP      KEY_CLR                            ;左右循环动作键是否按下,若按下则停止转动
   INC             COUNT_STEP
            CPI             COUNT_STEP,R_MOTOR_ANGLE        ;是否到转到角度允许范围
   BRLO      R_MOVE_CIRCLE                           ;未到则继续转动
   CLR             COUNT_STEP
   LDI             TEMP,DIRECT_R_MOTOR_EOR
   EOR             P_CONTROL_MOTOR,TEMP                ;若到转动范围则将转动方向取反
   CBR             P_STEP_MARK,(1<<B_MARK_R_MOTOR)
            RJMP      M_MOTOR_CIRCLE
;***********-----------
;中间马达循环动作
M_MOTOR_CIRCLE:


            INC             FIRST_COUNT
M_MOTOR_CIRCLE_START:
   CLR             np
            SBRS            P_CONTROL_MOTOR,B_mM_TL        ;向左转动控制位是否使能,即是否为"1",若为"1"则向左转动,
   RJMP     M_MOTOR_R_ONCE_TABLE                       ;否则向右转动
            LDI             ZL,LOW(MmotorLmovTable*2)     
            LDI             ZH,HIGH(MmotorLmovTable*2)     ;左转动表首地址入Z
   RJMP     M_MOVE_ONCE
M_MOTOR_R_CIRCLE_TABLE:
            LDI             ZL,LOW(MmotorRmovTable*2)
            LDI             ZH,HIGH(MmotorRmovTable*2)     ;右转动表首地址入Z  
   
M_MOVE_CIRCLE:


            PUSH            ZL
   ADD             ZL,np
            MAC_TRAN_MOTOR  P_MOTOR_3,ARITH_MOTOR_3,TEMP_MOTOR  ;马达驱动数据存入TEMP_MOTOR
            INC             np
   POP             ZL
            CPI             TEMP_MOTOR,0X00
            BREQ      M_MOTOR_CIRCLE_START
            SBRC            P_STEP_MARK,B_MARK_M_MOTOR
            RJMP      SEND_DATA_ONCE_M
            LDS             TEMP,M_MOTOR_POSITION
            CP              TEMP_MOTOR,TEMP
   BRNE      M_CHECK_CIRCLE_GOON
   SBR             P_STEP_MARK,(1<<B_MARK_M_MOTOR)
M_CHECK_CIRCLE_GOON:
            RJMP      M_MOVE_CIRCLE
SEND_DATA_CIRCLE_M:
            STS             M_MOTOR_POSITION,TEMP_MOTOR    ;保存转动位置数据
            OUT             P_MOTOR_3,TEMP_MOTOR           ;送驱动数据到驱动口
   RCALL     DELAY


   SBIS            P_KEY,B_CLR
   RJMP      KEY_CLR                            ;左右循环动作键是否按下,若按下则停止转动


   INC             COUNT_STEP


   CPI             FIRST_COUNT,2
   BRSH      COMP_ANGLE2_CIRCLE
            CPI             COUNT_STEP,M_MOTOR_ANGLE1       ;是否到转到角度允许范围
   BRLO      M_MOVE_CIRCLE                           ;未到则继续转动
   RJMP      CM_COUNT_STEP
COMP_ANGLE2_CIRCLE:
            CPI             COUNT_STEP,M_MOTOR_ANGLE2
   BRLO      M_MOVE_CIRCLE
CM_COUNT_STEP:
   CLR             COUNT_STEP
   LDI             TEMP,DIRECT_M_MOTOR_EOR
   EOR             P_CONTROL_MOTOR,TEMP                ;若到转动范围则将转动方向取反
   CBR             P_STEP_MARK,(1<<B_MARK_M_MOTOR)
            RJMP      L_MOTOR_CIRCLE 


;--------------------------------------------------------
CLEAR_RAM:
         LDI  ZL,($1F-$2)   ; REGISTER ($20-$1)-$2(Z)
         CLR  ZH
         CLR  R0
CLEAR0:
         ST  Z,R0
         DEC  ZL
         BRNE CLEAR0
         LDI  ZL,LOW (RAMEND-$20-$40-$1-3) ; PASS STACK POINTER 2 BYTES
         LDI  ZH,HIGH(RAMEND-$20-$40-$1-3)
         LDI  YL,LOW (RAMEND-$1-3)
         LDI  YH,HIGH(RAMEND-$1-3)
CLEAR1:
         ST  -Y,R0
         SBIW ZL,1
         BRNE CLEAR1    ; Y MUST TO START_SRAM($60)
         RET
;------------------------------------------------------------------------------
SET_MEMORY:
         PUSH TEMP2
CLEAR_M0:
         ST  Z+,TEMP
         DEC  TEMP2
         BRNE CLEAR_M0
         POP  TEMP2
         RET
;------------------------------------------------------------------------------


DELAY:


          ldi          temp2,0x0d       ;??2.2ms
          push         temp2
L0:       push         temp2
L1:       push         temp2
L2:       push         temp2
L3:       dec          temp2
          brne     L3
          pop          temp2
          dec          temp2
          brne     L2
          pop          temp2
          dec          temp2
          brne     L1 
          pop          temp2
          dec          temp2
          brne     L0
          pop          temp2
          ret
         RET



.ORG   0Xa00
LmotorLmovTable:


LmotorRmovTable:


RmotorLmovTable:


RmotorRmovTable:


MmotorLmovTable:


MmotorRmovTable:



.DSEG


.ORG   0X0100


L_MOTOR_POSITION                 :           .BYTE    1
R_MOTOR_POSITION                 :           .BYTE    1
M_MOTOR_POSITION                 :           .BYTE    1

1楼 0 0 回复
  • shirley122333

    shirley122333   |   当前状态:离线

    总积分:33  2025年可用积分:0

    注册时间: 2007-12-20

    最后登录时间: 2007-12-22

    空间 发短消息加为好友

    shirley122333   发表于 2007/12/20 15:03:00

    武汉西电伟业自动化控制设备有限公司


     


    主要代理销售德国西门子(SIEMENS)公司PLC及兼容产品,同时还提供备品备件和技术服务,以满足客户的各种需求。公司本着“最新的技术,最平的价格,最优的服务”的原则,不断开发和引进世界最新自控技术和产品,业已成为可提供全面的自动化系统集成技术和服务,完整的自动化控制设备和自动化检测设备的科技创新型自动化厂商。


    代理产品西门子6ES5 6ES7系列 加拿大VPT(mrr-220)晃电继电器


    质量有保证,超低价格,型号齐全!库存充足!


    公司地址:武汉武珞路460号聚豪华庭1605


    QQ号码:228704451


    传真号码:027-87265995


    联系电话:027-50704451         13277043116


    联系人:王雪丽


    在与西门子公司的合作下,我公司拿到了一系列的优惠政策,以超低价服务于国内厂商。真诚的希望在器件销售,工程项目承接和系统开发上能和贵公司开展多方面合作。如您有任何需要请和我们联系,我公司将竭诚为您服务.

    2楼 回复本楼

    引用 shirley122333 2007/12/20 15:03:00 发表于2楼的内容

总共 , 当前 /