latif18 | Dernière version, le programme fonctionne +ou- , les octets sont bien reçus, les servos sont bien commandés mais toujours des problèmes si un octet est envoyé pendant qu'il est dans l'interruption timer (je suppose) des fois ça marche, des fois ça déconne pas mal
J'ai essayé de réduire le temps qu'il reste dans l'interruption timer0, il n'y va que pour allumer ou éteindre les sorties, il n'y a plus de boucle pour créer des tempo mais il y a encore bcp de bordel à l'intérieur de l'interruption.
Code :
- $MOD51
- $TITLE(essai)
- $PAGEWIDTH(132)
- $DEBUG
- $OBJECT
- $NOPAGING
- ; *************************************************************************
- ; * *
- ; * PROGRAMME ASSEMBLEUR POUR LA FAMILLE MCS-51 *
- ; * *
- ; *************************************************************************
- ; * *
- ; * Titre: Commande servo-moteur par port RS232 *
- ; * Microcontrôleur: at89s8252 *
- ; * Auteur: David *
- ; * Objet: *
- ; * Date: *
- ; * Version: *
- ; * *
- ; *************************************************************************
- org 0000h ;vecteur reset
- ljmp 0100h ;saut au delà des vecteurs d'interruption
- ; ***************************************
- ; * Interruptions *
- ; ***************************************
- org 000Bh ;interruption Timer0
- LJMP INT_TIMER0
- reti
- org 0023h ;interruption interface sérielle
- LJMP INT_SER
- reti
- org 0100h ;début du programme
- ; ***************************************
- ; * Initialisation des SFR's *
- ; ***************************************
- MOV IE,#092h ;Active les interruptions sérielle et timer0
- MOV SCON,#050h ;active la réception
- MOV TMOD,#021h ;mode 16 bits pour timer0 (8bits à préchargement auto pour timer0)
- MOV IP,#010h ;priorité réception série
- MOV TCON,#050h ;Timer 0 et 1 en RUN
- MOV PCON,#080h ;Double le data rate (28800baud)
- ; ***************************************
- ; * Initialisation des variables *
- ; ***************************************
- ; Variables 1 bit
- ; variables 1 octet
- N_SERVO DATA 10h
- POSITION_SERVO DATA 11h
- POSITION_SERVO1 DATA 12h
- POSITION_SERVO2 DATA 13h
- POSITION_SERVO3 DATA 14h
- POSITION_SERVO4 DATA 15h
- POSITION_SERVO5 DATA 16h
- ; ***************************************
- ; * Programme principal *
- ; ***************************************
- MOV TH1,#0FEh ;chargement compteur pour 28800 baud
- MOV R1,#00h ;Mise à zéro de quelques registres et des sorties
- MOV P2,#00h
- MOV P1,#00h
- SETB P3.1 ;Sortie TX et RX
- CLR P3.0
- MOV R0,#0FFh ;47FF qui correspond à 18431 cycles ==> 20 mS
- MOV R1,#047h
- BOUCLE: ; Programme qui remplira les cases mémoires
- ; avec la position de chaque servo
- MOV A,N_SERVO
- SERVO1:
- CJNE A,#01h,SERVO2
- MOV A,POSITION_SERVO
- MOV POSITION_SERVO1,A
- JMP FIN
- SERVO2:
- CJNE A,#02h,SERVO3
- MOV A,POSITION_SERVO
- MOV POSITION_SERVO2,A
- JMP FIN
- SERVO3:
- CJNE A,#03h,SERVO4
- MOV A,POSITION_SERVO
- MOV POSITION_SERVO3,A
- JMP FIN
- SERVO4:
- CJNE A,#04h,SERVO5
- MOV A,POSITION_SERVO
- MOV POSITION_SERVO4,A
- JMP FIN
- SERVO5:
- CJNE A,#05h,FIN
- MOV A,POSITION_SERVO
- MOV POSITION_SERVO5,A
- JMP FIN
- FIN:
- JMP BOUCLE
- ; ***************************************
- ; * Sous programmes *
- ; ***************************************
- INT_SER: ;Réception Série, test de 1 à 5 pour savoir si l'octet
- MOV A,SBUF ;est un numéro de servo ou une position
- ;Fonctionne un peu à pouf :/
- N_SERVO1:
- CJNE A,#01h,N_SERVO2
- MOV N_SERVO,A
- JMP FINI
- N_SERVO2:
- CJNE A,#02h,N_SERVO3
- MOV N_SERVO,A
- JMP FINI
- N_SERVO3:
- CJNE A,#03h,N_SERVO4
- MOV N_SERVO,A
- JMP FINI
- N_SERVO4:
- CJNE A,#04h,N_SERVO5
- MOV N_SERVO,A
- JMP FINI
- N_SERVO5:
- CJNE A,#05h,POSITION_SERV
- MOV N_SERVO,A
- JMP FINI
- POSITION_SERV:
- MOV POSITION_SERVO,A
- FINI:
- CLR RI
- RETI
- INT_TIMER0: ;Interruption Timer qui va allumer/eteindre les sorties
- ;Le timer est préchargé à chaque fois avec les valeurs
- ;pour la position des servos
- INC R2 ;R2 permettra de suivre un ordre à chaque interruption
- ETAPE01:
- CJNE R2,#01h,ETAPE02
- SETB P1.0 ;Allumage sortie p1.0, début de l'impulsion Servo1
- MOV A,POSITION_SERVO1 ;On reprend la position du servo1 qui se trouve en mémoire
- MOV R5,A ;
- LCALL TEMPO_VAR ;appel de la sous-routine de calcul de la durée de l'impulsion
- MOV A,R6 ;Préchargement du compteur avec ce calcul
- MOV TH0,A
- MOV A,R7
- MOV TL0,A
- LCALL CYCLE_UTILISE ;Calcul des 20 mS (on additionne les 5 impulsions,
- LCALL TEMPO_RESTANT ;on soustrait 20 mS de ce total, ce qui nous donnera le temps
- ;restant pour avoir un cycle de 20 mS
- JMP FINII ;On sort de l'interruption
- ETAPE02:
- CJNE R2,#02h,ETAPE03
- CLR P1.0
- SETB P1.1
- MOV A,POSITION_SERVO2
- MOV R5,A ;
- LCALL TEMPO_VAR ;appel de la sous-routine de calcul de l'impulsion
- MOV A,R6
- MOV TH0,A
- MOV A,R7
- MOV TL0,A
- LCALL CYCLE_UTILISE
- LCALL TEMPO_RESTANT
- JMP FINII
- ETAPE03:
- CJNE R2,#03h,ETAPE04
- CLR P1.1
- SETB P1.2
- MOV A,POSITION_SERVO3
- MOV R5,A ;
- LCALL TEMPO_VAR ;appel de la sous-routine de calcul de l'impulsion
- MOV A,R6
- MOV TH0,A
- MOV A,R7
- MOV TL0,A
- LCALL CYCLE_UTILISE
- LCALL TEMPO_RESTANT
- JMP FINII
- ETAPE04:
- CJNE R2,#04h,ETAPE05
- CLR P1.2
- SETB P1.3
- MOV A,POSITION_SERVO4
- MOV R5,A ;
- LCALL TEMPO_VAR ;appel de la sous-routine de calcul de l'impulsion
- MOV A,R6
- MOV TH0,A
- MOV A,R7
- MOV TL0,A
- LCALL CYCLE_UTILISE
- LCALL TEMPO_RESTANT
- JMP FINII
- ETAPE05:
- CJNE R2,#05h,ETAPE06
- CLR P1.3
- SETB P1.4
- MOV A,POSITION_SERVO5
- MOV R5,A ;
- LCALL TEMPO_VAR ;appel de la sous-routine de calcul de l'impulsion
- MOV A,R6
- MOV TH0,A
- MOV A,R7
- MOV TL0,A
- LCALL CYCLE_UTILISE
- LCALL TEMPO_RESTANT
- JMP FINII
- ETAPE06:
- CJNE R2,#06h,FINII
- CLR P1.4
- MOV R2,#00h
- MOV A,R0
- MOV R7,A
- MOV A,R1
- MOV R6,A
- MOV R0,#0FFh
- MOV R1,#0FFh
- LCALL TEMPO_RESTANT
- MOV A,R0
- MOV TL0,A
- MOV A,R1
- MOV TH0,A
- MOV R0,#0FFh
- MOV R1,#047h
- FINII:
- RETI
- CYCLE_UTILISE:
- ;Step 1 of the process
- MOV A,#0FFh ;octet de poid faible
- CLR C ;Always clear carry before first subtraction
- SUBB A,R7 ;octet de poid faible
- MOV R7,A ;Résultat du poid faible dans R7
- ;Step 2 of the process
- MOV A,#0FFh ;octet de poid fort
- SUBB A,R6 ;octet de poid fort
- MOV R6,A ;Résultat du poid fort dans R6
-
- RET
- TEMPO_RESTANT:
- ;Step 1 of the process
- MOV A,R0 ;octet de poid faible
- CLR C ;Always clear carry before first subtraction
- SUBB A,R7 ;octet de poid faible
- MOV R0,A ;Résultat du poid faible dans R0
- ;Step 2 of the process
- MOV A,R1 ;octet de poid fort
- SUBB A,R6 ;octet de poid fort
- MOV R1,A ;Résultat du poid fort dans R1
-
- RET
- TEMPO_VAR: ;Permet de calculer la valeur pour précharger le timer0
- ;et envoyer l'impulsion demandée au servo
- MOV R3,#07h ;bouclé 7x
- ;Load the first value into R6 and R7
- MOV R6,#0FEh
- MOV R7,#033h
- RESUB:
- ;Step 1 of the process
- MOV A,R7 ;Move the low-byte into the accumulator
- CLR C ;Always clear carry before first subtraction
- SUBB A,R5 ;Subtract the second low-byte from the accumulator
- MOV R7,A ;Move the answer to the low-byte of the result
- ;Step 2 of the process
- MOV A,R6 ;Move the high-byte into the accumulator
- SUBB A,R4 ;Subtract the second high-byte from the accumulator
- MOV R6,A ;Move the answer to the low-byte of the result
- DJNZ R3,RESUB
- ;Return - answer now resides in R6, and R7.
- RET
- end
|
J'edite au fur et à mesure du nettoyage du programme Message édité par latif18 le 25-05-2006 à 16:28:23
|