FORUM Syndrome-OC - Jacky-PC


  Electronique


  Montage


  µControleur 8051 : Servo-moteur et RS232 .. Problème

 




Il y a 24 utilisateurs connus et inconnus. Pour voir la liste des connectés connus, cliquez ici

 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

µControleur 8051 : Servo-moteur et RS232 .. Problème

n°71625
latif18
Posté le 24-05-2006 à 21:08:12  profilanswer
 

Bonjour, j'ai quelques soucis pour programmer un µcontroleur de type 8051 (at89s8252)
 
Je dois pouvoir commander 5 servos-moteurs pour commander un bras de robot.
 
Les données arrivent par le port série, je sais envoyer un octet à la fois via la routine PORTINC pour delphi (sendbyte(x))
 
A la base, je voulais envoyer un octet pour choisir le servo-moteur (1,2,3,4 ou 5) puis un second octet pour envoyer la position (0 à 255)
 
En delphi, le programme envoie bien l'octet pour choisir le servo puis l'octet pour donner la position.
 
C'est plutôt du coté µcontroleur que j'ai des probs. La commande des servos (PWM) fonctionne correctement. Mais le fait de recevoir les données et commander les servos en même temps est assez compliqué.  :sweat:  
 
Je commande les servos l'un à la suite de l'autre :
 
Interruption timer 20Ms
Impulsion de 1ms à 2ms pour le 1er servo
Impulsion de 1ms à 2ms pour le 2eme servo
Impulsion de 1ms à 2ms pour le 3emeservo
Impulsion de 1ms à 2ms pour le 4eme servo
Impulsion de 1ms à 2ms pour le 5eme servo
Fin du timer
 
Puis, j'ai un peu de temps pour envoyer les données (à 28800bits/s, je pense que c'est assez rapide)
 
Pour le reste, je peux mettre le code que j'ai fait .. (c'est pas très documenté mais j'pense pas que ça soit compliqué pour un qui s'y connait)
 
Donc, j'aimerais juste savoir quelle méthode est la meilleur pour pouvoir faire tout ça :)
 
Merci
 

Code :
  1. $MOD51
  2. $TITLE(essai)
  3. $PAGEWIDTH(132)
  4. $DEBUG
  5. $OBJECT
  6. $NOPAGING
  7.        
  8. ; *************************************************************************
  9. ; *         *
  10. ; *        PROGRAMME ASSEMBLEUR POUR LA FAMILLE MCS-51  *
  11. ; *         *
  12. ; *************************************************************************
  13. ; *         *
  14. ; * Titre:        *
  15. ; * Microcontrôleur:       *
  16. ; * Auteur:        *
  17. ; * Objet:        *
  18. ; * Date:        *
  19. ; * Version:       *
  20. ; *         *
  21. ; *************************************************************************
  22. org 0000h ;vecteur reset
  23. ljmp 0100h ;saut au delà des vecteurs d'interruption
  24. ; ***************************************
  25. ; *        Interruptions  *
  26. ; ***************************************
  27. org 0003h ;interruption externe 0
  28. reti
  29. org 000Bh ;interruption Timer0
  30. LJMP TIMER0
  31. reti
  32. org 0013h ;interruption externe 1
  33. reti
  34. org 001Bh ;interruption Timer1
  35. reti
  36. org 0023h ;interruption interface sérielle
  37. LJMP INTSER
  38. reti
  39. org 0100h ;début du programme
  40. ; ***************************************
  41. ; *  Initialisation des SFR's *
  42. ; ***************************************
  43. MOV TL0,#00h
  44. MOV TH0,#0C5h
  45. MOV TH1,#0FDh
  46. MOV P2,#00h
  47. MOV P1,#00h
  48. MOV IE,#097h
  49. MOV SCON,#050h
  50. MOV TMOD,#021h
  51. MOV IP,#00h
  52. MOV TCON,#05Fh
  53. MOV PCON,#080h
  54. ; ***************************************
  55. ; *     Programme principal  *
  56. ; ***************************************
  57. SETB P3.1
  58. CLR P3.0
  59. BOUCLE:
  60. JMP BOUCLE
  61. ; ***************************************
  62. ; *       Sous programmes  *
  63. ; ***************************************
  64. TIMER0:
  65. MOV TH0,#0C5h
  66. CLR TF0
  67. SETB P1.0
  68. CALL TEMPO5
  69. MOV A,R0
  70. CALL TEMPOVAR
  71. CLR P1.0
  72. SETB P1.1
  73. CALL TEMPO5
  74. MOV A,R1
  75. CALL TEMPOVAR
  76. CLR P1.1
  77. SETB P1.2
  78. CALL TEMPO5
  79. MOV A,R2
  80. CALL TEMPOVAR
  81. CLR P1.2
  82. SETB P1.3
  83. CALL TEMPO5
  84. MOV A,R3
  85. CALL TEMPOVAR
  86. CLR P1.3
  87. SETB P1.4
  88. CALL TEMPO5
  89. MOV A,R4
  90. CALL TEMPOVAR
  91. CLR P1.4
  92. RETI
  93. INTSER:
  94. CLR RI
  95. MOV A,SBUF
  96. SERVO1:
  97. CJNE A,#01h,SERVO2
  98. CALL VALEUR
  99. MOV R0,A
  100. JMP FIN
  101. SERVO2:
  102. CJNE A,#02h,SERVO3
  103. CALL VALEUR
  104. MOV R1,A
  105. JMP FIN
  106. SERVO3:
  107. CJNE A,#03h,SERVO4
  108. CALL VALEUR
  109. MOV R2,A
  110. JMP FIN
  111. SERVO4:
  112. CJNE A,#04h,SERVO5
  113. CALL VALEUR
  114. MOV R3,A
  115. JMP FIN
  116. SERVO5:
  117. CJNE A,#05h,FIN
  118. CALL VALEUR
  119. MOV R4,A
  120. JMP FIN
  121. FIN
  122. CLR RI
  123. CLR TI
  124. RETI
  125. VALEUR:
  126. JNB RI,$
  127. MOV A,SBUF
  128. RET
  129. TEMPO5:    ;TEMPO5
  130. MOV R5,#0E6h
  131. BOUCLE2:
  132. DJNZ R5,BOUCLE2
  133. RET
  134. TEMPOVAR:   ;TEMPOVAR
  135. MOV R6,A
  136. BOUCLE3:
  137. NOP
  138. NOP
  139. NOP
  140. NOP
  141. NOP
  142. NOP
  143. DJNZ R6,BOUCLE3
  144. RET
  145. end


Message édité par latif18 le 24-05-2006 à 21:12:23
mood
Google
Posté le 24-05-2006 à 21:08:12  profilanswer
 

n°71631
Vince 007 ​-
C'est mignon une souris !
Posté le 25-05-2006 à 08:00:32  profilanswer
 

Franchement c'est tout simple à faire !
 
Il faut séparer les deux taches et la tache de fond (programme principal), la réception des infos et la commande des moteurs.
 
-> La réception des infos par RS:
- Réception du numéro de servo à piloter --> Sauvegarde en RAM (variable N_SERVO)
- Réception de la position --> Sauvegarde en RAM (variable POSITION_SERVO)
 
-> Le pilotage des moteurs
- A chaque IT timer il suffit de rafraichir la position des moteurs
- Lecture de la position en RAM(variable POSITION_SERVO1)
- Envoi au servo 1
- Lecture de la position en RAM(variable POSITION_SERVO2)
- Envoi au servo 2
- Lecture de la position en RAM(variable POSITION_SERVO3)
- Envoi au servo 3
- Lecture de la position en RAM(variable POSITION_SERVO4)
- Envoi au servo 4
- Lecture de la position en RAM(variable POSITION_SERVO5)
- Envoi au servo 5
 
Et enfin le programme principal:
- Déclaration des 5 variables de position (POSITION_SERVOx)
- Déclaration de la variable N_SERVO et POSITION_SERVO
- Début
- Lecture de N_SERVO
- Suivant la valeur de N_SERVO, affecter la bonne variable POSITION_SERVOx avec la variable POSITION_SERVO  
- retour au début
 
Voilà, c'est pas compliqué. Tu est sûr que la position des servos sont rafraichis à chaque IT timer, la boucle principal se charge de modifier la position d'un servo en fonction des données reçue sur la RS. Ton micro aura largement le temps de traiter les données reçues avant qu'un second octet arrive.


Message édité par Vince 007 - le 25-05-2006 à 08:02:01

---------------
Balade moto dans la région toulousaine.
Suivre la construction d'une maison
n°71638
latif18
Posté le 25-05-2006 à 11:54:30  profilanswer
 

Pour le pilotage des servos dans l'interruption timer, ce n'est pas déconseillé d'y rester si longtemps ?
 
Pour 5 servos, il me faut jusqu'à 12,5 mS sur les 20 mS du timer (en comptant 2,5 mS par servo)
 
 
Il faut que je sache envoyer les octets quand je sortirais du timer .. Mais comment le savoir ?
 
Pour les variables, il faut que je regarde ça, je me rappelle plus comment on fait, je vais chercher ça.
 
Je vais réécrir le programme comme je l'ai compris et je le montrerais pour voir si c'est bien ça ..
 
Merci beaucoup !
 
EDIT : pour les variables, j'ai retrouvé comment faire
 
EDIT 2 : Pour faciliter la reconnaissance d'un octet pour le numéro du servo et la position d'un servo, je ne vais envoyer que de 1à5 pour le numéro du servo et de 6à255 pour la position du servo. (dans un premier temps)


Message édité par latif18 le 25-05-2006 à 12:02:10
n°71640
latif18
Posté le 25-05-2006 à 12:44:14  profilanswer
 

Partie Réception, je vais voir comment bien optimiser la gestion des servos ...  :whistle:  
 

Code :
  1. $MOD51
  2. $TITLE(essai)
  3. $PAGEWIDTH(132)
  4. $DEBUG
  5. $OBJECT
  6. $NOPAGING
  7. ; *************************************************************************
  8. ; *         *
  9. ; *        PROGRAMME ASSEMBLEUR POUR LA FAMILLE MCS-51  *
  10. ; *         *
  11. ; *************************************************************************
  12. ; *         *
  13. ; * Titre:        *
  14. ; * Microcontrôleur:       *
  15. ; * Auteur:        *
  16. ; * Objet:        *
  17. ; * Date:        *
  18. ; * Version:       *
  19. ; *         *
  20. ; *************************************************************************
  21. org 0000h ;vecteur reset
  22. ljmp 0100h ;saut au delà des vecteurs d'interruption
  23. ; ***************************************
  24. ; *        Interruptions  *
  25. ; ***************************************
  26. org 0003h ;interruption externe 0
  27. reti
  28. org 000Bh ;interruption Timer0
  29. reti
  30. org 0013h ;interruption externe 1
  31. reti
  32. org 001Bh ;interruption Timer1
  33. reti
  34. org 0023h ;interruption interface sérielle
  35. LJMP INTSER
  36. reti
  37. org 0100h ;début du programme
  38. ; ***************************************
  39. ; *  Initialisation des SFR's *
  40. ; ***************************************
  41. MOV IE,#092h
  42. MOV SCON,#050h
  43. MOV TMOD,#021h
  44. MOV IP,#010h    ;priorité réception série
  45. MOV TCON,#040h
  46. MOV PCON,#080h
  47. ; ***************************************
  48. ; *    Initialisation des variables *
  49. ; ***************************************
  50. ;  Variables 1 bit
  51. ;  variables 1 octet
  52. N_SERVO DATA 10h
  53. POSITION_SERVO DATA 11h
  54. POSITION_SERVO1 DATA 12h
  55. POSITION_SERVO2 DATA 13h
  56. POSITION_SERVO3 DATA 14h
  57. POSITION_SERVO4 DATA 15h
  58. POSITION_SERVO5 DATA 16h
  59. ; ***************************************
  60. ; *     Programme principal  *
  61. ; ***************************************
  62. MOV TH1,#0FEh     ;chargement compteur pour 28800 baud
  63. BOUCLE:
  64. MOV A,N_SERVO
  65. SERVO1:
  66. CJNE A,#01h,SERVO2
  67. MOV A,POSITION_SERVO
  68. MOV POSITION_SERVO1,A
  69. JMP FIN
  70. SERVO2:
  71. CJNE A,#02h,SERVO3
  72. MOV A,POSITION_SERVO
  73. MOV POSITION_SERVO2,A
  74. JMP FIN
  75. SERVO3:
  76. CJNE A,#03h,SERVO4
  77. MOV A,POSITION_SERVO
  78. MOV POSITION_SERVO3,A
  79. JMP FIN
  80. SERVO4:
  81. CJNE A,#04h,SERVO5
  82. MOV A,POSITION_SERVO
  83. MOV POSITION_SERVO4,A
  84. JMP FIN
  85. SERVO5:
  86. CJNE A,#05h,FIN
  87. MOV A,POSITION_SERVO
  88. MOV POSITION_SERVO5,A
  89. JMP FIN
  90. FIN:
  91. JMP BOUCLE
  92. ; ***************************************
  93. ; *       Sous programmes  *
  94. ; ***************************************
  95. INTSER:
  96. MOV A,SBUF
  97. N_SERVO1:
  98. CJNE A,#01h,N_SERVO2
  99. MOV N_SERVO,A
  100. JMP FINI
  101. N_SERVO2:
  102. CJNE A,#02h,N_SERVO3
  103. MOV N_SERVO,A
  104. JMP FINI
  105. N_SERVO3:
  106. CJNE A,#03h,N_SERVO4
  107. MOV N_SERVO,A
  108. JMP FINI
  109. N_SERVO4:
  110. CJNE A,#04h,N_SERVO5
  111. MOV N_SERVO,A
  112. JMP FINI
  113. N_SERVO5:
  114. CJNE A,#05h,POSITION_SERV
  115. MOV N_SERVO,A
  116. JMP FINI
  117. POSITION_SERV:
  118. MOV POSITION_SERVO,A
  119. FINI:
  120. CLR RI
  121. RETI
  122. end


Message édité par latif18 le 25-05-2006 à 12:45:20
n°71643
latif18
Posté le 25-05-2006 à 16:11:05  profilanswer
 

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 :
  1. $MOD51
  2. $TITLE(essai)
  3. $PAGEWIDTH(132)
  4. $DEBUG
  5. $OBJECT
  6. $NOPAGING
  7. ; *************************************************************************
  8. ; *         *
  9. ; *        PROGRAMME ASSEMBLEUR POUR LA FAMILLE MCS-51  *
  10. ; *         *
  11. ; *************************************************************************
  12. ; *         *
  13. ; * Titre: Commande servo-moteur par port RS232   *
  14. ; * Microcontrôleur: at89s8252     *
  15. ; * Auteur: David       *
  16. ; * Objet:        *
  17. ; * Date:        *
  18. ; * Version:       *
  19. ; *         *
  20. ; *************************************************************************
  21. org 0000h ;vecteur reset
  22. ljmp 0100h ;saut au delà des vecteurs d'interruption
  23. ; ***************************************
  24. ; *        Interruptions  *
  25. ; ***************************************
  26. org 000Bh ;interruption Timer0
  27. LJMP INT_TIMER0
  28. reti
  29. org 0023h ;interruption interface sérielle
  30. LJMP INT_SER
  31. reti
  32. org 0100h ;début du programme
  33. ; ***************************************
  34. ; *  Initialisation des SFR's *
  35. ; ***************************************
  36. MOV IE,#092h    ;Active les interruptions sérielle et timer0
  37. MOV SCON,#050h    ;active la réception
  38. MOV TMOD,#021h    ;mode 16 bits pour timer0 (8bits à préchargement auto pour timer0)
  39. MOV IP,#010h    ;priorité réception série
  40. MOV TCON,#050h    ;Timer 0 et 1 en RUN
  41. MOV PCON,#080h    ;Double le data rate (28800baud)
  42. ; ***************************************
  43. ; *    Initialisation des variables *
  44. ; ***************************************
  45. ;  Variables 1 bit
  46. ;  variables 1 octet
  47. N_SERVO DATA 10h
  48. POSITION_SERVO DATA 11h
  49. POSITION_SERVO1 DATA 12h
  50. POSITION_SERVO2 DATA 13h
  51. POSITION_SERVO3 DATA 14h
  52. POSITION_SERVO4 DATA 15h
  53. POSITION_SERVO5 DATA 16h
  54. ; ***************************************
  55. ; *     Programme principal  *
  56. ; ***************************************
  57. MOV TH1,#0FEh     ;chargement compteur pour 28800 baud
  58. MOV R1,#00h    ;Mise à zéro de quelques registres et des sorties
  59. MOV P2,#00h
  60. MOV P1,#00h
  61. SETB P3.1    ;Sortie TX et RX
  62. CLR P3.0
  63. MOV R0,#0FFh    ;47FF qui correspond à 18431 cycles ==> 20 mS
  64. MOV R1,#047h
  65. BOUCLE:     ; Programme qui remplira les cases mémoires
  66.      ; avec la position de chaque servo
  67. MOV A,N_SERVO
  68. SERVO1:
  69. CJNE A,#01h,SERVO2
  70. MOV A,POSITION_SERVO
  71. MOV POSITION_SERVO1,A
  72. JMP FIN
  73. SERVO2:
  74. CJNE A,#02h,SERVO3
  75. MOV A,POSITION_SERVO
  76. MOV POSITION_SERVO2,A
  77. JMP FIN
  78. SERVO3:
  79. CJNE A,#03h,SERVO4
  80. MOV A,POSITION_SERVO
  81. MOV POSITION_SERVO3,A
  82. JMP FIN
  83. SERVO4:
  84. CJNE A,#04h,SERVO5
  85. MOV A,POSITION_SERVO
  86. MOV POSITION_SERVO4,A
  87. JMP FIN
  88. SERVO5:
  89. CJNE A,#05h,FIN
  90. MOV A,POSITION_SERVO
  91. MOV POSITION_SERVO5,A
  92. JMP FIN
  93. FIN:
  94. JMP BOUCLE
  95. ; ***************************************
  96. ; *       Sous programmes  *
  97. ; ***************************************
  98. INT_SER:    ;Réception Série, test de 1 à 5 pour savoir si l'octet
  99. MOV A,SBUF    ;est un numéro de servo ou une position
  100.      ;Fonctionne un peu à pouf :/
  101. N_SERVO1:
  102. CJNE A,#01h,N_SERVO2
  103. MOV N_SERVO,A
  104. JMP FINI
  105. N_SERVO2:
  106. CJNE A,#02h,N_SERVO3
  107. MOV N_SERVO,A
  108. JMP FINI
  109. N_SERVO3:
  110. CJNE A,#03h,N_SERVO4
  111. MOV N_SERVO,A
  112. JMP FINI
  113. N_SERVO4:
  114. CJNE A,#04h,N_SERVO5
  115. MOV N_SERVO,A
  116. JMP FINI
  117. N_SERVO5:
  118. CJNE A,#05h,POSITION_SERV
  119. MOV N_SERVO,A
  120. JMP FINI
  121. POSITION_SERV:
  122. MOV POSITION_SERVO,A
  123. FINI:
  124. CLR RI
  125. RETI
  126. INT_TIMER0:    ;Interruption Timer qui va allumer/eteindre les sorties
  127.      ;Le timer est préchargé à chaque fois avec les valeurs
  128.      ;pour la position des servos
  129. INC R2     ;R2 permettra de suivre un ordre à chaque interruption
  130. ETAPE01:
  131. CJNE R2,#01h,ETAPE02
  132. SETB P1.0    ;Allumage sortie p1.0, début de l'impulsion Servo1
  133. MOV A,POSITION_SERVO1   ;On reprend la position du servo1 qui se trouve en mémoire
  134.    MOV R5,A    ; 
  135.    LCALL TEMPO_VAR    ;appel de la sous-routine de calcul de la durée de l'impulsion
  136. MOV A,R6    ;Préchargement du compteur avec ce calcul
  137. MOV TH0,A
  138. MOV A,R7
  139. MOV TL0,A
  140. LCALL CYCLE_UTILISE   ;Calcul des 20 mS (on additionne les 5 impulsions,
  141. LCALL TEMPO_RESTANT   ;on soustrait 20 mS de ce total, ce qui nous donnera le temps
  142.      ;restant pour avoir un cycle de 20 mS
  143. JMP FINII    ;On sort de l'interruption
  144. ETAPE02:
  145. CJNE R2,#02h,ETAPE03
  146. CLR P1.0
  147. SETB P1.1
  148. MOV A,POSITION_SERVO2
  149.    MOV R5,A  ; 
  150.    LCALL TEMPO_VAR  ;appel de la sous-routine de calcul de l'impulsion
  151. MOV A,R6
  152. MOV TH0,A
  153. MOV A,R7
  154. MOV TL0,A
  155. LCALL CYCLE_UTILISE
  156. LCALL TEMPO_RESTANT
  157. JMP FINII
  158. ETAPE03:
  159. CJNE R2,#03h,ETAPE04
  160. CLR P1.1
  161. SETB P1.2
  162. MOV A,POSITION_SERVO3
  163.    MOV R5,A  ;
  164.    LCALL TEMPO_VAR  ;appel de la sous-routine de calcul de l'impulsion
  165. MOV A,R6
  166. MOV TH0,A
  167. MOV A,R7
  168. MOV TL0,A
  169. LCALL CYCLE_UTILISE
  170. LCALL TEMPO_RESTANT
  171. JMP FINII
  172. ETAPE04:
  173. CJNE R2,#04h,ETAPE05
  174. CLR P1.2
  175. SETB P1.3
  176. MOV A,POSITION_SERVO4
  177.    MOV R5,A  ; 
  178.    LCALL TEMPO_VAR  ;appel de la sous-routine de calcul de l'impulsion
  179. MOV A,R6
  180. MOV TH0,A
  181. MOV A,R7
  182. MOV TL0,A
  183. LCALL CYCLE_UTILISE
  184. LCALL TEMPO_RESTANT
  185. JMP FINII
  186. ETAPE05:
  187. CJNE R2,#05h,ETAPE06
  188. CLR P1.3
  189. SETB P1.4
  190. MOV A,POSITION_SERVO5
  191.    MOV R5,A  ; 
  192.    LCALL TEMPO_VAR  ;appel de la sous-routine de calcul de l'impulsion
  193. MOV A,R6
  194. MOV TH0,A
  195. MOV A,R7
  196. MOV TL0,A
  197. LCALL CYCLE_UTILISE
  198. LCALL TEMPO_RESTANT
  199. JMP FINII
  200. ETAPE06:
  201. CJNE R2,#06h,FINII
  202. CLR P1.4
  203. MOV R2,#00h
  204. MOV A,R0
  205. MOV R7,A
  206. MOV A,R1
  207. MOV R6,A
  208. MOV R0,#0FFh
  209. MOV R1,#0FFh
  210. LCALL TEMPO_RESTANT
  211. MOV A,R0
  212. MOV TL0,A
  213. MOV A,R1
  214. MOV TH0,A
  215. MOV R0,#0FFh
  216. MOV R1,#047h
  217. FINII:
  218. RETI
  219. CYCLE_UTILISE:
  220.  ;Step 1 of the process
  221.  MOV A,#0FFh   ;octet de poid faible
  222.  CLR C      ;Always clear carry before first subtraction
  223.  SUBB A,R7  ;octet de poid faible
  224.    MOV R7,A   ;Résultat du poid faible dans R7
  225.  ;Step 2 of the process
  226.    MOV A,#0FFh   ;octet de poid fort
  227.  SUBB A,R6  ;octet de poid fort
  228.    MOV R6,A   ;Résultat du poid fort dans R6
  229.  
  230.  RET
  231. TEMPO_RESTANT:
  232.  ;Step 1 of the process
  233.  MOV A,R0  ;octet de poid faible
  234.  CLR C     ;Always clear carry before first subtraction
  235.  SUBB A,R7 ;octet de poid faible
  236.    MOV R0,A  ;Résultat du poid faible dans R0
  237.  ;Step 2 of the process
  238.    MOV A,R1  ;octet de poid fort
  239.  SUBB A,R6 ;octet de poid fort
  240.    MOV R1,A  ;Résultat du poid fort dans R1
  241.  
  242.  RET
  243. TEMPO_VAR:   ;Permet de calculer la valeur pour précharger le timer0
  244.     ;et envoyer l'impulsion demandée au servo
  245. MOV R3,#07h   ;bouclé 7x
  246.     ;Load the first value into R6 and R7
  247.    MOV R6,#0FEh
  248.    MOV R7,#033h
  249. RESUB:
  250.    ;Step 1 of the process
  251.    MOV A,R7  ;Move the low-byte into the accumulator
  252.    CLR C     ;Always clear carry before first subtraction
  253.    SUBB A,R5 ;Subtract the second low-byte from the accumulator
  254.    MOV R7,A  ;Move the answer to the low-byte of the result
  255.    ;Step 2 of the process
  256.    MOV A,R6  ;Move the high-byte into the accumulator
  257.    SUBB A,R4 ;Subtract the second high-byte from the accumulator
  258.    MOV R6,A  ;Move the answer to the low-byte of the result
  259. DJNZ R3,RESUB
  260.    ;Return - answer now resides in R6, and R7.
  261.    RET
  262. end


 
J'edite au fur et à mesure du nettoyage du programme


Message édité par latif18 le 25-05-2006 à 16:28:23
n°71657
latif18
Posté le 26-05-2006 à 19:09:38  profilanswer
 

Personne qui a envie de se casser la tête ?  :whistle:  
 
(à part vince)

n°71661
Vince 007 ​-
C'est mignon une souris !
Posté le 27-05-2006 à 08:01:04  profilanswer
 

Ton problème est trés classique !
 
Tu utilise le registre A pour tout faire ! Hors si tu reçois un octet par la RS durant ton IT, tu perd la valeur du registre A car écrasée par l'IT timer.
 
La solution la plus propre est soit d'utiliser un autre registre (B ?) , soit de sauvegarder le registre A dans la pile programme à l'entrée dans l'IT timer et de le restaurer à la sortie de l'IT timer.
 
En assembleur Motorola, les instructions PUSHA et PULA permettent de sauvegarder et de rester en pile programme. en 8151 j'en sais rien mais ça existe c'est sur.
 
Quand ça marchera complétement, pour rendre ton code plus propre, dans l'IT timer, tu ne fait que lever un flag (1 dans une variable en RAM), ensuite dans le programme principal, si le flag vaut 1, alors tu envoi les impulsions aux servos puis tu rabaisse le flag (mise à 0), sinon tu ne fait rien et tu continue ta boucle principal.
 
Comme ça, dans l'IT tu ne fait rien qui prend du temps et toute les taches sont centralisées dans le programme principal.

Message cité 1 fois
Message édité par Vince 007 - le 27-05-2006 à 08:04:14

---------------
Balade moto dans la région toulousaine.
Suivre la construction d'une maison
n°71663
latif18
Posté le 27-05-2006 à 12:45:35  profilanswer
 

Vince 007 - a écrit :

Ton problème est trés classique !
 
Tu utilise le registre A pour tout faire ! Hors si tu reçois un octet par la RS durant ton IT, tu perd la valeur du registre A car écrasée par l'IT timer.
 
La solution la plus propre est soit d'utiliser un autre registre (B ?) , soit de sauvegarder le registre A dans la pile programme à l'entrée dans l'IT timer et de le restaurer à la sortie de l'IT timer.
 
En assembleur Motorola, les instructions PUSHA et PULA permettent de sauvegarder et de rester en pile programme. en 8151 j'en sais rien mais ça existe c'est sur.
 
Quand ça marchera complétement, pour rendre ton code plus propre, dans l'IT timer, tu ne fait que lever un flag (1 dans une variable en RAM), ensuite dans le programme principal, si le flag vaut 1, alors tu envoi les impulsions aux servos puis tu rabaisse le flag (mise à 0), sinon tu ne fait rien et tu continue ta boucle principal.
 
Comme ça, dans l'IT tu ne fait rien qui prend du temps et toute les taches sont centralisées dans le programme principal.


 
PUSH A et POP A
 
Oui, je vais essayer.
 
C'est vrai que je ne fais jamais attention à mon A que j'utilise partout.
 
Et je vais essayer de tout centraliser dans le programme principal.
 
Merci  
 

n°71664
latif18
Posté le 27-05-2006 à 13:04:06  profilanswer
 

PUSH A et POP A n'existe pas en fait.
 
On peut faire PUSH et POP seulement avec des variables en mémoire.
 
Le programme fonctionne très bien maintenant, il faut juste que je trouve 5 servos pour bien tout tester mais apparemment, ça ne déconne plus.
 
Je n'ai pas utilisé PUSH et POP, j'ai seulement sauvegardé A en rentrant dans l'interruption et restitué en y sortant (avec des variables)
 
Merci beaucoup, il n'y a plus qu'à nettoyer le programme maintenant !
 
PS : et à améliorer la longueur des impulsions qui sont un peu mal calculées  :whistle:


Message édité par latif18 le 27-05-2006 à 13:05:11
n°71666
bool@y
--
Posté le 27-05-2006 à 20:53:00  profilanswer
 

Pour l'histoire du push/pop, il faut mettre "PUSH ACC" et "POP ACC" :)
Et sauve le PSW aussi ( contient le bit de carry entre autres... )

mood
Google
Posté le 27-05-2006 à 20:53:00  profilanswer
 


Aller à :
Ajouter une réponse

  FORUM Syndrome-OC - Jacky-PC


  Electronique


  Montage


  µControleur 8051 : Servo-moteur et RS232 .. Problème

 

Hit Parade