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.