Moteur-run -:- pilotage moteur pas à pas avec rampes

Contenu du snippet

Je sais que nous ne sommes pas sur sourceforge et que les versions en évolution sont peut être mal perçues ici, toutefois et pour remplir un peu l'internet; voici le code de pilotage d'un moteur pàp unidirectionnel à 4 bobines et 2 points milieu.

Source / Exemple :


#include <p16f627.inc>

	__CONFIG        _BODEN_ON & _CP_OFF & _DATA_CP_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _MCLRE_ON & _XT_OSC

	CBLOCK 0x020
	TIMER1 :1			; Variable decomptee lors d'un tempo
	TIMER2 :1			; Variable decomptee lors d'un tempo
	BTN :1				; Variable de stockage des boutons du pas
	TIMER_VALUE :1			; Variable pour regler le temps a decompter
	MAXI :1				; Vitesse maximale (voir initialisation).
	MINI :1				; Vitesse minimale.
	MEMTMP :1			; variable temporaire
	COUNT :1			; Variable decomptee dans la validation
	RAMPE :1			; pente d'acceleration
	MOTOR :1			; sorties vers moteur
	WORK : 1			; bit 0 = forward
					; bit 1 = backward
					; bit 2 = marche
					; bit 3, 4 et 5 = gestion rampe. 
					; 543
					; 1xx => en roue libre, seuil atteint
					; 000 => en pause, a l'arret.
					; 001 => acceleration
					; 010 => decceleration
					; 011 => situation impossible
					; bit 7 = Bouton enfonce
					; 
;	w_temp :1
;	status_temp :1
	ENDC				; Fin de la zone
		;-------------------------------------------------------------
		; vecteur de redemarrage
		ORG 	H'0000'		; Emplacement appelé au reset du PIC
		GOTO	boot		; Aller à la routine boot
		;-------------------------------------------------------------
		; Temporisation
tempo		MOVF	TIMER_VALUE,W	; Chargement de la duree de temporisation dans W
                MOVWF   TIMER2		; Move W to TIMER2
DEL_LOOP1       MOVF	TIMER_VALUE,W	; Chargement de la duree de temporisation dans W
                MOVWF   TIMER1		; Move W to TIMER1
DEL_LOOP2	DECFSZ  TIMER1,F	; Decrement de TIMER1, sauter suivant si zero
                GOTO    DEL_LOOP2	; TIMER1 > 0 => decompter encore
                DECFSZ  TIMER2,F	; Decrement de TIMER2, sauter suivant si zero
                GOTO    DEL_LOOP1	; TIMER2 > 0 => decompter encore
		RETLW   0		; Retour en mettant W a zero

entrees		movf	PORTB, W	; Le portB est place dans W
		sublw	D'0'		; 0 en est soustrait
		btfss	STATUS, Z	; pour faire monter le bit Z si W=0
		goto	entrees_s	; non, le bit Z=0; un bouton a ete enfonce
		goto	entrees_end	; oui, le bit Z=1; on saute a la fin
entrees_s	movf	PORTB,w		; le portB est replace dans W
		movwf	BTN		; pour etre range dans BTN
entrees_end	return

traitement	btfsc	BTN, 0		; bouton "aller en avant" ?
		goto	traitement_dbw	; oui, traiter le ralentissement recul
		btfsc	BTN, 1		; bouton "aller en arriere" ?
		goto	traitement_dfw	; oui, traiter le ralentissement avant
		btfsc	BTN, 2		; bouton "arreter" ?
		goto	traitement_sfw	; oui, traiter l'arret avant
		return

traitement_sfw	btfss	WORK,0		; est on en marche avant ?
		goto	traitement_sbw	; non, traiter l'arret arriere
		bcf	WORK, 5		; oui, raz du seuil atteint
		call	down_fw		; ralentir marche avant
		return

traitement_sbw	btfss	WORK, 1		; est on en marche arriere ?
		bcf	WORK, 5		; raz du seuil atteint
		call	down_bw		; oui, ralentir marche arriere
		return

traitement_dfw	btfss	WORK, 0		; est on en marche avant ?
		goto	traitement_gbw	; non, traiter le recul
		bcf	WORK, 5		; oui, raz du seuil atteint
		call	down_fw		; ralentir marche avant
		return

traitement_gbw	btfss	WORK, 1		; est on en marche arriere ?
		goto	traitement_ubw	; non, traiter l'acceleration arriere
		bcf	WORK, 5		; raz du seuil atteint
		call	go_bw		; oui, aller en arriere
		return

traitement_ubw	call	up_bw		; accelerer en arriere
		return

traitement_dbw	btfss	WORK, 1		; est on en marche arriere ?
		goto	traitement_gfw	; non, traiter la marche avant
		bcf	WORK, 5		; raz du seuil atteint
		call	down_bw		; oui, ralentir marche arriere
		return

traitement_gfw	btfss	WORK, 0		; est on en marche avant ?
		goto	traitement_ufw	; non, traiter l'acceleration en avant
		call	go_fw		; oui, aller en avant
		return

traitement_ufw	call	up_fw		; accelerer en avant
		return

down_fw		btfss	WORK, 5		; seuil atteint ?
		goto	down_fw_count	; non, continuer a compter
		goto	down_fw_end	; oui, aller a la fin
down_fw_count	movf	MINI, W		; placer MINI dans W
		subwf	TIMER_VALUE, W	; le soustraire a TIMER_VALUE
		btfss	STATUS,C	; est ce inferieur ou egal a zero
		goto	down_fw_up	; non, on peut diminuer la tempo entre pas
		bcf	WORK,0		; oui, on ne marche plus en avant
		btfsc	BTN,3		; arret demande ?
		return			; oui, on retourne
		goto	down_fw_end	; non, aller a la fin
down_fw_up	movf	TIMER_VALUE,W	; sinon, placer TIMER_VALUE dans W
		movwf	MEMTMP		; placer W dans une variable temporaire
		movf	RAMPE,W		; placer RAMPE dans W
		addwf	MEMTMP,W	; le soustraire a la variable temporaire
		movwf	TIMER_VALUE	; placer le resultat dans TIMER_VALUE
down_fw_end	call	tempo		; appeler la tempo avec cette valeur
		bcf	STATUS,C	; necessaire pour les 1 qui sortent du chapeau
		rlf	MOTOR,W		; 0001 devient 0010 dans W
		movwf	MEMTMP		; W est place dans MEMTMP
		btfss	MEMTMP,4	; le bit 4 de MEMTPM est il a 1 (10000)
		goto	down_fw_send	; non, envoyer comme ca
		clrf	MOTOR		; oui, raz MOTOR
		bsf	MOTOR,0		; MOTOR = 0001
		movf	MOTOR,W		; on place MOTOR dans W
down_fw_send	movwf	MOTOR		; on place W dans MOTOR
		return

go_bw		movf	TIMER_VALUE,W	; placer TIMER_VALUE dans W
		call	tempo		; appeler la tempo avec cette valeur
		bcf	STATUS,C	; necessaire pour les 1 qui sortent du chapeau
		rrf	MOTOR,W		; 0100 devient 0010 dans W
		movwf	MEMTMP		; W est place dans MEMTMP
		btfss	STATUS,C	; etait ce 0001 qui est entre dans le carry ?
		goto	go_bw_send	; non, envoyer comme ca
		bcf	MOTOR,0		; oui, donc la pre-sortie 1 est mise a zero
		bsf	MOTOR,3		; et la pre-sortie 3 est mise a 1
		movf	MOTOR,W		; MOTOR est place dans W
go_bw_send	movwf	MOTOR		; on place W dans MOTOR
		return

up_bw		btfss	WORK, 5		; seuil atteint ?
		goto	up_bw_count	; non, continuer a compter
		goto	up_bw_end	; oui, aller a la fin
up_bw_count	movf	TIMER_VALUE, W	; placer TIMER_VALUE dans W
		subwf	MAXI, W		; le soustraire a MAXI
		btfss	STATUS,C	; est ce inferieur ou egal a zero
		goto	up_bw_up	; non, on peut diminuer la tempo entre pas
		bsf	WORK,1		; on est maintenant en marche arriere
		goto	up_bw_end	; aller a la fin
up_bw_up	movf	TIMER_VALUE,W	; placer TIMER_VALUE dans W
		movwf	MEMTMP		; placer W dans une variable temporaire
		movf	RAMPE,W		; placer RAMPE dans W
		subwf	MEMTMP,W	; le soustraire a la variable temporaire
		movwf	TIMER_VALUE	; placer le resultat dans TIMER_VALUE
up_bw_end	call	tempo		; appeler la tempo avec cette valeur
		bcf	STATUS,C	; necessaire pour les 1 qui sortent du chapeau
		rrf	MOTOR,W		; 0100 devient 0010 dans W
		btfss	STATUS,C	; etait ce 0001 qui est entre dans le carry ?
		goto	up_bw_send	; non, envoyer comme ca
		bcf	MOTOR,0		; oui, il faut eteindre 1
		bsf	MOTOR,3		; et il faut rallumer 3
		movf	MOTOR,W		; MOTOR est place dans W
up_bw_send	movwf	MOTOR		; on place W dans MOTOR
		return

down_bw		btfss	WORK, 5		; seuil atteint ?
		goto	down_bw_count	; non, continuer a compter
		goto	down_bw_end	; oui, aller a la fin
down_bw_count	movf	MINI, W		; placer MINI dans W
		subwf	TIMER_VALUE, W	; le soustraire a TIMER_VALUE
		btfss	STATUS,C	; est ce inferieur ou egal a zero
		goto	down_bw_up	; non, on peut diminuer la tempo entre pas
		bcf	WORK,1		; on n'est plus en marche arriere
		btfsc	BTN,3		; arret demande ?
		return			; oui, on retourne
		goto	down_bw_end	; aller a la fin
down_bw_up	movf	TIMER_VALUE,W	; placer TIMER_VALUE dans W
		movwf	MEMTMP		; placer W dans une variable temporaire
		movf	RAMPE,W		; placer RAMPE dans W
		addwf	MEMTMP,W	; le soustraire a la variable temporaire
		movwf	TIMER_VALUE	; placer le resultat dans TIMER_VALUE
down_bw_end	call	tempo		; appeler la tempo avec cette valeur
		bcf	STATUS,C	; necessaire pour les 1 qui sortent du chapeau
		rrf	MOTOR,W		; 0100 devient 0010 dans W
		btfss	STATUS,C	; etait ce 0001 qui est entre dans le carry ?
		goto	down_bw_send	; non, envoyer comme ca
		bcf	MOTOR,0		; oui, il faut eteindre 1
		bsf	MOTOR,3		; et il faut rallumer 3
		movf	MOTOR,W		; MOTOR est place dans W
down_bw_send	movwf	MOTOR		; on place W dans MOTOR
		return

go_fw		movf	TIMER_VALUE,W	; placer TIMER_VALUE dans W
		call	tempo		; appeler la tempo avec cette valeur
		bcf	STATUS,C	; necessaire pour les 1 qui sortent du chapeau
		rlf	MOTOR,W		; 0001 devient 0010 dans W
		movwf	MEMTMP		; W est place dans MEMTMP
		btfss	MEMTMP,4	; le bit 4 de MEMTPM est il a 1
		goto	go_fw_send	; non, envoyer comme ca
		clrf	MOTOR		; oui, raz MOTOR
		bsf	MOTOR,0		; MOTOR = 0001
		movf	MOTOR,W		; on place MOTOR dans W
go_fw_send	movwf	MOTOR		; on place W dans MOTOR
		return

up_fw		btfss	WORK, 5		; seuil atteint ?
		goto	up_fw_count	; non, continuer a compter
		goto	up_fw_end	; oui, aller a la fin
up_fw_count	movf	TIMER_VALUE, W	; placer TIMER_VALUE dans W
		subwf	MAXI, W		; le soustraire a MAXI
		btfss	STATUS,C	; est ce inferieur ou egal a zero
		goto	up_fw_up	; non, on peut diminuer la tempo entre pas
		bsf	WORK,5		; oui, on a atteint le seuil
		bsf	WORK,0		; on est en marche avant
		goto	up_fw_end	; aller a la fin
up_fw_up	movf	TIMER_VALUE,W	; placer TIMER_VALUE dans W
		movwf	MEMTMP		; placer W dans une variable temporaire
		movf	RAMPE,W		; placer RAMPE dans W
		subwf	MEMTMP,W	; le soustraire a la variable temporaire
		movwf	TIMER_VALUE	; placer le resultat dans TIMER_VALUE
up_fw_end	call	tempo		; appeler la tempo avec cette valeur
		bcf	STATUS,C	; necessaire pour les 1 qui sortent du chapeau
		rlf	MOTOR,W		; 0001 devient 0010 dans W
		movwf	MEMTMP		; W est place dans MEMTMP
		btfss	MEMTMP,4	; le bit 4 de MEMTPM est il a 1
		goto	up_fw_send	; non, envoyer comme ca
		clrf	MOTOR		; oui, raz MOTOR
		bsf	MOTOR,0		; MOTOR = 0001
		movf	MOTOR,W		; on place MOTOR dans W
up_fw_send	movwf	MOTOR		; on place W dans MOTOR
		return

sorties	;	clrf	PORTA
		movf	MOTOR,W
		movwf	PORTA
		return
		;-------------------------------------------------------------
		; Routine de redemarrage
boot		MOVLW	B'00000111'	; Disable Comparator module's
		MOVWF	CMCON
		BSF	STATUS,RP0	; Switch to register bank 1
					; Disable pull-ups
					; INT on rising edge
					; TMR0 to CLKOUT
					; TMR0 Incr low2high trans.
					; Prescaler assign to Timer0
					; Prescaler rate is 1:256
		MOVLW	B'11010111'	; Set PIC options (See datasheet).
		MOVWF	OPTION_REG	; Write the OPTION register.
;		MOVLW	B'10001000'
;		MOVWF	INTCON
		CLRF	INTCON		; Disable interrupts
		movlw	B'00000000'	; all RA ports are outputs
		movwf	TRISA
		movlw	B'11111111'
		movwf	TRISB		; RB7...RB0 are inputs.
		bcf	STATUS,RP0	; Switch Back to reg. Bank 0
		;-------------------------------------------------------------
		; Initialisation de valeurs de variables
		clrf	PORTA		; Clear PORTA
		clrf	MOTOR
		bsf	PORTA,0
		movf	PORTA,W
		movwf	MOTOR
		; Reglage de la vitesse de depart. Represente la temporisation
		; qui sera appellee entre chaque pas
		movlw	0xFF		; 0xFF = lent; 0x41 = rapide
		movwf	MINI
		movwf	TIMER_VALUE
		; Reglage de la vitesse de fin d'acceleration
		movlw	0x40		; Vitesse mini
		movwf	MAXI
		movlw	0x10
		movwf	RAMPE

		clrf	WORK
		goto	MENU		; Aller au menu principal

MENU		call	entrees	
		call	traitement
		call	sorties
		GOTO	MENU		;Aller à MENU
		END

Conclusion :


J'adore la mise en page du code assembleur. De plus, l'intégralité du code s'affiche sur le site asmFR.com et c'est chouette.

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.