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

Gestion précise d'un encodeur numérique
F6FCO
Avatar de l’utilisateur
Expert
Expert
Messages : 2287
Âge : 99
Enregistré en : décembre 2017
Localisation : Furtif je suis.
Contact :

#1 Message par F6FCO » dim. 22 déc. 2024 20:20

Hello les gens,
Temps tout pourri dehors j'en ai profité pour pondre une routine qui me servira à la mise au point de mon servo ultra-puissant. J'ai fais un sujet ailleurs sur le forum sur la gestion d'un encodeur en quadrature, comme la majorité des programmes qu'on peut trouver sur la question il ne donne que le sens de rotation, horaire ou anti-horaire,
Mais là j'ai besoin de récupérer les ticks, au cours d'une séquence (au moment ou le déphasage des signaux retrouve la même position) on s'aperçoit qu'on peut détecter 4 positions intéressantes, alors que si on se contente de repérer le changement de sens on n'en a qu'une.

Pour chaque sens on peut en tirer les équations suivantes, on aurait pu tracer les tableaux de Karnaugh mais les équations se suffisent à elles-mêmes pour détecter les bons moments. En orange les moments T, en jaune les moments T-1:

Sens Horaire

encH.jpg


Sens Anti-horaire

encAH.jpg


A partir de ces deux équations on peut poser l'algorigramme suivant, le programme positionne trois variables, "sensH" pour une rotation horaire, "sensAH" pour une rotation anti-horaire et "immo" si l'encodeur n'a pas bougé. Ces trois variables sont remises à zéro à chaque appel de la routine, on peut donc s'en servir pour les compter quand elles sont positionnées, ensuite ce sera suivant le projet demandé, il suffira d'incrémenter une variable suivant la progression de sensH ou sensAH.
A noter que si le nombre de ticks généré est trop important (s'il n'est pas nécessaire de compter au-delà de 256) on peut commenter quelques tests aux labels e1/e8 et e3/e10, on ne testera alors plus que deux fois au lieu de 4.

enc.jpg




Code : Tout sélectionner

; ***********************************************************************************************
;
                     F6FCO
;                 Réglages des fusibles 18f2525
;
;************************************************************************************************

        Errorlevel-302             ; Supprime le message "Ensure that bank bits are correct" 
        list            p
=18f2525    ; processeur utilisé 
        
#include        <p18f2525.inc>    ; Définitions des constantes PIC
    
 CONFIG OSC 
= INTIO67                   ; Oscillateur interne 8MHz 
 
;CONFIG OSC = XT                         ; Oscillateur xtal externe 
 CONFIG IESO 
= OFF                         ; Délai au démarrage (ON/OFF)
 CONFIG BOREN = OFF                        ; Reset si chute de tension (ON/OFF)
 CONFIG PWRT = ON                          ; Délai au démarrage (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 bootblock (ON/OFF)


Fichier init:

Code : Tout sélectionner

;******************************************************************************
;
                           F6FCO - dec 2024                                            
;                 
;                gestion encodeur
;                horloge 8Mhz interne
;        
;******************************************************************************

#include<Fusibles 18f2525.asm>


; gestion encodeur
#define pinA         PORTB,0        ; pin A encodeur
#define pinB        PORTB,1        ; pin B encodeur
#define At        encodeurB,0    ; valeur pinA au moment T
#define Bt        encodeurB,1    ; veleur pinB au moment T
#define A_old        encodeurB,2    ; valeur pinA au moment T-1
#define B_old        encodeurB,3    ; valeur pinB au moment T-1
#define sensH        encodeurB,4    ; sens de rotation de l'encodeur 
#define sensAH         encodeurB,5    ; sens de rotation anti horaire
#define immo        encodeurB,6    ; encodeur immobile
;gestion moteur cc
#define driverA        LATB,3        ; driver L298
#define driverB        LATB,4        ; driver L298

#define consigne    d'20'        ; nb d'impulsions à envoyer au moteur
     

    CBLOCK 0x00C               
    w_temp         
:1        ; Sauvegarde du registre W
    status_temp     
:1        ; Sauvegarde du registre STATUS
    Reg_1        
:1
    Reg_2        
:1
    Reg_3        
:1
    conchita    
:2        ; variable bonne à tout faire    
    conchita2    
:1
    ptr        
:1
    encodeurB    
:1        ; pins encodeur au moment T et T-1
            
; <0> A
            
; <1> B
            
; <2> A_old
            
; <3> B_old
            
; <4> sensH
            
; <5> sensAH
            
; <6> immo
            
; <7> 
    ENDC                                      

    org    0x000             
; Adresse de départ après reset     


    bra        init            

; ------------------------  Routines Interruptions                            
    
;sauvegarder registres    
    org     0x008            
; adresse d'interruption
    movwf   w_temp          ; sauver registre W
    swapf    STATUS,w        ; swap status avec résultat dans w
    movwf    status_temp        ; sauver status swappé
    
    ; Interrupt MSSP
    btfss    PIR1,SSPIF        ; <3>
    bra    restorereg        
    call    intMSSP            ; on vient d'
avoir une int MSSP, on la traite
        
    
;restaurer registres
restorereg
    swapf    status_temp
,w        ; swap ancien status, résultat dans w
    movwf   STATUS            
; restaurer status
    swapf   w_temp
,f        ; Inversion L et H de l'ancien W, sans modifier Z
    swapf   w_temp,w          ; Réinversion de L et H dans W, W restauré sans modifier status
    retfie              ; return from interrupt

intMSSP
    movff    SSPBUF,conchita
    bsf    SSPCON1,CKP        ; on relâche l'
horloge
    bcf    PIR1
,SSPIF        ; <3> raz flag d'interrupt                         
    return
    
    
    
; ------------------------ Init

init
    clrf    EEADR            ; diminue la consommation
    ; init oscillateur
    movlw    0xff            ; Horloge interne 8Mhz
    movwf    OSCCON

        ; init ports
        movlw     0xff
          movwf     ADCON1                ; mode digital
          bcf    ADCON0,ADON        ; <0> CAN désactivé
          
          movlw    0x07
          movwf    CMCON            ; mode comparateur désactivé

    movlw    b'
00000011'        
    movwf    TRISB
    clrf    PORTB
    clrf    LATB
    
    movlw    b'
00000000'        ; rc3/rc4 I2C        
    movwf    TRISC
    clrf    PORTC
    clrf    LATC

    ; init interruptions
    bsf    RCON,IPEN
    bsf    INTCON,GIE        ; <7> int non masquées activées
    bsf    INTCON,PEIE        ; <6> int périphériques non masquées activées
    bsf    PIE1,SSPIE        ; <3> MSSP activé
    bcf    PIR1,SSPIF        ; <3> flag interrupt à zéro
    bsf    SSPCON1,SSPEN        ; <5> rb0 et rb1 en mode SDA/SCL
    
        
    ; mode esclave 7 bits avec interruptions
    bsf    SSPCON1,SSPEN        ; <5>
    bsf    SSPCON1,CKP        ; <4>

    bcf    SSPCON1,SSPM0        ; <0>        
    bsf    SSPCON1,SSPM1        ; <1>
    bsf    SSPCON1,SSPM2        ; <2>
    bcf    SSPCON1,SSPM3        ; <3>

    bsf    SSPCON2,SEN        ; <0> Etirement horloge activé

    ; adresse esclave
    movlw    b'
00010000'    
    movwf    SSPADD
    
    bsf    SSPSTAT,S        ; <3> startbit
    
    

    

    ; vers main
; -----------------------------------
            



Le fichier main

Code : Tout sélectionner

#include <init.asm>


    clrf    conchita
    clrf    encodeurB
    clrf    ptr
main    
    
    call    Lecture_encodeurB
    bra    main









#include <Routines.asm>

    END


Le fichier routine

Code : Tout sélectionner

Lecture_encodeurB
    
    bcf    sensH
    bcf    sensAH
    bcf    encodeurB
,0
    bcf    encodeurB
,1
    btfsc    pinA            
; état de la pinA encodeur
    bsf    encodeurB
,0
    btfsc    pinB            
; état de la pinB encodeur
    bsf    encodeurB
,1    
    nop 

e0    movff    encodeurB
,WREG
    cpfseq    conchita
    bra    e1
    bra    e12
    
    
; --------Décommenter e1 et e3 pour rendre l'encodeur plus précis
    ;         4 lectures au lieu de 2
e1    ;btfsc    Bt            ; test si sens horaire    
    ;bra    e8
e2    btfss    Bt            ; test si sens horaire
    bra    e9
e3    ;btfsc    Bt            ; test si sens anti-horaire
    ;bra    e10
e4    btfss    Bt            ; test si sens anti-horaire
    bra    e11

e5    
    ; on range A et B dans A_old et B_old
    bcf    A_old
    bcf    B_old
    btfsc    At
    bsf    A_old
    btfsc    Bt
    bsf    B_old
    movff    encodeurB,conchita
e6    nop
    return
        
e8    btfss    A_old
    bra    e13
    bra    e2


e9    btfsc    A_old
    bra    e13
    bra    e3
    
e10    btfsc    A_old
    bra    e14
    bra    e4
    
e11    btfss    A_old
    bra    e14
    bra    e5

    ; encodeur immobile
e12    bcf    sensH
    bcf    sensAH
    bsf    immo
    bra    e5
    
    ; encodeur à tourné sens horaire
e13    bsf    sensH
    bcf    sensAH
    bcf    immo
    incf    ptr
    nop
    nop
     bra    e5
    
    ; encodeur à tourné sens anti-horaire
e14    bcf    sensH
    bsf    sensAH
    bcf    immo
    decf    ptr
    nop
    nop
    bra    e5    


Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Une porte nand prend 2 bits en entrée... :eek:

Retourner vers « Langage ASM »

Qui est en ligne

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