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 ---
- 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 ---
Modérateur : mazertoc
Gestion encodeur V2 basse résolution
- F6FCO

Expert- Messages : 2857
- Âge : 99
- Enregistré en : décembre 2017
- Localisation : Banlieue sud de Klyntar
- Contact :
Salut les gens,
Une nouvelle version de gestion d'encodeur que j'utilise sur mon servomoteur CC. Le bras se déplace de 180° (et plus si nécessaire), j'utilise les ticks générés par l'encodeur pour contrôler le déplacement, pour des raisons que j'expliquerai sur le sujet du servomoteur j'ai besoin d'un encodeur basse résolution. Cette version ne compte volontairement qu'un tick sur deux et divise par conséquent la résolution/tour par deux.
Pour ceux qui voudraient se prendre la tête à comprendre le code asm les équations et l'algorithme sont d'une grande aide.
Les équations:
L'algorithme:
Ce code peut servir à piloter un encodeur pour n'importe quel projet, ici je m'en sert pour mon servomoteur CC.
On retrouve le sens de rotation sur les bits H, AH et immo. On récupère le nombre de ticks générés dans la variable ptr.
Encodeur testés: mécanique chinois et Wurst: 20 crans/tour au toucher, 4 états par crans ---> 80 ticks par tour. J'avais besoin de moins.
De base l'algo pourrait être très simple mais j'ai du le complexifier avec la variable flag: le bras monté sur un moteur gearbox 60rpm se déplace... à 60rpm.
Le pic lui, est cadencé par l'horloge interne à 8Mhz, le temps que l'encodeur monté sur l'axe arrière du moteur 60rpm génère un tick le PIC aura effectué plusieurs millions d'itérations, ce qui modifie ptr à chaque itération, donc la grosse zone. La variable flag limite la modification de ptr à la seule première itération et ignore les autres tant qu'on n'a pas changé d'état sur l'encodeur.
Le code:
Une nouvelle version de gestion d'encodeur que j'utilise sur mon servomoteur CC. Le bras se déplace de 180° (et plus si nécessaire), j'utilise les ticks générés par l'encodeur pour contrôler le déplacement, pour des raisons que j'expliquerai sur le sujet du servomoteur j'ai besoin d'un encodeur basse résolution. Cette version ne compte volontairement qu'un tick sur deux et divise par conséquent la résolution/tour par deux.
Pour ceux qui voudraient se prendre la tête à comprendre le code asm les équations et l'algorithme sont d'une grande aide.
Les équations:
L'algorithme:
Ce code peut servir à piloter un encodeur pour n'importe quel projet, ici je m'en sert pour mon servomoteur CC.
On retrouve le sens de rotation sur les bits H, AH et immo. On récupère le nombre de ticks générés dans la variable ptr.
Encodeur testés: mécanique chinois et Wurst: 20 crans/tour au toucher, 4 états par crans ---> 80 ticks par tour. J'avais besoin de moins.
De base l'algo pourrait être très simple mais j'ai du le complexifier avec la variable flag: le bras monté sur un moteur gearbox 60rpm se déplace... à 60rpm.
Le pic lui, est cadencé par l'horloge interne à 8Mhz, le temps que l'encodeur monté sur l'axe arrière du moteur 60rpm génère un tick le PIC aura effectué plusieurs millions d'itérations, ce qui modifie ptr à chaque itération, donc la grosse zone. La variable flag limite la modification de ptr à la seule première itération et ignore les autres tant qu'on n'a pas changé d'état sur l'encodeur.
Le code:
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)
Code : Tout sélectionner
;******************************************************************************
; F6FCO - février 2026;
; gestion d'un encodeur en quadrature V2
;
; Cette version ne compte volontairement qu'un tick sur deux pour
; utiliser un encodeur dans une fourchette de 0 255 sans dépassement
; de part et d'autre
;
; horloge 8Mhz interne
;
;******************************************************************************
;
; IMPORTANT, A SAVOIR !!!
; Les encodeurs mécaniques chinois bon marché d'Aliexpress génèrent 4 ticks par cran
; 1 tour = 20 crans (pas) = 80 ticks
;
#include<Fusibles 18f2525.asm>
; gestion encodeur
#define pinA PORTB,0 ; pin A encodeur
#define pinB PORTB,1 ; pin B encodeur
#define newA bits_encodeur,0
#define newB bits_encodeur,1
#define oldA bits_encodeur,2
#define oldB bits_encodeur,3
#define H bits_gestion,1
#define AH bits_gestion,2
#define immo bits_gestion,3
moteur_tourneH macro
bcf driverA
bsf driverB
endm
moteur_tourneAH macro
bsf driverA
bcf driverB
endm
moteur_stop macro
bcf driverA
bcf driverB
endm
CBLOCK 0x00C
tmp :1
w_temp :1 ; Sauvegarde du registre W
status_temp :1 ; Sauvegarde du registre STATUS
Reg_1 :1
Reg_2 :1
Reg_3 :1
;
; --------------------Variables gestion_encodeur
ptr :1 ; nombre de ticks générés
flag_comptage :1 ; utilisé dans gestion_encodeur
bits_encodeur :1 ; bits de gestion
; <0> newA
; <1> newB
; <2> oldA
; <3> oldB
; <4>
; <5>
; <6>
; <7>
bits_gestion ; <0>
; <1> H
; <2> AH
; <3> immo
; <4>
; <5>
; <6>
; <7>
conchita :1 ; variable bonne à tout faire
; --------------------
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'00110000' ; 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
; ------------------------- initialisation
clrf bits_gestion
clrf conchita
clrf bits_encodeur
movlw d'128'
movwf ptr
nop
testA ; lecture pinA encodeur
btfss pinA
bra pinA00
bsf newA
bra testB
pinA00 bcf newA
testB ; lecture pinB encodeur
btfss pinB
bra pinB00
bsf newB
bra fin_test_pin
pinB00 bcf newB
; on a maintenant ici l'état présent de l'encodeur
; dans oldA et oldB
fin_test_pin
; vers fichier main_ServoMoteurCC.asm
; -----------------------------------
Code : Tout sélectionner
#include <Init_encodeur V2.asm>
main
nop
call gestion_encodeur
bra main
#include <Routines_encodeur V2.asm>
END
Code : Tout sélectionner
gestion_encodeur:
nop
; -------------------
; mise en mémoire oldA=newA et oldB=newB
movf bits_encodeur,WREG
rlncf WREG,f
rlncf WREG,f
andlw b'00001111'
movwf bits_encodeur
; oldA=newA oldB=newB
nop
; -------------------
; lecture pins encodeur et mise en mem dans newA et newB
bcf newA
bcf newB
movff PORTB,conchita
btfsc conchita,0
bsf newA
btfsc conchita,1
bsf newB ; newB=1
; newA=pinA newB=pinB
nop
; -------------------
; teste si b./oldA
ge0 movf bits_encodeur,WREG
andlw 0x0f
movff WREG,conchita
;
movlw b'1000'
cpfseq conchita
bra ge1
movlw d'1'
cpfseq flag_comptage
bra ge6
ge1 ; teste si /B.oldA
movf bits_encodeur,WREG
andlw 0x0f
movff WREG,conchita
;
movlw b'0111'
cpfseq conchita
bra ge2
movlw d'2'
cpfseq flag_comptage
bra ge7
ge2 ; ------------------
; teste si B.oldA
movf bits_encodeur,WREG
andlw 0x0f
movff WREG,conchita
;
movlw b'1011'
cpfseq conchita
bra ge3
movlw d'3'
cpfseq flag_comptage
bra ge8
ge3 ; teste si /B./oldA
movf bits_encodeur,WREG
andlw 0x0f
movff WREG,conchita
;
movlw b'0100'
cpfseq conchita
bra ge4
movlw d'4'
cpfseq flag_comptage
bra ge9
ge4 ; ------------------
; aucunes conditions au-dessus alors on est immobile
bcf H
bcf AH
bsf immo
bra ge5
ge6 ; -----------------
; on tourne sens horaire
movlw d'1'
movwf flag_comptage
bra ge10
ge7 movlw d'2'
movwf flag_comptage
ge10 bsf H
bcf AH
bcf immo
incf ptr
bra ge5
ge8 ; ----------------
; on tourne sens anti-horaire
movlw d'3'
movwf flag_comptage
bra ge11
ge9 movlw d'4'
movwf flag_comptage
ge11 bcf H
bsf AH
bcf immo
decf ptr
ge5 nop
return
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Retourner vers « Langage ASM »
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 4 invités
