⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drivera.asm

📁 步进微步控制(采用了10细分的方式)很好实现了步进的细分控制
💻 ASM
📖 第 1 页 / 共 4 页
字号:
		dt	 0,   1, 134, 160	; 100000
		dt	 0,   0,  39,  16	; 10000
		dt	 0,   0,   3, 232	; 1000
		dt	 0,   0,   0, 100	; 100
		dt	 0,   0,   0,  10	; 10
		dt	 0,   0,   0,   1	; 1
;
; User level subroutine call 
; 	call with:
;	  PCLATH set to return addr top
;	  w set to return addr bottom
;	  b0mwsave set to calling w
;
savertn
		banksel	stackptr	;
		movwf	mlsave		; Save bottom of return addr
		movfw	FSR		; Save FSR
		movwf	mfsave		;
		movfw	stackptr	; Pick up stack pointer
		movwf	FSR		;
		movfw	mlsave		; Pick up bottom
		movwf	INDF		; Push on stack
		decf	FSR, f		;
		movfw	PCLATH		; Pick up top
		movwf	INDF		; Push on stack
		decf	FSR, f		;
		movfw	FSR		; Stash stack pointer
		movwf	stackptr	;
		movfw	mfsave		; Restore FSR
		movwf	FSR		;
		banksel	0		; Back to bank 0
		movfw	b0mwsave	;
		return			; All done
;
; User level subroutine return
;	Just jump here
;
restrtn
		movwf	b0mwsave	; Save w
		banksel	stackptr	;
		movfw	FSR		; Save FSR
		movwf	mfsave		;
		movfw	stackptr	; Load FSR from stack pointer
		movwf	FSR		;
		incf	FSR, f		; Back to saved hi addr
		movfw	INDF		;
		movwf	PCLATH		; Save in PCLATH
		incf	FSR, f		; Back to saved low addr
		movfw	INDF		;
		movwf	mlsave		; Stash for a minute
		movfw	FSR		;
		movwf	stackptr	; Save new stack pointer
		movfw	mfsave		; 
		movwf	FSR		; Restore FSR
		movfw	mlsave		; Pick low addr back up
		movwf	PCL		; And return

;
; Start of code
;
main
; Initalize main registers - shut everything off for now
		movlw	B'10000111'	; RBPU=1 INTEDG=0 TOCS=0 TOSE=0 PSA=0 PS0:PS2=7
		banksel	OPTION_REG	;
		movwf	OPTION_REG	;
		movlw	B'00000000'	; Turn off all interrupts, clear bits
		banksel	INTCON		;
		movwf	INTCON		;
		movlw	B'00000000'	; Turn off all interrupt enables in PIE1
		banksel	PIE1		;
		movwf	PIE1		;
		movlw	B'00000000'	; Clear all interrupt flag bits in PIR1
		banksel	PIR1		;
		movwf	PIR1		;
		movlw	B'00000000'	; Clear CCP2IE in PIE2
		banksel	PIE2		;
		movwf	PIE2		;
		movlw	B'00000000'	; Clear all flags in PIR2
		banksel	PIR2		;
		movwf	PIR2		;
		banksel	0
; Set up user level stack
		banksel	stackptr	;
		movlw	stack		;
		movwf	stackptr	;
		banksel	0
; Initialize port registers
		banksel	PORTA		; Initalize PORTs
		clrf	PORTA		;
		clrf	PORTB		;
		clrf	PORTC		;
		banksel	TRISA		;
		movlw	B'00111111'	; Set all as inputs
		movwf	TRISA		;
		clrf	TRISB		; Set all as outputs
		movlw	B'11000000'	; Transmit, receive = in, others = out
		movwf	TRISC		; 
		banksel	0
; First thing, shut down the motors.
		movlw	0		;
		ra_out			; 0 to RA motor latch
		movlw	0		;
		dec_out			;
; Set up globals that need it
		clrd	rapos		;
		clrd	dpos		;
		clrf	rtrajp		;
		clrf	dtrajp		;
		clrf	cmdidx		; point at first char
		clrf	rstatus		;
		clrf	dstatus		;
		bsf	rstatus, ST_STOPPED ;
		bsf	dstatus, ST_STOPPED ;
		movlw	TRACKH		; default for slew command
		movwf	speedh		;
		movlw	TRACKL		;
		movwf	speedl		;
		movlw	SL_SLOW_MASK	;
		movwf	slew		;
		movlw	USTEPF		;
		movwf	stepcmd		;
		movlw	1		;
		movwf	inccmd		;
		movlw	STARTBATT	; Set up start for rolling average
		movwf	avgbatt		;
		clrf	t0ticks		; No ticks received yet
		clrf	timbatt		; Last time the battery was checked = 0
	ifdef	SIM
		clrf	fakeidx
	endif
; Set up timers
		movlw	B'00000000'	; TICKPS1:TICKPS0=0 T1OSCEN=0 T1SYNC=0 TMR1CS=0
		movwf	T1CON		; Set up for internal clock, leave off for now
		clrf	TMR1L		; Zero out timer 1
		clrf	TMR1H		;
		bsf	T1CON, 0	; Start Timer 1 ticking
		clrf	TMR0		; Clear timer 0
		bcf	INTCON, 2	; Clear T0IF
		bsf	INTCON, 5	; Set T0IE - want an interrupt on each rollover
; Set up a/d
		banksel	ADCON1		;
		movlw	0		; RA0:RA5 all analog inputs
		movwf	ADCON1		;
		banksel	ADCON0		;
		movlw	B'11000000'	; ADCS1:ADCS0=Internal Osc, ADON=converter off
		movwf	ADCON0		;
; Set up RS232
		movlw	baud(9600)	; Should be 25 for 9615 baud
		banksel	SPBRG		;
		movwf	SPBRG		;
		banksel	0		;
		movlw	B'00100100'	; CSRC=0 TX9=0 TXEN=1 SYNC=0 BRGH=1
		banksel	TXSTA		;
		movwf	TXSTA		;
		banksel	0		;
		movlw	B'10010000'	; SPEN=1 RX9=0 SREN=0 CREN=1
		movwf	RCSTA		;
		bsf	PORTC, SHDN	; Enable the MAX222 chip
     		bsf	PORTC, LED	; Set the LED, ready to roll
; Send out a "Hello" message
		mcall	sayhi		;
; Finally, enable interrupts - everything is ready to go
		bsf	INTCON, 7	; Set GIE
		bsf	INTCON, 6	; Set PEIE
; Default mode is track so we don't need a paddle to start
		mcall	dotrack		; Start it tracking
;	
; Main loop
;
loop
		mcall	rs232in		; Try to get a character
		andlw	0xff		; Check to see if we  got one
		skpnz			; 
		goto	main1		;
		mcall	bufchar		; Buffer char if yes
		sublw	0x0D		; Is it a CR?
		skpz
		goto	main1		;
		mcall	docmd		; Do the command if yes
main1
		mcall	chklim		; Check the limit switches
		mcall	chkbatt		; Check the battery voltage
		goto	loop
;
; Hello, we're here msg
;
sayhi
		movlw	high sayhisub	;
		movwf	PCLATH		;
		movlw	0		; Set up index
		movwf	temp		;
sayhi1		movfw	temp		; Pick up the index
		call	sayhisub	; Get the char
		andlw	0xff		; Zero?
		skpnz			;
		goto	sayhidone	; End if done
		mcall	rs232out	; Send the char
		incf	temp, f		; Advance the index
		goto	sayhi1		; Loop
sayhidone	mreturn			;

sayhisub	addwf	PCL, f		; Get a char
		dt	"\r\ndrivera V1.0 7/5/00\r\n>"
		dt	0
;
; Send a character out the RS232 port
;	Character passed in w
;	(Same) character returned in w
rs232out
	IFNDEF	SIM
		btfss	PIR1, TXIF	; Check for buffer full
		goto	rs232out	;
	ENDIF
		movwf	TXREG		; Send the character
		toggle_led		; Let them know we sent one
		mreturn			;
;
; Check for a character in the RS232 input register
;	Returns character in w or 0 if no char
;	Echoes character to output line if we got one
;
rs232in
		movlw	0		; assume no char
	IFDEF	SIM
		mcall	fakeinput	;
	ELSE
		btfss	PIR1, RCIF	; Check receive buffer full
		goto	rs232indone	; Return if no char
		movfw	RCREG		; Get the char
	ENDIF		
		mcall	rs232out	; Echo it
rs232indone	mreturn			; Return the character
;
; Buffer up an ascii character
;	Character passed in w
;	Returns the character in w
;
bufchar
		movwf	temp		; Stash the char
		movfw	cmdidx		; Pick up the index to the next char
		sublw	CMDLEN		; Check length
		skpz			;
		goto	bufchar1	;
		movfw	temp		; don't store if buff is full
		goto	bufchardone	;
bufchar1
		movfw	cmdidx		; Grab it again
		addlw	cmdbuff		; index into buffer
		movwf	FSR		;
		movfw	temp		; Get the character
		movwf	INDF		; indirect store
		incf	cmdidx, f	; Increment the index	
bufchardone	mreturn			; And done
;
; Send buffer at FSR to the output rs232
;	Buffer is null terminated
;
buffout
		movfw	INDF		; Get a char
		skpnz			;
		goto	buffoutend	; Done if null
		mcall	rs232out	; Send the char
		incf	FSR, f		; Advance to the next one
		goto	buffout		; And loop
buffoutend	mreturn
		
;
; Do the command in the buffer
;	No parameters passed
;	No return value
docmd
		movlw	cmdbuff		; Point at the buffer
		movwf	FSR		;
		movfw	INDF		; Pick off the 1st char
		sublw	'F'		; Full step?
		skpz			;
		goto	docmd1		;
		mcall	dofstep		; Do full step cmd
		goto	docmdend	;
docmd1		movfw	INDF		;
		sublw	'G'		; Get?
		skpz			;
		goto	docmd2		;
		mcall	doget		; Do the get commands
		goto	docmdend	;
docmd2		movfw	INDF		;
		sublw	'U'		; Microstep?
		skpz			;
		goto	docmd3		;
		mcall	domicrostep	; Do microstep commands
		goto	docmdend	;	
docmd3		movfw	INDF		;
		sublw	'Q'		; Quit?
		skpz			;
		goto	docmd4		;
		movlw	0		; Quit, don't idle
		mcall	doquit		; Do quit cmd
		goto	docmdend	;
docmd4		movfw	INDF		;
		sublw	'R'		; Reset?
		skpz			;
		goto	docmd5		;
		lgoto 	0x00		; xxx may not be adequate
docmd5		movfw	INDF		;
		sublw	'S'		; Set?
		skpz			;
		goto	docmd6		;
		mcall	doset		; Do Set commands
		goto	docmdend	;
docmd6		movfw	INDF		;
		sublw	'T'		; Track?
		skpz			;
		goto	docmd7		;
		mcall	dotrack		; Do Track cmd
		goto	docmdend	;
docmd7		movfw	INDF		;
		sublw	'M'		; Slew?
		skpz			;
		goto	docmd8		;
		mcall	doslew		; Do Slew cmd
		goto	docmdend	;
docmd8		movfw	INDF		;
		sublw	'I'		; Idle?
		skpz			;
		goto	docmd9		;
		movlw	1		; Quit and idle
		mcall	doquit		; Do Idle command
		goto	docmdend	;
docmd9	; Didn't recognize the cmd...
		movlw	1		; - error invalid command
; Wrap it up, prompt for next cmd
docmdend
		movwf	temp
		movlw	0x0A		; LF
		mcall	rs232out	;
		movfw	temp		; Get command return status
		skpnz			;
		goto	dcmde1		;
		movlw	'?'		; Error indicator
		mcall 	rs232out	;
dcmde1		movlw	'>'		; Prompt
		mcall	rs232out	;
		clrf	cmdidx		; Set the index back to start
		mreturn			;
;
; Start tracking
;	Hard code the speeds and slew...

;
dotrack
		movlw	TRACKH		; Set up parameters for raslowslew
		movwf	speedh		;
		movlw	TRACKL		;
		movwf	speedl		;
		movlw	USTEPB		;
		movwf	stepcmd		;
		movlw	-1		;
		movwf	inccmd
		goto	raslowslew	;
;
; Start slewing
;	Call with FSR pointing to M
;	M<m><dir>
;
doslew
		incf	FSR, f		; Advance to "R" or "D"
		movfw	INDF		;
		sublw	'R'		; RA?
		skpz			;
		goto	doslewnr	;
		movlw	0		; 0 clear = ra
		goto	doslewfb	;
doslewnr	movfw	INDF		;
		sublw	'D'		; Dec?
		skpz			;
		goto	doslewbad	;
		movlw	1		; 0 set = dec
doslewfb	movwf	temp		; bit 0 of temp = ra/dec
		incf	FSR, f		; Advance to '+' or '-'
		movfw	INDF		; Get direction
		sublw	'+'		; Forward?
		skpz			;
		goto	doslewcm	;
		bsf	temp, 1		; 1 set = +
		goto	doslew1
doslewcm	movfw	INDF		;
		sublw	'-'		;
		skpz			;
		goto	doslewbad	; 1 clear = -
doslew1
		btfss	slew, SL_GUIDE	; Guide?
		goto	doslew2		;
		btfss	temp, 1		; Forward, back
		goto	doslew3
		movlw	GUIDEFH		; Set speed to guide forward
		movwf	speedh		;
		movlw	GUIDEFL		;
		movwf	speedl		; 2 clear = slow
		goto	doslew4		;
doslew3		movlw	GUIDEBH		;
		movwf	speedh		;
		movlw	GUIDEBL		;
		movwf	speedl		;
		bsf	temp, 1		; Really forward
doslew2		btfsc	slew, SL_FAST	;
		bsf	temp, 2		; 2 set = fast, 2 clear = slow
		btfsc	slew, SL_MED	;
		bsf	temp, 2		;
doslew4	; Temp all set up
		btfss	temp, 1		; Forward?
		goto	doslew6		;
		movlw	USTEPF		; Yes, forward,  Set up for motor start
		movwf	stepcmd		;
		movlw	1		;
		movwf	inccmd		;
		goto	doslew7		;
doslew6		movlw	USTEPB		; Nope, backwards
		movwf	stepcmd		;
		movlw	-1		;
		movwf	inccmd		;
doslew7		btfsc	temp, 0		; RA set?
		goto	doslew5		;
		btfss	temp, 2		; Fast?
		goto	raslowslew	;
		goto	rafastslew	;
doslew5		btfss	temp, 2		;
		goto	dslowslew	;
		goto	dfastslew	;
doslewbad	mretlw	1		; Error

;
; raslowslew starts a slow slew
;    speedh, speedl, stepcmd, inccmd all set up previously
;
raslowslew
		bsf	rstatus, ST_STOP ; Signal that we need to stop
raslowslew2
		btfss	rstatus, ST_STOPPED ; Check for stopped
		goto	raslowslew2	; Wait for a stop
raslowslew1
		movfw	speedh		; Set up compare regs for int level
		movwf	rspdhigh	;
		movfw	speedl		;
		movwf	rspdlow		;
		movlw	0		; Start in state 0
raslewall ; start up the engine...  Enter here with initial state in w
		movwf	t1state		;
		clrf	rstatus		;
		movfw	inccmd		; Set up interrupt level vbls
		movwf	rinc		;
		movfw	stepcmd		;
		movwf	t1stepcmd	;	
		splh			; Disable ints while we get timer 1
		movfw	TMR1H		; Mark1 - Pick up high
		addwf	rspdhigh, w	; calc capture reg
		movwf	CCPR1H		;
		movlw	5		; Mark2-Mark1+1 timing
		subwf	TMR1L, w	; Mark2 - Pick up low
		spl0			; Reenable
		addwf	rspdlow, w	; Calc other reg
		movwf	CCPR1L		;
		skpnc			;
		incf	CCPR1H, f	;
		movlw	B'00001010'	; CCP1X:CCP1Y=0 CCP1M3:CCP1M0=1010
		movwf	CCP1CON		; Set up for compare mode, int on match
		bcf	PIR1, 2		; Be sure CCP1IF is clear
		banksel	PIE1		;
		bsf	PIE1, 2		; Enable the capture interrupt
		banksel	0		;
; rstep expanded here by hand to allow for lcall of gettraj
		movfw	t1stepcmd	; Step 1 of 8
		addwf	rtrajp, f	; see where to go next
		movlw	0x1f		; Wrap pointer
		andwf	rtrajp, w	; w gets ptr for gettraj
		movwf	rtrajp		; Save new ptr
		lcall	gettraj		; Get the table value
		ra_out			; Send to motor
		mlretlw	0		; Successful completion
;
; rafastslew starts a fast slew
;	speedh, speedl, stepcmd, inccmd all set up previously
;
rafastslew
		bsf	rstatus, ST_STOP ; Signal that we need to stop
rafastslew2
		btfss	rstatus, ST_STOPPED ; Check for stopped
		goto	rafastslew	; Wait for a stop
rafastslew1
		movlw	0		; Start at 0
		movwf	rcuridx	; Set starting point
		lcall	rgetaccel	; Set up rac_cnt, rspdhigh, rspdlow
		movfw	speedh		; Pick up high index
		movwf	rhiacidx	; Set stopping point

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -