Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur l'Assembleur !

Modérateur : mazertoc

Petit topo sur la gestion d'un encodeur en ASM
F6FCO
Avatar de l’utilisateur
Expert
Expert
Messages : 1413
Âge : 70
Enregistré en : décembre 2017
Localisation : Furtif je suis.
Contact :

#1 Message par F6FCO » lun. 25 oct. 2021 15:22

Hello les gens,

Pour mon projet avec l'AD9850 j'ai besoin de gérer un encodeur, plutôt que de chercher sur le net j'ai ré-inventé la roue, c'est plus amusant.
J'ai utilisé un encodeur très bas de gamme chinois mais çà doit convenir à n'importe quel autre type d'encodeur pour peu que le chronogramme soit identique. En examinant le résultat à l'analyseur logique j'ai été surpris de la bonne qualité des signaux, aucun rebond et pas obligé d'inclure des tempos pour les masquer. J'avais pourtant déjà été bien embêté auparavant avec ce type de composant.

Principe:
Pour comprendre le fonctionnement il suffit de faire le chronogramme de l'encodeur, de l'observer et d'en tirer une table de vérité. Il faut auparavant sauvegarder l'état antérieur des pins pour les comparer ensuite avec le nouvel état.
On s'aperçoit que si on tourne en sens anti-horaire la pin A vaut toujours B_old, et à l'inverse si on tourne en sens horaire la pin A est toujours différente de B_old.
Si on n'a pas touché l'encodeur rien ne change, A=A_old et B=B_old.

ec1.jpg


A partir de là on a tout ce qu'il faut pour pondre un algorithme:

ec2.jpg


Et en tirer un code ASM.
La première partie concerne juste l'initialisation du PIC:

Code : Tout sélectionner

;************************************************************************************************
;
                         F6FCO - Init PIC 18F4525                        ;
;
                                                                                      ;
;**********************************************************************************************
 ;


        Errorlevel-302 
        list        p
=18f4525                
        
#include    <p18f4525.inc>            
    

 CONFIG OSC 
= INTIO67                     ; Oscillateur interne 8MHz 
 CONFIG IESO 
= OFF                        ; Délai au démarrage (ON/OFF)
 CONFIG BOREN = OFF                       ; Reset si chute de tension (ON/OFF)
 CONFIG BORV = 0                          ; Tension de reset en 1/10ème Volts 
 CONFIG WDT 
= OFF                         ; Mise hors service du watchdog (ON/OFF)
 CONFIG PBADEN = OFF                      ; PORTB<4:0> les broches sont configurées comme E/S numériques lors de la réinitialisation
 CONFIG LPT1OSC 
= OFF                     ; Timer1 configuré pour un fonctionnement plus puissant
 CONFIG MCLRE 
= ON                        ; Mclr configuré comme entrée
 CONFIG STVREN 
= ON                       ; Reset sur débordement de pile (ON/OFF)
 CONFIG LVP = OFF                         ; Programmation basse tension autorisée (ON/OFF)
 CONFIG XINST = OFF                       ; L'extension du jeu d'instructions et le mode d'adressage indexé sont désactivés(mode hérité)
 CONFIG DEBUG = OFF                       ; Debugger hors service
 CONFIG CP0 = OFF                         ; Code protection sur block 0 (ON/OFF)
 CONFIG CP1 = OFF                         ; Code protection sur block 1 (ON/OFF)
 CONFIG CP2 = OFF                         ; Code protection sur block 2 (ON/OFF)
 CONFIG CPB = OFF                         ; Code protection sur bootblock  (ON/OFF)
 CONFIG CPD = OFF                         ; Code protection sur eeprom (ON/OFF)
 CONFIG WRT0 = OFF                        ; Protection écriture block 0 (ON/OFF)
 CONFIG WRT1 = OFF                        ; Protection écriture block 1 (ON/OFF)
 CONFIG WRT2 = OFF                        ; Protection écriture block 2 (ON/OFF)
 CONFIG WRTB = OFF                        ; Protection écriture bootblock (ON/OFF)
 CONFIG WRTC = OFF                        ; Protection écriture configurations (ON/OFF)
 CONFIG WRTD = OFF                        ; Protection écriture zone eeprom (ON/OFF)
 CONFIG EBTR0 = OFF                       ; Protection lecture de table block 0 (ON/OFF)
 CONFIG EBTR1 = OFF                       ; Protection lecture de table block 1 (ON/OFF)
 CONFIG EBTR2 = OFF                       ; Protection lecture de table block 2 (ON/OFF)
 CONFIG EBTRB = OFF                       ; Protection lecture de table bobtfsssssssssssssssotblock (ON/OFF)

; ------------------------------------ #define
;#define        EncA    PORTD,0

; ------------------------------------ 
     CBLOCK H'
0
        EncA_old    :1     ; état de la pin A de l'
encodeur au tour d'avant
        EncB_old    :1     ; état de la pin B de l'
encodeur au tour d'avant
        Sens        :1    ; sens de rotation de l'
encodeur
        Valeur        
:1
    ENDC

    ORG H
'0'
    
; ------------------------------------ 
init
        movlw     B
'01110011'
        movwf     OSCCON            
    movlw    b
'00000000'
    movwf    TRISC
    movwf    TRISB
    movlw    b
'00000011'        ; les 2 pins de l'encodeur en entrée, ici sur le PORTD
    movwf    TRISD
    
    



La routine de gestion de l'encodeur proprement dite, elle se suffit à elle-même. Ca aurait pu être optimisé au niveau des tests mais pour qu'elle soit portable des 16F aux 18F je n'ai pas utilisé celles spécifiques aux 18F. Il faut déclarer les variables EncA_old, EncB_old et Sens, toutes sur 1 octet. Il suffit ensuite de l'invoquer. L'encodeur est ici câblé sur PORTD,0 et PORTD,1, si on veut changer il ne faut pas oublier de modifier la routine au niveau des comparaisons ANDLW et la valeur du décalage RRNCF.

Code : Tout sélectionner

;------------------------------------------------------------------------------
;
;
        Gestion encodeur rotatif - F6FCO -
;
            Octobre 2021
;
;
    pin A de l'encodeur sur PORTD,0   configurée en input
;    pin B de l'
encodeur sur PORTD,1   configurée en input
;
;
 Déclarer les variables:
;
    EncA_old    :1     ; état de la pin A de l'encodeur au tour d'avant
;    EncB_old    :1     ; état de la pin B de l'encodeur au tour d'avant
;    Sens        :1    ; sens de rotation de l'encodeur
;-------------------------------------------------------------------------------

Gestion_encodeur
    movf    PORTD,w
    andlw    b'
00000001'
    subwf    EncA_old,w
    btfsc    STATUS,Z
    goto    enc1
        
enc3    movf    PORTD,w        ; est-ce que A=B_old ?
    andlw    b'
00000010'
    rrncf    WREG,w
    subwf    EncA_old,w
    btfsc    STATUS,Z
    goto    enc4
    movlw    1
    movwf    Sens        ; Sens=1  horaire
    
enc5    movf    PORTD,w
    andlw    b'
00000001'
    movwf    EncA_old
    movf    PORTD,w
    andlw    b'
00000010'
    movwf    EncB_old
    return    

enc1    movf    PORTD,W
    andlw    b'
00000010'
    subwf    EncB_old,w
    btfss    STATUS,Z
    goto    enc3
    
enc2    movlw    2
    movwf    Sens        ; sens=2  encodeur figé
    return
    
enc4    clrf    Sens        ; Sens=0 anti-horaire
    goto    enc5


La partie main qui sera variable selon le programme de chacun, ici je me suis contenté pour l'exemple d'incrémenter ou décrementer la variable "Valeur".

Code : Tout sélectionner


     
#include     <encodeur init.asm>
; -----------------------------------
;
initialisations variables encodeur
    movlw    2
    movwf    Sens
    movf    PORTD
,w
    andlw    b
'00000001'
    movwf    EncA_old
    movf    PORTD
,w
    andlw    b
'00000010'
    movwf    EncB_old
    movlw    d
'127'
    movwf    Valeur
main
    call    Gestion_encodeur
    movf    Sens
,w
    sublw    2        
; test si Sens=2 inerte
    btfsc    STATUS
,Z
    goto    fin
    movf    Sens
,w
    sublw    1        
; test si Sens =1 horaire
    btfsc    STATUS
,Z
    bra    horaire
    goto    AntiHoraire    
; sinon antihoraire
    
horaire decf    Valeur
    goto    fin
    
AntiHoraire
    incf    Valeur
    
fin    goto    main
    
; ----------------------------------------
#include    <encodeur routines.asm>
end
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Une porte nand prend 2 bits en entrée... la cochonne !!! :langue:

Petit topo sur la gestion d'un encodeur en ASM
Temps-x
Avatar de l’utilisateur
Expert
Expert
Messages : 2596
Enregistré en : juillet 2016
Localisation : Terre

#2 Message par Temps-x » mar. 26 oct. 2021 01:03

Bonsoir F6FCO, et tout le forum,

Une fois souder tu pourrais avoir des surprises, car la chaleur ou le placage sur le circuit imprimé modifie le comportement de celui-ci.
de plus je te conseille de rajouter 2 condensateurs avec 2 résistances de 10K comme sur l'image ci-dessous.

Encodeur rotatif.jpg


Dans mon code ASM je n’utilise pas de et logique, juste un teste, voici un exemple ci-dessous.

Code : Tout sélectionner

;***** "encodeur rotatif avec résistance sur PORTB activé via paramètre du microcontrôleur" **** 
encodeur   
      btfsc PORTB
,7                       ; si le bit RB7 est à 1 on va à la ligne 1 
      return                               

      btfss PORTB
,7                       ; si le bit RB7 est à 0 on va à la ligne 1
      goto 
$+D'2'
      goto sens_1                         ; cran de l'encodeur relâché
      call _10ms                          ; gestion anti rebond          
  
sens_1                                      
      btfsc PORTB,6                       ; si le bit RB6 est à 1 on va à la ligne 1 
      goto augmente'
                      ; augmente le nombre
sens_2
      btfss PORTB
,6                       ; si le bit RB6 est à 0 on va à la ligne 1
      goto 
$+D'2'
      goto diminuer'                      ; diminuer le nombre      
      call _10ms                          ; gestion anti rebond
      goto sens_2


augmente
      incf chiffre,F
      return

diminuer
      decf chiffre,F
      return      



==> A+
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
:roll: Les requins, c'est comme le langage ASM, c'est le sommet de la chaîne alimentaire. :wink:

Petit topo sur la gestion d'un encodeur en ASM
F6FCO
Avatar de l’utilisateur
Expert
Expert
Messages : 1413
Âge : 70
Enregistré en : décembre 2017
Localisation : Furtif je suis.
Contact :

#3 Message par F6FCO » mar. 26 oct. 2021 15:39

Salut Temps-X,

Quelles surprises ? un encodeur ne chauffe pas.
Mon schéma de câblage est représenté plus haut sur la même feuille que l'algorithme, le même que le tien à part la valeur des résistances, j'ai mis des 4.7k car les 10k ne donnaient pas un état haut franc.
J'évite dans la mesure du possible d'utiliser les pins B6 et B7 réservées au Pickit.

Je réfléchis maintenant à greffer un affichage sur le trio PIC/encodeur/AD9850. Pas simple.
Une porte nand prend 2 bits en entrée... la cochonne !!! :langue:

Petit topo sur la gestion d'un encodeur en ASM
Temps-x
Avatar de l’utilisateur
Expert
Expert
Messages : 2596
Enregistré en : juillet 2016
Localisation : Terre

#4 Message par Temps-x » mer. 27 oct. 2021 00:46

Bonsoir F6FCO, et tout le forum,

F6FCO a écrit :Source du message Quelles surprises ?


J'ai remarqué qu'une fois soudé sur le PCB que l'encodeur ne fonctionne plus comme avant le soudage (c'est une constatation, j'espère que tu n'auras pas les mêmes problème que moi)

F6FCO a écrit :Source du message un encodeur ne chauffe pas

:lol: Bien sur que non, et heureusement, c'est juste quand tu vas le souder que ça va chauffer, c'est sensible à la chaleur du fer à souder, si c'est trop chauffé tu peux l'endommager(c'est du vécu)
F6FCO a écrit :Source du message Mon schéma de câblage est représenté plus haut sur la même feuille que l'algorithme, le même que le tien à part la valeur des résistances

oops je n'avais pas vu, sory
F6FCO a écrit :Source du message j'ai mis des 4.7k car les 10k ne donnaient pas un état haut franc.

Tu peux te servir du tirage des résistances via ton microcontrôleur, ça économise des résistances, de plus le Pic18F27K42 permet de choisir n'importe quelle patte qu'on veut avec tirage de résistance.

F6FCO a écrit :Source du message J'évite dans la mesure du possible d'utiliser les pins B6 et B7 réservées au Pickit.

Normalement ça ne pose pas de problème, mais quand tu peux c'est mieux comme tu le préconise.

F6FCO a écrit :Source du message Je réfléchis maintenant à greffer un affichage sur le trio PIC/encodeur/AD9850. Pas simple.

Tout ta fait d'accord avec toi, je fini le fréquencemètre, après je m'attaque au NCO

Pour la sélection il faut en premier lieu définir la fréquence : soit en hertz, kilohertz, mégahertz, après voir le pas qu'on veut lieu donnée

==> A+
:roll: Les requins, c'est comme le langage ASM, c'est le sommet de la chaîne alimentaire. :wink:

Petit topo sur la gestion d'un encodeur en ASM
F6FCO
Avatar de l’utilisateur
Expert
Expert
Messages : 1413
Âge : 70
Enregistré en : décembre 2017
Localisation : Furtif je suis.
Contact :

#5 Message par F6FCO » jeu. 28 oct. 2021 22:19

Pour l'instant je lui ai greffé un petit fréquencemètre chinois à 8€ histoire de le mettre au point. Le fréquencemètre à PIC est aussi un projet. En fait je suis en train de construire un petit émetteur dont ce géné sera la base. Ensuite il faut que j'en refasse un autre pour le récepteur.

Mais je galère un peu sur le préampli de sortie, le signal donné par le l'AD9850 n'est pas assez costaud pour attaquer la suite de l'émetteur. J'ai vu que Paulfjujo en a mis un sur son AD9850 mais il me semble qu'il lui faut du -5v.
Une porte nand prend 2 bits en entrée... la cochonne !!! :langue:


Retourner vers « Langage ASM »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 39 invités