Regprog -:- enregistrer une séquence dans un pic

Contenu du snippet

Ce petit programme permet d'enregistrer une séquence de 15 états de 4 sorties pour un microcontroleur PIC.

Il me servira pour la simulation d'un encodeur machine afin d'en faire un simulateur didactique. Il peut servir pour des jeux de lumière.

Ce code est mon premier programme écrit en assembleur pour la carte velleman K8048, donc sont utilisés le PORTA en entrée et le PORTB en sortie.

Source / Exemple :


;		  _ \  ____|  ___|  _ \   _ \   _ \   ___|

;		 |   | __|   |     |   | |   | |   | |

;		 __ <  |     |     ___/  __ <  |   | |   |

;		_| \_\_____|\____|_|    _| \_\\___/ \____|

; RecProg - Licence Creative - pour usage commercial ou non mais sans enlever

; les commentaires. Peut etre modifie a volonte.

; Gilles OTTAVIANI - bermudos acrobate free point fr

;

;**************************************************************************

;*          Hardw. Rev: P8048'1          Softw. Rev:  0.31                *

;*          OSC.......: XT 4MHz Max.     POWER.....:  12V DC              *

;**************************************************************************

; Ma premiere application sur la carte K8048 de Velleman

;

; But : Enregistrer l'etat de 4 boutons pour la gestion d'un miniprogrammeur

; qui contiendrait 0x0F instructions. On peut comprendre ceci comme une came

; electronique dont on programme l'état de 4 sorties selon l'endroit où l'on

; se trouve dans un cycle étape par étape.

;

; L'appui court sur un des 4 boutons declenche l'affichage des led LD5 et LD6

; alternativement et rapidement. Il faut relacher le bouton avant la fin de ce

; clignotement sinon on enclenche la seconde fonction du bouton decrite plus

; loin.

; Le bit correspondant au bouton enfonce est memorise dans une variable

; temporaire en attendant l'appui d'un autre bouton. Lorsque l'enregistrement

; du pas de programme ainsi constitue est demande; le contenu de la variable

; temporaire est place dans la premiere case memoire RAM disponible a partir

; de 0x30. Et ceci jusqu'a 0x40.

;

; Bouton 1 (SW1) : Enregistrer le "pas de programme" 

; Bouton 2 (SW2) : Effacer le "programme"

; Bouton 3 (SW3) : Afficher (ou derouler) le "programme"

; Bouton 4 (SW4) : Effacer le "pas de programme" en cours

;

;list      p=16f627            ; list directive to define processor in gpasm

#include <p16f627.inc>

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

#DEFINE  	LD1 PORTB,0		; Sur la carte vm111, les

#DEFINE  	LD2 PORTB,1		; leds sont branchees sur

#DEFINE  	LD3 PORTB,2		; PORTB et les 4 boutons

#DEFINE  	LD4 PORTB,3		; sont sur PORTA pour le

#DEFINE  	LD5 PORTB,4		; 18 pattes

#DEFINE  	LD6 PORTB,5

#DEFINE  	SW1 PORTA,0

#DEFINE  	SW2 PORTA,1

#DEFINE  	SW3 PORTA,2

#DEFINE  	SW4 PORTA,3

;==========================================================================

;       Variable Definition

;==========================================================================

;INPUTS

	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

	POINTER :2			; Adresse memoire libre

	COUNT :2			; Variable decomptee dans la validation

	ENDC				; Fin de la zone

		;-------------------------------------------------------------

		; vecteur de redémarrage

		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

		;-------------------------------------------------------------

		; Routine de redémarrage

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.

		CLRF	INTCON		; Disable interrupts

		MOVLW	B'11111111'	; all RA ports are inputs

		MOVWF	TRISA

		MOVLW	B'11000000'

		MOVWF	TRISB		; RB7 & RB6 are inputs.

					; RB5...RB0 are outputs.

		BCF	STATUS,RP0	; Switch Back to reg. Bank 0

		CLRF	PORTB		; Clear PORTB

		GOTO	MENU		; Aller au menu principal

		;-------------------------------------------------------------

		; Routine de scrutation des boutons

store_sw	BTFSC	SW1		; SW1 est il enfonce ?

		CALL	store_sw1	; Oui, aller enregistrer la position de ce bouton

		BTFSC	SW2		; SW2 est il enfonce ?

		CALL	store_sw2	; Oui, aller enregistrer la position de ce bouton

		BTFSC	SW3		; SW3 est il enfonce ?

		CALL	store_sw3	; Oui, aller enregistrer la position de ce bouton

		BTFSC	SW4		; SW4 est il enfonce ?

		CALL	store_sw4	; Oui, aller enregistrer la position de ce bouton

		RETURN			; Retourner d'ou l'on vient

		;-------------------------------------------------------------

		; Stockage du bouton 1

		; le bouton 1 sert aussi a la validation de la saisie du pas

store_sw1	CALL	warning		; Avertissement de la double saisie

		BTFSC	SW1		; Le bouton 1 est il encore enfonce ?

		GOTO	sw1_still_on	; Oui, aller valider la saisie

		GOTO	sw1_now_off	; Non, juste saisir le bouton

		;-------------------------------------------------------------

		; Dans le cas ou le bouton reste enfonce

sw1_still_on	CALL	ack_sw		; On va valider la saisie des 4 boutons

		GOTO	end_store_sw1	; Termine, aller a la fin

		; Sinon, si il a ete relache avant la fin de l'avertissement

sw1_now_off	BTFSC	BTN,0		; Le bouton 1 a t'il jamais ete enfonce pour ce pas ?

		GOTO	end_store_sw1	; Termine, aller a la fin

		BSF	BTN,0		; Placer bit 0 de BTN a 1 pour l'enregistrer

		CALL	blink_quick	; Clignotement pour signifier la saisie

end_store_sw1	BTFSC	SW1		; Le bouton 1 est il encore enfonce ?

		GOTO	end_store_sw1	; Il faut penser a le relacher, donc retest

		RETURN			; Retour de l'enregistrement du bouton 1

		;-------------------------------------------------------------

		; Stockage du bouton 2

		; le bouton 2 sert aussi a effacer le "programme"

store_sw2	CALL	warning		; Avertissement de la double saisie

		BTFSC	SW2		; Le bouton 2 est il encore enfonce ?

		GOTO	sw2_still_on	; Oui, aller effacer le "programme"

		GOTO	sw2_now_off	; Non, juste saisir le bouton

		;-------------------------------------------------------------

		; Dans le cas ou le bouton reste enfonce

sw2_still_on	CALL	erase_all	; Aller effacer le "programme"

		GOTO	end_store_sw2	; Termine, aller a la fin

		; Sinon, si il a ete relache avant la fin de l'avertissement

sw2_now_off	BTFSC	BTN,1		; Le bouton 2 a t'il jamais ete enfonce pour ce pas ?

		GOTO	end_store_sw2	; Termine, aller a la fin

		BSF	BTN,1		; Placer bit 1 de BTN a 1 pour l'enregistrer

		CALL	blink_quick	; Clignotement pour signifier la saisie

end_store_sw2	BTFSC	SW2		; Le bouton 2 est il encore enfonce ?

		GOTO	end_store_sw2	; Il faut penser a le relacher, donc retest

		RETURN			; Retour de l'enregistrement du bouton 2

		;-------------------------------------------------------------

		; Stockage du bouton 3

		; le bouton 3 sert aussi a afficher le "programme"

store_sw3	CALL	warning		; Avertissement de la double saisie

		BTFSC	SW3		; Le bouton 3 est il encore enfonce ?

		GOTO	sw3_still_on	; Oui, aller afficher le "programme"

		GOTO	sw3_now_off	; Non, juste saisir le bouton

		;-------------------------------------------------------------

		; Dans le cas ou le bouton reste enfonce

sw3_still_on	CALL	display_prog	; Aller afficher le "programme"

		GOTO	end_store_sw3	; Termine, aller a la fin

		; Sinon, si il a ete relache avant la fin de l'avertissement

sw3_now_off	BTFSC	BTN,2		; Le bouton 3 a t'il jamais ete enfonce pour ce pas ?

		GOTO	end_store_sw3	; Non, il est deja enregistre, sauter a la fin

		BSF	BTN,2		; Placer bit 2 de BTN a 1 pour l'enregistrer

		CALL	blink_quick	; Clignotement pour signifier la saisie

end_store_sw3	BTFSC	SW3		; Le bouton 3 est il encore enfonce ?

		GOTO	end_store_sw3	; Il faut penser a le relacher, donc retest

		RETURN			; Retour de l'enregistrement du bouton 3

		;-------------------------------------------------------------

		; Stockage du bouton 4

		; le bouton 4 sert aussi a l'effacement de la saisie

store_sw4	CALL	warning		; Avertissement de la double saisie

		BTFSC	SW4		; Le bouton 4 est il encore enfonce ?

		GOTO	sw4_still_on	; Oui, aller effacer le "pas de programme"

		GOTO	sw4_now_off	; Non, juste saisir le bouton

		;-------------------------------------------------------------

		; Dans le cas ou le bouton reste enfonce

sw4_still_on	CLRF	BTN		; Oui, effacer le "pas de programme"

		GOTO	end_store_sw4	; Termine, aller a la fin

		; Sinon, si il a ete relache avant la fin de l'avertissement

sw4_now_off	BTFSC	BTN,3		; Le bouton 4 a t'il jamais ete enfonce pour ce pas ?

		GOTO	end_store_sw4	; Non, il est deja enregistre, sauter a la fin

		BSF	BTN,3		; Oui, placer bit 3 de BTN a 1 pour l'enregistrer

		CALL	blink_quick	; Clignotement pour signifier la saisie

end_store_sw4	BTFSC	SW4		; Le bouton 4 est il encore enfonce ?

		GOTO	end_store_sw4	; Il faut penser a le relacher, donc retest

		RETURN			; Retour de l'enregistrement du bouton 4

		;-------------------------------------------------------------

		; Routine Warning

warning		CALL	tempo_ff

		CALL	blink_warning	; Clignotement pour signifier la saisie

		RETURN

		;-------------------------------------------------------------

		; Routine Warning pour l'effacement

warning_erase	MOVLW	H'00FF'		; Chargement de la valeur maximale de 8 bits

		MOVWF	TIMER_VALUE	; Dans la duree de la temporisation

		CALL	tempo		; Appel de la temporisation

		CALL	blink_delete	; Clignotement pour signifier l'effacement

		MOVLW	H'00FF'		; Appel de la temporisation une seconde fois

		MOVWF	TIMER_VALUE

		CALL	tempo

		RETURN

		;-------------------------------------------------------------

		; validation de la saisie

ack_sw		movlw	0x30		; Premiere case vide

		MOVWF	FSR		; Pointer sur cette adresse

as_next		MOVF	INDF,F		; Placer son contenu dans F

		BTFSC	STATUS, Z	; Pour voir si c'est zero

		GOTO	as_endloop	; Oui, aller a la fin

		INCF	FSR		; Incrementer le pointeur

		BTFSS	FSR,6		; Est on arrive a la fin de la zone

		GOTO	as_next		; Non, faire la case suivante

as_endloop	MOVF	BTN,W		; Charger le "pas de programme"

		MOVWF	INDF		; Dans la case memoire vide

		CLRF	BTN		; C'est ici qu'est effacee la saisie

		RETURN			; Retour d'ou l'on vient.

		;-------------------------------------------------------------

		; Effacement du programme

erase_all	CALL warning_erase	;

		;---------------------------------------------------

		; Effacer RAM

		MOVLW	0x30		; Charger 48 dans W

		MOVWF	FSR		; Se placer a cette adresse dans la RAM

ea_init		CLRF	INDF		; Effacer le contenu de la case

		INCF	FSR,F		; Case suivante

		BTFSS  	FSR,6		; >= 0x40

		GOTO  	ea_init		; Il reste des cases, continuer a effacer

		CALL	tempo_c0	; Appel tempo courte

		CALL	blink_erase	; Appel clignotement d'effacement

		CALL	tempo_c0	; Appel tempo courte

		CALL	blink_erase	; Appel clignotement effacement

		CLRF	BTN		; C'est ici qu'est effacee la saisie

		RETURN			; Retour d'ou l'on vient

		;---------------------------------------------------

		; Affichage des 15 pas du programme

		; C'est cette partie qui peut etre exploitee

		; - jeu de lumieres

		; - choix d'un programme sur une autre puce

		; - Simulation d'une came electronique

display_prog	movlw	0x30		; Premiere case

		MOVWF	FSR		; Pointer sur cette adresse

dp_next		MOVF	INDF,W		; Placer son contenu dans W

		MOVF	INDF,F		; Et dans F

		BTFSC	STATUS,Z	; Pour voir si il est different de zero

		GOTO	dp_endloop	; Non, il n'y a plus rien; aller a la fin

		MOVWF	PORTB		; Et dans PORTB (les led)

		CALL	tempo_ff	; Appel tempo longue

		MOVWF	PORTB		; W revient vide de tempo (retw 0)

		INCF	FSR		; Incrementer le pointeur

		BTFSS	FSR,6		; Est on arrive a la fin de la zone

		GOTO	dp_next		; Non, faire la case suivante

		CALL	tempo_ff	; Appel tempo longue

dp_endloop	CLRF	PORTB		; Extinction des feux

		RETURN			; Retour d'ou l'on vient.

		;-------------------------------------------------------------

		; Affichage du pas en cours

choose		MOVF	BTN,F		; La memoire des boutons est placee dans F

		BTFSC	STATUS,Z	; Pour voir si c'est different de zero

		GOTO	c_end		; Non, aller a la fin

		MOVF	BTN,W		; La memoire des boutons du pas dans W

		MOVWF	PORTB		; W contient la valeur a afficher

c_end		CALL	tempo_ff	; Appel d'une tempo longue

		MOVLW	B'00000000'	; Chargement de 0 dans W

		MOVWF	PORTB		; Pour eteindre PORTB

		RETURN			; Et sortie de la routine

		;-------------------------------------------------------------

		; Clignotement rapide de LD5 et LD6

blink_warning	MOVLW 5			; La routine va etre repetee 4 fois

		MOVWF	COUNT		; 5 est place dans la variable COUNT

bw_looping	DECFSZ	COUNT , F	; COUNT = COUNT -1

		goto	bw_loop		; Le resultat est different de zero

		goto	bw_out		; Le resultat est egal a zero

bw_loop		MOVLW	B'00100000'	; Valeur pour allumer les LED

		MOVWF	PORTB		; Connectees au PORTB

		CALL	tempo_7f	; Appel tempo moyenne

		MOVLW	B'00010000'	; Valeur pour allumer les LED

		MOVWF	PORTB		; Connectees au PORTB

		CALL	tempo_7f	; Appel tempo moyenne

		MOVLW	B'00000000'	; Valeur pour allumer les LED

		MOVWF	PORTB		; Connectees au PORTB

		CALL	tempo_7f	; Appel tempo moyenne

		SUBWF 	COUNT,F		; On y soustrait COUNT

		BTFSS 	STATUS,Z	; Est ce egal a zero ?

		GOTO	bw_looping	; Non, on boucle

bw_out		RETURN			; Et sortie de la routine

		;-------------------------------------------------------------

		; Chenillard rapide pour signifier l'enregistrement

blink_quick	MOVLW	B'00000001'	; Valeur pour allumer les LED

		MOVWF	PORTB		; Connectees au PORTB

		CALL	tempo_7f	; Appel tempo moyenne

		MOVLW	B'00000010'	; Valeur pour allumer les LED

		MOVWF	PORTB		; Connectees au PORTB

		CALL	tempo		; Appel de la temporisation

		MOVLW	B'00000100'	; Valeur pour allumer les LED

		MOVWF	PORTB		; Connectees au PORTB

		CALL	tempo		; Appel de la temporisation

		MOVLW	B'00001000'	; Valeur pour allumer les LED

		MOVWF	PORTB		; Connectees au PORTB

		CALL	tempo		; Appel de la temporisation

		MOVLW	B'00000100'	; Valeur pour allumer les LED

		MOVWF	PORTB		; Connectees au PORTB

		CALL	tempo		; Appel de la temporisation

		MOVLW	B'00000010'	; Valeur pour allumer les LED

		MOVWF	PORTB		; Connectees au PORTB

		CALL	tempo		; Appel de la temporisation

		MOVLW	B'00000001'	; Valeur pour allumer les LED

		MOVWF	PORTB		; Connectees au PORTB

		CALL	tempo		; Appel de la temporisation

		MOVLW	B'00000000'	; Valeur pour allumer les LED

		MOVWF	PORTB		; Connectees au PORTB

		RETURN			; Retour

		;-------------------------------------------------------------

		; Clignotement pour signifier l'effacement

blink_delete	MOVLW	B'00101000'	; Valeur pour allumer les LED

		MOVWF	PORTB		; Connectees au PORTB

		CALL	tempo_7f	; Appel tempo moyenne

		MOVLW	B'00010100'	; Valeur pour allumer les LED

		MOVWF	PORTB		; Connectees au PORTB

		CALL	tempo		; Appel de la temporisation

		MOVLW	B'00001010'	; Valeur pour allumer les LED

		MOVWF	PORTB		; Connectees au PORTB

		CALL	tempo		; Appel de la temporisation

		MOVLW	B'00000101'	; Valeur pour allumer les LED

		MOVWF	PORTB		; Connectees au PORTB

		CALL	tempo		; Appel de la temporisation

		MOVLW	B'00000010'	; Valeur pour allumer les LED

		MOVWF	PORTB		; Connectees au PORTB

		CALL	tempo		; Appel de la temporisation

		MOVLW	B'00000001'	; Valeur pour allumer les LED

		MOVWF	PORTB		; Connectees au PORTB

		RETURN			; Retour

		;-------------------------------------------------------------

		; Clignotement pour signifier un effacement

blink_erase	MOVLW	B'00111111'	; Valeur pour allumer les 6 LED

		MOVWF	PORTB		; Connectees au PORTB

		CALL	tempo_7f	; Appel tempo moyenne

		MOVLW	B'00000000'	; Valeur pour eteindre les 6 LED

		MOVWF	PORTB		; Connectees au PORTB

		RETURN			; Retour d'ou l'on vient

		;-------------------------------------------------------------

		; Clignotement pour signifier l'ordre recu

blink_ack	MOVLW	B'00110000'	; Valeur pour allumer LD5 et LD6

		MOVWF	PORTB		; Connectees au PORTB

		CALL	tempo_c0	; Appel tempo courte

		MOVLW	B'00000000'	; Valeur pour eteindre les 6 LED

		MOVWF	PORTB		; Connectees au PORTB

		CALL	tempo_c0	; Appel tempo courte

		MOVLW	B'00110000'	; Valeur pour eteindre les 6 LED

		MOVWF	PORTB		; Connectees au PORTB

		CALL	tempo_c0	; Appel tempo courte

		MOVLW	B'00000000'	; Valeur pour eteindre les 6 LED

		MOVWF	PORTB		; Connectees au PORTB

		RETURN			; Retour d'ou l'on vient

tempo_c0	MOVLW	H'00C0'

		MOVWF	TIMER_VALUE

		CALL	tempo

		RETURN

tempo_ff	MOVLW	H'00FF'

		MOVWF	TIMER_VALUE

		CALL	tempo

		RETURN

tempo_7f	MOVLW	H'007F'

		MOVWF	TIMER_VALUE

		CALL	tempo

		RETURN

MENU		CALL	tempo_ff

		CALL	store_sw

		CALL	choose

		GOTO	MENU		;Aller à MENU

		END

Conclusion :


Il est important d'imprimer la signification des 4 boutons car ils ont 2 usages...

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.