;*************************************
;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
-
-
-
-
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
联系人:王雪丽
在与西门子公司的合作下,我公司拿到了一系列的优惠政策,以超低价服务于国内厂商。真诚的希望在器件销售,工程项目承接和系统开发上能和贵公司开展多方面合作。如您有任何需要请和我们联系,我公司将竭诚为您服务.
引用 shirley122333 2007/12/20 15:03:00 发表于2楼的内容
-