Variateur (Contrôleur) pour moteur Brushless
avec un PIC16F628

Je décris ci-dessous une carte électronique qui me donne satisfaction, sachant que je ne suis plus vraiment débutant en électronique. Ce montage est alimenté par un accu Lithium Polymère. Ces Accus sont extraordinaires de capacité et de légèreté, mais sont réputés dangereux dans des mains peu expertes. Ils peuvent exploser ou prendre feu en cas de court-circuit ou de surcharge.

Donc je montre ici ce que je fais, mais je ne vous encourage pas à en faire autant, c'est vous qui voyez.

Si vous n'avez pas de solides connaissances en électronique et en programmation des microcontroleurs, je vous conseille d'acheter un variateur tout fait, on en trouve à 10 euros (2018) ! ou mieux : d'étudier l'électronique, c'est passionnant !!!!!

Quant-à moi:

  • Je ne vends rien. A la question "combien ça coûte ?" : Je réponds : Il suffit de voir le prix des composants chez les fournisseurs
  • (tels que "Selectronic" ou "Electronique Diffusion", ou autres (eBay)...
  • Je n'adapte jamais mes réalisations à des besoins personnels.
  • Si les réalisations que je publie ici évoluent parfois (trop) lentement, c'est parce que je fais plusieurs choses à la fois...

Montage évolutif puisque le PIC16F628 est un uP flash reprogrammable.


1 Le prototype:


Au début il y avait ça ! Le montage en cours de test sur plaque d'essai. A gauche, le micro-récepteur de radiocommande (poids 5g...) On distingue les six transistors MOSFET qui commutent les enroulements du moteur, ainsi que le microcontrôleur qui génère les tensions de commande suivant un timing très précis. Il va sans dire que la version définitive sera réalisée avec des composants CMS ( SMD en Anglais, composants miniatures de montage en surface).

2 LE MOTEUR

Le moteur est un REX 220 FLYWARE
  • type LRK (9 pôles et 12 aimants).
  • conçu pour être alimenté par 2 à 3 éléments LIPO (Lithium-polymère).
  • 1350 rpm/V.
  • 220 milli-ohm.
  • masse 31g.

3 -

Il peut faire tourner une hélice 9x5 à 10000 Tr/mn !

4 -

Les moteurs brushless (sans balais ni charbons) développent un couple important de par leur principe de fonctionnement: le champ tournant créé par les tensions triphasées appliquées aux enroulements doit faire PLUSIEURS TOURS pour que le rotor (cage extérieure portant les aimants) fasse un seul tour (voir plus bas). Cela fait l'effet d'une démultiplication (magnétique), sans réducteur mécanique d'aucune sorte, le résultat étant une vitesse de rotation plus faible et un couple plus important. ( La puissance étant égale au produit du couple par la vitesse angulaire, pour une puissance restituée donnée, la vitesse est inversement proportionnelle au couple et vice versa). Je vous explique cela en détail un peu plus bas...

5 LE SCHEMA

6 -

Remarques:

Rôle des résistances (R11,12,13) de 10k reliant la gate des MOSFETS côté (-) à GND: Les Ports du PIC sont placés en haute impédance lors du reset. Sans ces résistances, lors du reset, les MOSFETS coté (+) et (-) d'une même phase pourraient conduire simultanément provoquant un court circuit sur l'alimentation et leur destruction immédiate.

Rôle des résistances (R34,35,36) de 100 ohm: Le PIC ne supporte pas de débiter sur la charge capacitive que représente la gate des IRF7455 (3,5 nF + l'effet Miller, le double que pour les IRFZ44). En fait, sur charge capacitive, et sans ces résistances, le port concerné configuré en sortie se bloque à GND après une impulsion avortée à peine visible à l'oscillo.

7 LE FIRMWARE pour le PIC16F628

Tout d'abord voici l'organigramme (définissant la boucle principale seulement) La production et le découpage des signaux de sortie, ainsi que le décodage des signaux de la télécommande et l'interprétation des signaux BEMF se fait par tout un jeu d'interruptions matérielles et logicielles. (Voir le .asm)

Notes:

-T_PPM représente la durée des impulsions PPM (Phase pulse modulation) de la radiocaommande.
-Les notations (N1, N2 etc...) utilisées sur cet organigramme se retrouvent dans le listing en assembleur.

8 -

CODE SOURCE en langage ASM
  1. ;===============================================================================================
  2. ; VARIATEUR pour moteur BRUSHLESS a 3 fils : variat3_21.ASM
  3. ; pour PIC16F628 et Qx=20,000 Mhz
  4. ; par Silicium 628
  5. ;derniere mise a jour: 29/09/2005
  6. ;===============================================================================================
  7. ;REMERCIEMENTS
  8. ;Suite a la publication de ce soft sur mon site, certains internautes specialistes dans tel ou tel domaine
  9. ;m'ont contacte afin de m'aider a en ameliorer l'ecriture.
  10. ;Je tiens ainsi a remercier tout particulierement I.M.B. qui m'a donne (en anglais);beaucoup d'astuces
  11. ;afin de rendre mon code plus structure et plus lisible.
  12. ;===============================================================================================
  13.  
  14. ;DIRECTIVEES D'ASSEMBLAGE:
  15. stops=1
  16. stop_BEC=1
  17. frein_permis=1
  18. vif=1
  19. detecte_perio_z=0
  20. detecte_vts_lente=0
  21. integration_PPM=1
  22. ;NOTE: ces directives activent ou inhibent certaines fontions
  23.  
  24.  
  25. ;LISTE DES PRINCIPALES PROCEDURES: (Double-clic sur 1 mot pour le selectionner puis ctrl+F3 dans MPLAB, pratique...)
  26. ;TESTS
  27. ;MACROS
  28. ;mot16A macro ;charge AH et AL avec le mot code sur 16 bits transmis
  29. ;mot16B macro ;charge BH et BL avec le mot code sur 16 bits transmis
  30. ;Changements de banques
  31. ;R_EEPROM
  32. ;W_EEPROM
  33. ;CONSTANTES
  34. ;VARIABLES_EN_BANQUE0
  35. ;TRAITEMENT DES INTERRUPTIONS (Aiguillage vers routines)
  36. ;INITIALISATION DES PORTS
  37.  
  38. ;PROGRAMMATION DU REGISTRE OPTION (BANK1)
  39. ;PROG DU REGISTRE INTCON (BANK0)
  40. ;PROG DU REGISTRE T1CON (BANK0)
  41. ;PROG DU REGISTRE T2CON (BANK0)
  42. ;PROG DU REGISTRE PR2 (BANK1)
  43. ;PROG DU REGISTRE PIE1 (BANK1)
  44. ;PROG DU REGISTRE CCP1CON (BANK0)
  45.  
  46. ;Initialisation_des_variables
  47. ;BOUCLE_PRINCIPALE
  48. ;inttimer0 ;-> PERIODEMETRE sur le signal PPM du recepteur de radiocommande (detecte arret radio)
  49. ;inttimer1 ;-> genere les signaux de commande moteur
  50. ;inttimer2 ;-> decoupe le signal de sortie a (relativement, 10kHz) haute frequence au demarrage
  51. ;intB0 ;-> detecte les fronts du signal PPM du recepteur de radio-commande et MESURE le signal T_PPM
  52. ;intB4_7 ;-> detection signaux BEMF
  53.  
  54. ;pasMot1
  55. ;BLOQUE
  56. ;sortie
  57. ;demarre
  58.  
  59. ;ROUTINES MATH
  60. ;convhbin ;conversion sexadecimale -> binaire ;entree: AA, BB ;resultat: AH,AL = 60*AA+BB
  61. ;multi16 ;mutiplication 8 bits x 8 bits de w par AA (donnees sur 1 octet) ;resultat (sur 2 octets) dans AH,AL
  62. ;multi24 ;mutiplication 8 bits x 16 bits de w par AH,L (donnees sur 1 octet) ;resultat (sur 3 octets) dans A2,1,0
  63. ;divi2 ;division d'une valeur codee sur 16 bits (AH,AL) par 2
  64. ;Div24_8 ;division 24bits par 8 bits, resultat sur 24 bits
  65. ;add16A ;addition 16bits resultat dans A ;(AH,AL)+(BH,BL) -> (AH,AL)
  66. ;add16B ;addition 16bits resultat dans B ;(AH,AL)+(BH,BL) -> (BH,BL)
  67. ;cpl16x ;complement a deux de la variable codee sur 2 octets situes aux adresses w et w+1 permet les soustractions
  68. ;compar16p;comparaison de deux valeurs codees sur 16 bits (AH,AL a BH,BL) ;resultat dans STATUS carry et zero
  69. ;movxA ;mov la variable codee sur 2 octets situes aux adresses w et w+1 dans -> AH,AL
  70. ;movAx ;mov AH,AL dans -> la variable codee sur 2 octets situes aux adresses w et w+1
  71. ;movxB ;mov la variable codee sur 2 octets situes aux adresses w et w+1 dans -> BH,BL
  72. ;movBx ;mov BH,BL dans -> la variable codee sur 2 octets situes aux adresses w et w+1
  73.  
  74. ;cvBDU ;CONVERSION BINAIRE(1) (1 octet incomplet 0..99 et pas 0..255) --> BCD ;nombre a convertir dans AA
  75. ;cvBCU ;CONVERSION BINAIRE(2) (1 octet complet 0..255) --> BCD ;resultat dans BB (centaines) et dans AA (unites)
  76.  
  77. ;Delay_ms (voir code externe dans le fichier Delay.asm)
  78.  
  79. ;pasMot1
  80. ;vari_vit
  81. ;demarre
  82.  
  83. ;TABLEAUX
  84. ;
  85. ;
  86. ;------------------------------------------------------------------------------------------------
  87. ;remarque: suite aux modifications (=ameliorations!) certains commentaires peuvent se reveler faux !!!
  88. ;j'en suis desole. Je relis regulierement les commentaires et essaye de les tenir a jour.
  89. ;toutefois il m'arrive de trouver des enormites ! que je corrige...
  90. ;------------------------------------------------------------------------------------------------
  91.  
  92.  
  93.  
  94. ;===================================== PRINCIPE ==================================================
  95. ;REMARQUE PRELIMINAIRE:
  96. ;De par la constitution du moteur brusless utilise: (9 poles electro-magnetiques cables en 3 groupes de 3 et 12 aimants):
  97. ;Quand le champ tourne de 360degre durant le cycle electrique complet, le rotor ne tourne que de 360/6=60 degres.
  98. ;Il faut que le champ magnetique fasse 6 tours pour que le rotor en fasse un -> couple important
  99.  
  100. ;un tour (360degre ) de champ magnetique se decompose electroniquement en 6 phases.
  101. ;un tour moteur est effectue apres 6x6 = 36 phases electriques.
  102. ;chacune de ces phases electriques correspond a un pas dans le tableau Tab_ph
  103. ;le tableau Tab_ph comprend 6 lignes correspondant aux six types de phases,
  104. ;dont la totalite se deroule pendant 1/6 de tour moteur soit 60degre
  105. ;une ligne du tableau concerne donc un angle de 10degre du moteur.
  106.  
  107. ;le PIC commande 6 MOSFETS (2 par phase) montes en pont en H
  108. ;par 4 bits du PORTA (bit 0 a 3) et 2 bits du portB
  109. ;Il s'agit de construire un champs tournant avec un courant triphase
  110. ;voir tableau Tab_ph
  111.  
  112. ;Par l'interruption intPortB, les signaux issus d'un traitement analogique des tensions BEMF font avancer
  113. ;le cycle de commande des MOSFFETS d'un pas a chaque impulsion recue sur un des 3 pins (RB5, RB6 ou RB7)
  114.  
  115. ;la variation de vitesse se fait par variation du rapport cyclique de decoupage des signaux de sortie
  116.  
  117. ;===================================== SECURITE ==================================================
  118.  
  119. ;arret si plus de signal de reception
  120. ;arret si manche gaz + trim =0
  121. ;ne demarre pas a la mise sous tension, meme avec le manche des gaz a fond (a condition que la duree
  122. ;de coupure de l'alim soit suffisante pour que le PIC ait eu le temps de reseter, donc attention!)
  123. ;le seul demarrage possible se produit en montant le manche des gaz DEPUIS ZERO
  124. ;attention si l'emetteur de radiocommande est a l'arret, il faut s'attendre a des receptions de parasites
  125. ;provoquant des demarrages rates.
  126.  
  127. ;fonction BEC implantee depuis la version 19 - met le moteur au ralentit si tension accu faible. sert a deux choses
  128. ;- ne pas decharger les accus LiPo sous le minimum autorise (3V par element, reglage par diode zener et resistances
  129. ; sur le circuit)
  130. ;- toujours garder sufisamment de tension pour alimenter le recepteur de radiocommande
  131. ;ATTENTION: le BEC est ici ajuste pour 2 elements LiPo en serie, pas pour 3.
  132. ;le circuit constitue autour du transistor Q10 est perfectible
  133. ;la partie du soft qui gere le BEC, et qui stope completement (ou pas) le moteur et egalement revisable
  134. ;(chercher BEC dans le listing)
  135.  
  136.  
  137. ;============================== REMARQUES GENERALES ==============================================
  138. ;RAZ signifie Remise a Zero
  139. ;PPM : type de modulation utilisee en radiocommande analogique par largeur d'impulsion (Phase Pulse Modulation)
  140. ;un train de 'n' impulsions, 'n'=nombre de voies module la HF, 1 impulsion par voie
  141. ;les impulsions durent entre 1,1ms et 2,2ms suivant la position du manche de la telecommande
  142. ;periode de 'relaxation' entre deux trains = 20ms environ
  143. ;la separation des impultions destinees a chaque voies se fait dans le recepteur radio
  144.  
  145. ;la notation ':=' dans les commentaires (affectation) me vient de la programmation en Pascal.
  146. ;une lecture attentive de ce code fait apparaitre de curieuses sequences goto etiquette suivis immediatement
  147. ;par la destination. C'est voulu, par souci de lisibilite et de structuration du code
  148. ;ca evite surtout, lors d'ajout de bouts de code, D'OUBLIER d'ajouter le-dit goto
  149. ;D'autre part, j'aime bien que mes routines aient une porte de sortie unique
  150. ;plutot que de ballancer des 'return' un peu partout.
  151.  
  152. ;representation d'un nombre hexadecimal: commence par "0x" ex: 0x20
  153. ; B'00010000' represente une valeur binaire
  154. ;la notation periodeH,L (par exemple) designe ici le mot 16bits forme par les 2 octets periodeH et periodeL
  155. ;et represente donc une valeur numerique codee sur 16 bits
  156.  
  157. ;Utiliser une version recente de MPLAB afin que le PIC16F628 soit pris en compte (ma version= 7.10.00 )
  158. ;voir sur le site de Microchip(R): http://www.microchip.com
  159.  
  160. ;===============================================================================================================
  161.  
  162. list p=16f628A,r=dec ; list directive to define processor ; constantes systeme decimal
  163. #include <p16f628a.inc> ; processor specific variable definitions
  164. #include "Delay.inc"
  165.  
  166. __CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _HS_OSC & _MCLRE_ON & _LVP_OFF
  167.  
  168.  
  169. ; '__CONFIG' precise les parametres encodes dans le processeur au moment de
  170. ; la programmation du processeur. Les definitions sont dans le fichier include.
  171. ; Voici les valeurs et leurs definitions :
  172. ; _CP_ON Code protection ON : impossible de relire
  173. ; _CP_OFF Code protection OFF
  174.  
  175. ; _PWRTE_ON Timer reset sur power on en service
  176. ; _PWRTE_OFF Timer reset hors-service
  177.  
  178. ; _WDT_ON Watch-dog en service
  179. ; _WDT_OFF Watch-dog hors service
  180.  
  181. ; _LP_OSC Oscillateur quartz basse vitesse (32<F<200Khz)
  182. ; _XT_OSC Oscillateur quartz moyenne vitesse (200Khz<F<4Mhz)
  183. ; _HS_OSC Oscillateur quartz grande vitesse (4Mhz<F<20Mhz)
  184. ; _RC_OSC Oscillateur a reseau RC
  185.  
  186. ; Reset du PIC si tension <4V
  187. ; ------------------------------
  188. ; _BODEN_ON Reset tension en service Valide PWRTE_ON automatiquement
  189. ; _BODEN_OFF Reset tension hors service
  190.  
  191. ; Programmation sur circuit
  192. ; ------------------------------
  193. ; _LVP_ON RB4 permet la programmation serie du PIC
  194. ; _LVP_OFF RB4 en utilisation normale
  195.  
  196. ; "departRam equ 0x20"
  197.  
  198.  
  199. ;===============================================================================================================
  200. ; MACROS
  201. ;===============================================================================================================
  202. SWAPwf MACRO reg
  203. xorwf reg,f
  204. xorwf reg,w
  205. xorwf reg,f
  206. ENDM
  207.  
  208. mot16A macro mot16 ;charge AH et AL avec le mot code sur 16 bits transmis
  209. movlw low mot16
  210. movwf AL
  211. movlw high mot16
  212. movwf AH
  213. endm
  214.  
  215. mot16B macro mot16 ;charge BH et BL avec le mot code sur 16 bits transmis
  216. movlw low mot16
  217. movwf BL
  218. movlw high mot16
  219. movwf BH
  220. endm
  221.  
  222. LoadInt24 macro Destination,mot24b
  223.  
  224. banksel Destination
  225. movlw low mot24b ;bits 0..7 (8 bits)
  226. movwf Destination+0
  227. movlw high mot24b ;bits 8..15 (8 bits)
  228. movwf Destination+1
  229. movlw upper mot24b ;bits 16..21 (6 bits)
  230. movwf Destination+2
  231.  
  232. endm
  233.  
  234. ; lire eeprom (adresse et resultat en w)
  235. R_EEPROM macro
  236. clrwdt
  237. banksel EEADR ;(bank1)
  238. movwf EEADR ; Adresse to read
  239. bsf EECON1,RD ; ordre de lecture
  240. movf EEDATA,w ; W = EEDATA
  241. bcf STATUS,RP0 ; Bank 0
  242. endm
  243.  
  244. ;ecriture en EEPROM (adresse dans DDD (commun 4 banques), data dans w)
  245. W_EEPROM macro
  246. clrwdt
  247. LOCAL loop
  248. movwf EEDATA ; Data to write
  249. ; movlw adress1 ; adresse passee en parametre a la macro (moins souple que par registre)
  250. movf DDD,w ; adresse passee par registre DDD, commun aux 4 banques
  251. movwf EEADR
  252. bsf EECON1, WREN ; Enable Write
  253. bcf INTCON, GIE ; Disable INTs
  254. movlw 0x55
  255. movwf EECON2 ; Write 55
  256. movlw 0xAA
  257. movwf EECON2 ; Write AA
  258. bsf EECON1, WR ; lancer cycle d'ecriture
  259. bsf INTCON, GIE ; reautoriser INTs
  260.  
  261. loop clrwdt
  262. btfsc EECON1 , WR ; tester si ecriture terminee
  263. goto loop ; non, attendre
  264. bcf EECON1 , WREN ; verrouiller prochaine ecriture
  265. bcf STATUS , RP0 ; passer en banque0
  266. endm
  267.  
  268. ;===============================================================================================================
  269. ;VARIABLES_EN_BANQUE0
  270. ;le PIC16F628 possede 224 octets de RAM repartis en 3 emplacements (80+16, +80, +48 octets)
  271. ;ici premiere banque de 96 octets, debut a l'adresse 0x20
  272. ;verifier sur le listing absolu que la derniere adresse soit < 7Fh
  273.  
  274. GPR0 udata ;
  275.  
  276. AA res 1 ;registre de travail
  277. BB res 1 ;registre de travail
  278. CC res 1 ;registre de travail
  279. DD res 1 ;registre de travail
  280.  
  281. ;registres pour travailler avec des mots de 16 bits
  282. AH res 1 ;registre de travail poids fort
  283. AL res 1 ;registre de travail poids faible
  284. BH res 1 ;registre de travail poids fort
  285. BL res 1 ;registre de travail poids faible
  286. CH res 1 ;registre de travail poids fort
  287. CL res 1 ;registre de travail poids faible
  288.  
  289. ;registres pour travailler avec des mots de 24 bits
  290. A2 res 1 ;registre de travail poids fort
  291. A1 res 1 ;registre de travail poids intemediaire
  292. A0 res 1 ;registre de travail poids faible
  293.  
  294. B2 res 1 ;registre de travail poids fort
  295. B1 res 1 ;registre de travail poids intemediaire
  296. B0 res 1 ;registre de travail poids faible
  297.  
  298. count0 res 1 ;utilise dans la l'int Timer0
  299. count1 res 1 ;utilise dans la multiplication 8bits x 8bits
  300.  
  301. n_ph res 1 ;numero de la periode en cours (1 cycle = 6 periodes)
  302.  
  303. signal res 1 ;signal de sortie brut
  304.  
  305. T_PPM res 1 ;temps (duree) du signal PPM (voie des gaz en sortie du recepteur de radiocommande)
  306. memo1 res 1 ;memo dans la boucle principale
  307.  
  308. periodeH res 1 ;pour mesurer la periode (vitesse de rotation) et decouper le signal en fonction
  309. periodeL res 1
  310.  
  311. rapcycl res 1 ;pour le decoupage HF des signaux de sortie pendant le demarrage
  312.  
  313. Dividende res 3 ;pour la routine Div24_8
  314. Diviseur res 1 ;pour la routine Div24_8
  315. Aux res 2 ;pour la routine Div24_8
  316. Compteur1 res 1 ;pour la routine Div24_8
  317. #define Quotient Dividende
  318.  
  319.  
  320. mesflag1 res 1 ;8 flags perso divers
  321. ;b0: stop moteur par ordre emis par la radio-commande (trim + amnche gaz en bas...) ou pas de signal du tout
  322. ;b1; stop si accrochage HF de l'electronique
  323. ;b2: vitesse lente ou arret du moteur detecte
  324. ;b3: decoupage HF des signaux pendant le demarrage
  325. ;b4: phase du decoupage HF
  326. ;b5: quel front du signal PPM vient-on de detecter ? ( voir l'intB0 )
  327. ;b6: stop moteur permanent si tension faible ("BEC")
  328. ;b7: empeche le decoupage: moteur force a vitesse max lorsque manche + trim de la radio au max
  329.  
  330.  
  331. #define STOP_RADIO mesflag1,0
  332. #define STOP_ACCRO mesflag1,1
  333. #define VTS_LENTE mesflag1,2
  334. #define DECOUP_HF mesflag1,3
  335. #define PHASE_HF mesflag1,4
  336. #define EDGE_PPM mesflag1,5
  337. #define U_FAIBLE mesflag1,6
  338. #define A_FOND mesflag1,7
  339.  
  340. mesflag2 res 1 ;8 flags perso divers
  341. ;b0: decoupage enable (1 seul par pas moteur)
  342. ;b1: FREIN MOTEUR Enable
  343.  
  344. #define DECOU_En mesflag2,0
  345. #define FREIN_En mesflag2,1
  346.  
  347.  
  348. ;===============================================================================================================
  349. ; VARIABLES ZONE COMMUNE
  350. ; Zone de 16 bytes
  351. ; CBLOCK 0x70 ;Debut de la zone (0x70 a 0x7F)
  352.  
  353. udata_shr
  354. WW res 1 ;pour sauvegarder w pendant INT
  355. STUS_TMP res 1 ;pour sauvegarder STATUS pendant INT
  356. FSR_temp res 1 ;sauvegarde FSR (si indirect en interrupt)
  357. PLATH_tmp res 1
  358.  
  359. DDD res 1 ;registre d'adresses commun
  360.  
  361. ;===============================================================================================================
  362. STARTUP code
  363. ;===============================================================================================================
  364.  
  365. goto start
  366.  
  367.  
  368. ;===============================================================================================================
  369. ; TRAITEMENT DES INTERRUPTIONS (Aiguillage vers routines)
  370. ;===============================================================================================================
  371. ;RAPPEL Un seul vecteur d'interruption, d'adresse 004 est diponible
  372. ;Quelle que soit la cause de l'interruption, le PC est charge par 004
  373. ;Il faut ensuite tester les differents indicateurs pour savoir quel est la source de l'INT.
  374. ;voir le registre INTCON
  375.  
  376. ; ORG ISR_V ; Vecteur d'Interruption
  377.  
  378. PROG code
  379.  
  380. ISR movwf WW
  381. swapf STATUS,w
  382. movwf STUS_TMP
  383. movf FSR , w
  384. movwf FSR_temp
  385. movf PCLATH , w ;charger PCLATH
  386. movwf PLATH_tmp ;le sauver
  387. clrf PCLATH ;on est en page 0
  388. banksel INTCON ;passer en banque0
  389.  
  390. intTMR0 btfsc INTCON,5 ;TOIE teste si c'est bien le timer0 qui a declenche l'INT
  391. btfss INTCON,2 ;TOIF test FLAG timer0
  392. goto intRB47 ;non suite
  393. call inttimer0 ;oui, traiter interrupt timer0
  394. bcf INTCON,2 ;effacer flag interupt timer: reautorise l'INT Timer0
  395. goto restorREG
  396.  
  397. intRB47 btfsc INTCON,3 ;RBIE teste si c'est bien RB47 qui a declenche l'INT
  398. btfss INTCON,0 ;RBIF test FLAG INT exterieure bits 4 a 7 du port B
  399. goto intRB0 ;non suite
  400. call intB4_7 ;oui, traiter interrupt PORTB,4_7
  401. bcf INTCON,0 ;effacer flag interupt portB: reautorise interruption PORTB,4_7
  402. goto restorREG
  403.  
  404. intRB0 btfsc INTCON,4 ;INTE teste si c'est bien RB0 qui a declenche l'INT
  405. btfss INTCON,1 ;INTF test FLAG INT exterieure bit 0 du port B
  406. goto intTMR2 ;non suite
  407. call intB0 ;oui, traiter interrupt PORTB,0
  408. bcf INTCON,1 ;effacer flag interupt portB: reautorise interruption PORTB,0
  409. goto restorREG
  410.  
  411. intTMR2
  412. banksel PIE1 ;BANK1
  413. btfss PIE1,TMR2IE ;TMR2IE teste si c'est bien le timer 2 qui a declenche l'INT
  414. goto intTMR1
  415. banksel PIR1 ;BANK0
  416. btfss PIR1,TMR2IF ;TMR2IF test FLAG timer2
  417. goto intTMR1 ;non suite...
  418. call inttimer2 ;oui, traiter interrupt timer2
  419. bcf PIR1,TMR2IF ;reautorise l'INT par Timer2
  420. goto restorREG
  421.  
  422. intTMR1
  423. banksel PIR1 ;BANK0
  424. btfss PIR1,TMR1IF ;test FLAG timer1
  425. goto intCCP1 ;non test suivant
  426. call inttimer1 ;oui, traiter interrupt timer1
  427. bcf PIR1,TMR1IF ;reautorise l'INT par Timer1
  428. goto restorREG
  429.  
  430. intCCP1 btfss PIR1,CCP1IF ;test FLAG module de COMPARAISON TMR1H,L = CCPR1H,L ?
  431. goto restorREG ;non suite...
  432. call intCompar ;oui, traiter interrupt COMPARAISON
  433. bcf PIR1,CCP1IF ;reautorise l'INT COMPARAISON
  434. goto restorREG
  435.  
  436. ;intUSRTi btfss PIR1,RCIF ;test FLAG USART en reception
  437. ; goto intUSRTo ;non test suivant
  438. ; call int232in ;oui, traiter interrupt USART IN
  439. ; goto restorREG
  440. ;
  441. ;intUSRTo btfss PIR1,TXIF ;test FLAG USART en emission
  442. ; goto restorREG ;non suite
  443. ; call int232out ;oui, traiter interrupt USART OUT
  444. ; goto restorREG
  445.  
  446. restorREG movf PLATH_tmp, w ;recharger ancien PCLATH
  447. movwf PCLATH
  448. movf FSR_temp,w
  449. movwf FSR
  450. swapf STUS_TMP,w ;swap STATUS_TMP, resultat dans w
  451. movwf STATUS ;restaurer status
  452. swapf WW,f ;Inversion L et H de l'ancien W sans modifier Z
  453. swapf WW,w ;Re-inversion de L et H dans W
  454.  
  455. retfie ;remet GIE a 1 puis return
  456.  
  457. ;===============================================================================================================
  458. ; TABLEAUX DE DONNEES
  459. ;===============================================================================================================
  460.  
  461. Tab_Ph movlw high Tableau
  462. movwf PCLATH
  463. movlw low Tableau
  464. addwf n_ph,w
  465. btfsc STATUS,C
  466. incf PCLATH,f
  467. movwf PCL
  468.  
  469. ;tableau des valeurs des bits de commande des phases
  470.  
  471. Tableau retlw B'00000110' ;phase 0
  472. retlw B'00100100' ;phase 1
  473. retlw B'00100001' ;phase 2
  474. retlw B'00001001' ;phase 3
  475. retlw B'00011000' ;phase 4
  476. retlw B'00010010' ;phase 5
  477. retlw B'00000000'
  478. retlw B'00000000'
  479.  
  480. ;===============================================================================================================
  481. ; START START START START START START START START START START START
  482. ;===============================================================================================================
  483.  
  484. start nop
  485.  
  486. bcf STATUS,IRP ;pour l'adressage indirect
  487. ;IRP: Register Bank Select bit (used for indirect addressing)
  488. ;=0 -> Bank 0, 1 (00h - FFh)
  489. ;=1 -> Bank 2, 3 (100h - 1FFh)
  490.  
  491. banksel AA ;BANK0
  492.  
  493. ;===============================================================================================================
  494. ;ZONE de TESTS de procedures (simulation soft)
  495.  
  496.  
  497. ;===============================================================================================================
  498. ; INITIALISATION DES PORTS
  499. ;===============================================================================================================
  500.  
  501. bcf RCSTA,7 ;(bit SPEN) portB[1,2] en ports E/S ( pas en USART )
  502.  
  503. banksel CMCON ;BANK0
  504. movlw 0x07
  505. movwf CMCON ;PORT A en E/S numeriques (BANK0)
  506.  
  507. call BLOQUE ;positionne les bits du port A avant meme de les configurer en sortie
  508.  
  509. banksel TRISA
  510. movlw B'00000000' ;0=sortie 1=entree ATTENTION RA4 =drain ouvert
  511. movwf TRISA ;config du port A (TRISA en page 1)
  512.  
  513. movlw B'11101001'
  514. movwf TRISB ;config du port B
  515.  
  516. banksel AA
  517. ; bsf PORTB,4 ;POUR TEST: signal de RESET visible sur le PORTB,4
  518.  
  519. ;===============================================================================================================
  520. ;PROGRAMMATION DU REGISTRE OPTION (BANK1) - voir datasheet p:20 du datasheet PIC16F62X.pdf
  521.  
  522. ;bit 7: RBPU =0 -> R tirage a Vdd du port B
  523. ;bit 6: INTEDG=1 -> INT sur front montant ou descendant de RB0
  524. ; 1 = Interrupt on rising edge of RB0/INT pin
  525. ; 0 = Interrupt on falling edge of RB0/INT pin
  526.  
  527. ;bit 5: T0CS = 0 -> TMR0 Clock Source Select bit
  528. ; 1 = Transition on RA4/T0CKI pin (Fonctionnement en mode compteur)
  529. ; 0 = Internal instruction cycle clock (CLKOUT) (Fonctionnement en mode timer)
  530.  
  531. ;bit 4: RTE = 0 -> inc sur front montant
  532.  
  533. ;bit 3: PSA = 0 -> prediv affecte au timer0
  534. ;bits 2,1,0 : PS2,1,0
  535. ;Bit Value TMR0 Rate WDT Rate
  536. ;000 1 : 2 1 : 1
  537. ;001 1 : 4 1 : 2
  538. ;010 1 : 8 1 : 4
  539. ;011 1 : 16 1 : 8
  540. ;100 1 : 32 1 : 16
  541. ;101 1 : 64 1 : 32 ***** ICI 100b -> Timer0 = 1/64 *****
  542. ;110 1 : 128 1 : 64
  543. ;111 1 : 256 1 : 128
  544.  
  545. banksel OPTION_REG
  546. ; ndegre bits: '76543210'
  547. movlw B'01000101'
  548. movwf OPTION_REG
  549.  
  550. ;===============================================================================================================
  551. ;PROG DU REGISTRE INTCON (BANK0) - voir datasheet p:21
  552. ;bit 7 GIE =0 -> INT GLOBALE interdite. (voir + bas)
  553. ;bit 6 PEIE=1 -> INT PERIPHERIQUES autorisees. (timer1 en fait partie)
  554. ;bit 5 T0IE=1 -> INT par debordement Timer0 autorisees.
  555. ;bit 4 INTE=1 -> INT de RB0/INT autorisee (INTERRUPTIONS EXTERNES)
  556. ;bit 3 RBIE=1 -> INT du port RB4 a RB7 autorisee.
  557. ;bit 2 T0IF=x (flag mis a 1 par debordement du Timer0)
  558. ;bit 1 INTF=x (flag mis a 1 par une INT provoquee par la libne RB0/INT du port B)
  559. ;bit 0 RBIF=x (flag mis a 1 si changement d'etat des entrees RB4 a RB7 du port B. attention RB1 a RB3 -> pas d'INT)
  560.  
  561. banksel INTCON
  562. ; ndegre bits: '76543210'
  563. movlw B'01111000'
  564. movwf INTCON
  565.  
  566.  
  567. ;===============================================================================================================
  568. ;PROG DU REGISTRE T1CON (BANK0) (i zorepu lapele otremen !)
  569.  
  570. ;bit 7-6: Unimplemented: Read as '0'
  571.  
  572. ;bit 5-4: T1CKPS1:T1CKPS0: Timer1 Input Clock Prescale Select bits
  573. ;11 = 1/8 Prescale value
  574. ;10 = 1/4 Prescale value >> valeur choisie ici <<
  575. ;01 = 1/2 Prescale value
  576. ;00 = 1/1 Prescale value
  577.  
  578. ;bit 3: T1OSCEN: Timer1 Oscillator Enable Control bit
  579. ;1 = Oscillator is enabled
  580. ;0 = Oscillator is shut off
  581. ;Note: The oscillator inverter and feedback resistor are turned off to eliminate power drain
  582.  
  583. ;bit 2: T1SYNC: Timer1 External Clock Input Synchronization Control bit
  584. ;si -> TMR1CS = 1
  585. ;1 = Do not synchronize external clock input
  586. ;0 = Synchronize external clock input
  587. ;si -> TMR1CS = 0
  588. ;This bit is ignored. Timer1 uses the internal clock when TMR1CS = 0.
  589.  
  590. ;bit 1: TMR1CS: Timer1 Clock Source Select bit
  591. ;1 = External clock from pin RB6/T1OSO/T1CKI (on the rising edge)
  592. ;0 = Internal clock (FOSC/4)
  593.  
  594. ;bit 0: TMR1ON: Timer1 On bit
  595. ;1 = Enables Timer1
  596. ;0 = Stops Timer1
  597.  
  598. ; **** RECAPITULONS:*****
  599. ;bit 7 : Inutilise : lu comme 0
  600. ;bit 6 : Inutilise : lu comme 0
  601. ;bit 5 : T1CKPS1 : Timer 1 oscillator ClocK Prescale Select bit 1
  602. ;bit 4 ; T1CKPS0 : Timer 1 oscillator ClocK Prescale Select bit 0
  603. ;bit 3 : T1OSCEN : Timer 1 OSCillator ENable control bit (oscillateur interne)
  604. ;bit 2 : T1SYNC : Timer 1 external clock input SYNChronisation control bit
  605. ;bit 1 : TMR1CS : TiMeR 1 Clock Source select bit
  606. ;bit 0 : TMR1ON : TiMeR 1 ON bit
  607.  
  608. banksel T1CON
  609. ; ndegre bits: '76543210' ;prescale Timer1=1/4
  610. movlw B'00100001'
  611. movwf T1CON
  612.  
  613. ;===============================================================================================================
  614.  
  615. ;PROG DU REGISTRE T2CON (BANK0)
  616.  
  617. ;bit 7: Unimplemented: Read as '0'
  618. ;bit 6-3: TOUTPS3:TOUTPS0: Timer2 Output Postscale Select bits
  619. ;0000 = 1:1 Postscale
  620. ;0001 = 1:2 Postscale
  621. ;0010 = 1:3 Postscale
  622. ;0011 = 1:4 Postscale
  623. ;0100 = 1:5 Postscale etc... (valeur binaire +1)
  624. ;1111 = 1:16 Postscale
  625.  
  626. ;bit 2: TMR2ON: Timer2 On bit =1 : Timer2 is on
  627. ;bit 1-0: T2CKPS1:T2CKPS0: Timer2 Clock Prescale Select bits
  628. ;00 = Prescaler = 1
  629. ;01 = Prescaler = 4
  630. ;1x = Prescaler = 16 (valeur choisie ici)
  631.  
  632. banksel T2CON
  633. ; ndegre bits: '76543210'
  634. movlw B'00000110'
  635. movwf T2CON
  636.  
  637. ;===============================================================================================================
  638. ;PROG DU REGISTRE PR2 (BANK1)
  639. ;utilise par timer2
  640. banksel PR2
  641. movlw 16
  642. movwf PR2
  643.  
  644. ;===============================================================================================================
  645. ;PROG DU REGISTRE PIE1 (BANK1)
  646. ;bit 7 : PSPIE b7 : Toujours 0 sur PIC 16F876
  647. ;bit 6 : ADIE : masque int convertisseur A/D
  648. ;bit 5 : RCIE : masque int reception USART
  649. ;bit 4 : TXIE : masque int transmission USART
  650. ;bit 3 : SSPIE : masque int port serie synchrone
  651. ;bit 2 : CCP1IE: masque int CCP1 (module de comparaison TMR1H,L = CCPR1H,L ->INT)
  652. ;bit 1 : TMR2IE: masque int TMR2 = PR2
  653. ;bit 0 : TMR1IE: masque int debordement tmr1
  654.  
  655. banksel PIE1
  656. ; ndegre bits: '76543210'
  657. movlw B'00000111' ;enable: INT TIMER1 ; INT TIMER2 ; COMPARAISON ; disable le reste
  658. movwf PIE1
  659.  
  660. ;===============================================================================================================
  661. ;PROG DU REGISTRE CCP1CON (BANK0)
  662. ;je vous fais un petit copier coller du datasheet pour le plaisir...
  663.  
  664. ;bit 7-6: Unimplemented: Read as '0' -> dommage, ca aurait pu compliquer un peu !
  665. ;bit 5-4: CCP1X:CCP1Y: PWM Least Significant bits
  666. ;Capture Mode: Unused
  667. ;Compare Mode: Unused
  668. ;PWM Mode: These bits are the two LSbs of the PWM duty cycle. The eight MSbs are found in CCPRxL.
  669.  
  670. ;bit 3-0: CCP1M3:CCP1M0: CCPx Mode Select bits
  671. ;0000 = Capture/Compare/PWM off (resets CCP1 module)
  672. ;0100 = Capture mode, every falling edge
  673. ;0101 = Capture mode, every rising edge
  674. ;0110 = Capture mode, every 4th rising edge
  675. ;0111 = Capture mode, every 16th rising edge
  676. ;1000 = Compare mode, set output on match (CCP1IF bit is set)
  677. ;1001 = Compare mode, clear output on match (CCP1IF bit is set)
  678. ;1010 = Compare mode, generate software interrupt on match (CCP1IF bit is set, CCP1 pin is unaffected)
  679. ;1011 = Compare mode, trigger special event (CCP1IF bit is set; CCP1 resets TMR1
  680. ;11xx = PWM mode
  681.  
  682. banksel CCP1CON
  683. ; ndegre bits: '76543210'
  684. movlw B'00001010' ;bits 0-3 = 1010 -> mode COMPARE
  685. movwf CCP1CON
  686.  
  687. banksel AA ;BANK1
  688. movlw .200 ;duree du signal de RESET visible sur le PORTB,4
  689. call Delay_ms
  690. ; bcf PORTB,4 ;POUR TEST: fin du signal de RESET visible sur le PORTB,4
  691.  
  692.  
  693. ;===============================================================================================================
  694. ;Initialisation_des_variables
  695. N1 bcf INTCON, GIE ;->INT GLOBALE interdite
  696. movlw .20 ;voir inttimer2
  697. movwf rapcycl
  698.  
  699. banksel n_ph
  700. clrf n_ph
  701. clrf count0
  702.  
  703. movlw 200
  704. movwf TMR0
  705.  
  706. clrf TMR1L
  707. clrf TMR1H
  708.  
  709. movlw 128
  710. movwf TMR2
  711.  
  712. movlw 100
  713. clrf CCPR1H
  714. movlw 1
  715. movwf CCPR1L
  716.  
  717. bcf VTS_LENTE
  718. bcf A_FOND
  719. bsf DECOU_En
  720. bcf STOP_ACCRO
  721. bcf U_FAIBLE
  722.  
  723. movlw .200 ;duree du signal de RESET visible sur le PORTB,4
  724. call Delay_ms
  725. bsf INTCON, GIE ;->INT GLOBALE autorisee
  726.  
  727. ;-----------------------------------------------------------------------
  728. call STOP
  729.  
  730. ;===============================================================================================================
  731. ;TESTS HARDWARE
  732. ;ici1 bcf PORTB,1
  733. ; call tp10ms
  734. ; bsf PORTB,1
  735. ; call tp10ms
  736. ; goto ici1
  737.  
  738. ;===============================================================================================================
  739. ; BOUCLE_PRINCIPALE
  740. ;===============================================================================================================
  741. ;Les numeros des noeuds N1,2... correspondent a ceux de l'organigramme
  742.  
  743. N2 call PPMzero? ;c=1 si oui
  744. btfss STATUS,C
  745. goto N2 ;non
  746. goto N3 ;oui
  747.  
  748. N3 call PPMzero? ;c=1 si oui
  749. btfss STATUS,C
  750. goto N4 ;non
  751. goto N3 ;oui
  752.  
  753. N4 goto demarre
  754.  
  755. N5 call REG_VIT
  756.  
  757. N6 call PPMzero? ;c=1 si oui
  758. btfss STATUS,C
  759. goto N7 ;non
  760. goto N8 ;oui
  761.  
  762. N7 nop
  763. if detecte_vts_lente == 1 ;voir directives en tout debut du listing
  764. btfss VTS_LENTE ;vitesse lente ou moteur arrete ?
  765. ENDIF
  766. goto N9 ;non
  767. goto N1 ;oui
  768.  
  769. N8 bsf STOP_RADIO ;pour stopper le MOTEUR
  770. goto N3
  771.  
  772. N9 nop
  773. if detecte_perio_z == 1
  774. call perio_z? ;(c=1 si oui)
  775. btfss STOP_ACCRO
  776. ENDIF
  777. goto N5 ;non
  778. goto N1 ;oui
  779.  
  780.  
  781. ;===============================================================================================================
  782. ; DEBUT DES PROCEDURES
  783. ;===============================================================================================================
  784.  
  785. ;Teste si T_PPM est inferieure a 90 ? (c=1 si oui)
  786. PPMzero? movf T_PPM,w
  787. sublw 91 ;90-w ; c=0 si neg ; c=1 si pos c.a.d si T_PPM<91
  788. btfss STATUS,C ;(c=1 si oui)
  789. bcf FREIN_En
  790. btfsc STATUS,C ;
  791. bsf FREIN_En
  792. return ;si oui, c=1 et FREIN_En=1
  793.  
  794. ;===============================================================================================================
  795. ;teste si periodeH,L < valeur mini (si accrochage HF) (c=1 si oui)
  796. ;RAPPEL: 1 pas de TMR1H,L = 20MHz/4/4 -> 0,8us
  797. ;cette routine ne me donne pas satisfaction ! le moteur ne peut pas prendre ses tours !
  798.  
  799. perio_z? movlw periodeH ;adresse de periodeH,L
  800. call movxA
  801.  
  802. mot16B 20 ;20*0.8 = 16us ; si la periode est < 16us, on positionne 'c'
  803. call compar16p ;B-A c=0 si negatif c.a.d si A>B
  804. ; btfsc STATUS,C ;(c=1 si oui)
  805. ; return
  806. ; bsf STOP_ACCRO
  807. return
  808.  
  809. ;===============================================================================================================
  810. STOP bsf STOP_RADIO ;STOP
  811. bcf INTCON,3 ;bit3 RBIE=0 -> disable INT du port RB4 a RB7 ; Le moteur ne peut redemarrer
  812. ;que par la routine 'demarre', et pas 'a la main'
  813. call BLOQUE
  814. return
  815.  
  816. ;===============================================================================================================
  817. ;note: ce test est appele dans l'int timer0
  818. V_mini? btfsc PORTB,3 ;PB3=1 si U<6V
  819. bsf U_FAIBLE
  820. btfss PORTB,3
  821. bcf U_FAIBLE
  822. return
  823.  
  824. ;===============================================================================================================
  825. ;REGLAGE DE LA VITESSE (en fait, reglage du rapport cyclique de conduction des MOSFETS,
  826. ;ce qui entraine la variation de vitesse)
  827. ;calcul d'une fonction AH,L = F(T_PPM)
  828. ;fait sauter l'offset
  829. REG_VIT movf T_PPM,w
  830. movwf memo1
  831. movlw 95 ; w:=95 T_PPM_G mini CETTE VALEUR EST A AJUSTER
  832. subwf memo1,f ; f-w(c=0 si negatif) T_PPM_G:= T_PPM_G - 90 (pre-ofset)
  833. btfss STATUS,C ; debordement ?
  834. clrf memo1 ;oui ;memo1 n'est jamais <0
  835.  
  836. ;memo1 est donc une fontion directe de T_PPM
  837. ;ici memo1 = [0..80]
  838.  
  839. ;offset strictement positif
  840. movlw 15 ;valeur minimale admise
  841. addwf memo1,f
  842. ;ici memo1 = [15..95]
  843.  
  844. ;-----------------------------------
  845. ;BEC = DETECTION TENSION D'ALIM FAIBLE
  846. if stop_BEC == 1
  847. btfss U_FAIBLE ;U faible ?
  848. goto suite2 ;non
  849. movlw 4 ;oui, brider vitesse moteur a une valeur fixe, faible, si l'accu est decharge (BEC)
  850. movwf memo1
  851. bcf A_FOND ;pour s'assurer que le decoupage aura bien lieu
  852. goto suite3
  853. endif
  854.  
  855. ;-----------------------------------
  856. ;ARRET DU DECOUPAGE si manche des gaz a fond : pleine puissance.
  857. ;cette partie est sautee si le BEC est entre en limitation de vitesse
  858. suite2 movlw 90
  859. subwf memo1,w ; f-w(c=0 si negatif donc si memo1<90) w= memo1 - 90
  860. btfsc STATUS,C ;memo1>=90 ?
  861. bsf A_FOND ;oui
  862.  
  863. movlw 85 ;cette valeur differente de la precedente imtroduit un hysteresis dans le seuil
  864. subwf memo1,w ; f-w(c=0 si negatif donc si memo1<90) w= memo1 - 85
  865. btfss STATUS,C ;memo1>=90 ?
  866. bcf A_FOND ;non
  867.  
  868. ;-----------------------------------
  869.  
  870. suite3 movlw periodeH ;adresse de periodeH,L
  871. call movxA ;AH,L:=periodeH,L
  872.  
  873. ;on va borner la valeur obtenue a la valeur max atteinte par TMR1H,L compte tenu de la vitesse de rotation actuelle
  874. ;c.a.d de la periode actuelle max
  875. ;qui est memorisee dans periodeH,L par l'INT PORTB4-7
  876. ;le but est de ne pas decouper le signal de sortie a partir d'un instant situe au dela de sa duree maximale !
  877. ;REMARQUE: cette duree maximale de la periode EN COURS n'est pas connue d'avance !
  878. ;on prend donc en compte la duree de la periode precedente et on suppose que la periode en cours
  879. ;aura une duree tres proche, meme si le moteur accelere ou ralentit...
  880. ;La methode a ses limites (en cas de changement brutal du couple mecanique par exemple)
  881. ;toutefois, avec comme charge une helice d'avion, les changements de regime restent progressifs
  882.  
  883. ;Le calcul est le suivant:
  884. ;CCPR1H,L = ( memo1 * periodeH,L )/95
  885. ;sachant que 95 represente la valeur max de memo1, lorsque memo1 = memo1_max = 95 on aura:
  886. ;CCPR1H,L = 95 * periodeH,L / 95 = periodeH,L
  887. ;on obtient donc pour memo1 une valeur [0..periodeH,L]
  888.  
  889. movlw -1 * 20 ;w=20 ;garde
  890. addwf AL,f
  891. btfss STATUS,C
  892. decf AH,f ;ici AH,L:=periodeH,L -20
  893.  
  894. movf memo1,w
  895. call multi24 ;mutiplication 8 bits x 16 bits de w par AH,L resultat (24bits) dans A2,1,0
  896. ;B:=A
  897. movf A0,w
  898. movwf Dividende
  899. movf A1,w
  900. movwf Dividende+1
  901. movf A2,w
  902. movwf Dividende+2
  903. ;ici Dividende= memo1 * periodeH,L
  904. movlw 95 ;valeur de max de memo1
  905. call Div24_8 ;Dividende / w -> Quotient (division 24bits par 8 bits resultat sur 24 bits)
  906.  
  907. ;------------------------------------------------
  908. ;ecriture de la valeur dans le registre CCPR1L du module de COMPARAISON du PIC
  909. ;fonctionne avec le Timer1
  910. ;lorsque TMR1H,L (qui mesure le temps depuis l'INT PORB4-7) = CCPR1H,L, une interruption se produit
  911. ;qui decoupe le signal de sortie
  912. ;RAPPEL: l'INT PORB4-7 se produit quant a elle lors d'un front d'un des trois signaux BEMF
  913. ;et determine 2 actions:
  914. ;- RAZ du Timer1 (TMR1H,L:=0)
  915. ;- Debut de conduction d'une phase
  916.  
  917. movf Quotient,w
  918. movwf CCPR1L
  919. movf Quotient+1,w
  920. movwf CCPR1H
  921.  
  922. return
  923.  
  924. ;===============================================================================================================
  925. ; SOUS-ROUTINES d'INTERRUPTIONS
  926. ;===============================================================================================================
  927. ;int timer0
  928. ;utilise en PERIODEMETRE sur le signal PPM du recepteur de radiocommande
  929. ;la RAZ du timer0 se fait par l'intportB; en principe le timer0 ne deborde jamais, sauf emetteur sur OFF.
  930.  
  931. ;20MHz/4/64= 78.125kHz (12.8us)
  932. ;12.8us*256=3.2768ms (temps max mesurable)
  933. ;en fait on doit mesurer une duree [1,1 ... 2,2 ms]
  934.  
  935. inttimer0 decfsz count0,f
  936. goto fintimer0
  937. bsf STOP_RADIO ;STOP MOTEUR pour arret si plus de signal de reception
  938.  
  939. fintimer0 call V_mini?
  940. return
  941.  
  942. ;===============================================================================================================
  943. ;int timer1
  944. ;TMR1H,L est utilise pour chronometrer la periode de l'enveloppe (1 pas moteur) et gere par l'intB4_7
  945. ;on passe ici si le moteur est a l'arret ou tourne a vitesse tres faible <100rpm
  946.  
  947. ;voir prediv =1/4 (voir T1CON))
  948. ;20MHz -> 50ns
  949. ;20MHz/4/4 -> 0,8us
  950. ;THM1H,L peuvent compter 65536 soit: 53 ms
  951. ;Le moteur a fond sous 8V -> 10 000 rpm soit 1/(10000 /60 *6) -> 1ms de duree de cycle entre 2 INT PORTB4-7
  952. ;Le moteur a 3000 rpm soit 10/3000 = 3,3ms de duree de cycle entre 2 INT PORTB4-7
  953. ;Le moteur a 100 rpm soit 10/100 = 100ms de duree de cycle entre 2 INT PORTB4-7 soit presque 104ms (max)
  954. ;Donc la limite de la vitesse minimale mesurable est d'environ 200rpm
  955.  
  956. ;10000rpm ->TRM1H,L max:= 1236
  957. ;3000 ->TRM1H,L max:= 3710
  958. ;200 ->TRM1H,L max:= 61826
  959.  
  960.  
  961. inttimer1 bsf VTS_LENTE ;vitesse lente ou arret
  962.  
  963. fin_int1 return
  964.  
  965. ;===============================================================================================================
  966. ;int module COMPARAISON
  967. ;on passe ici lorsque TMR1H,L = CCPR1H,L
  968.  
  969. intCompar btfsc A_FOND
  970. goto FinIntCmp
  971. btfss DECOU_En
  972. goto FinIntCmp
  973. call BLOQUE ;decoupage des signaux de sortie
  974.  
  975. FinIntCmp return
  976.  
  977. ;===============================================================================================================
  978. ;int timer2
  979. ;pour decouper le signal de sortie a (relativement, 10kHz) haute frequence lors de la phase de demarrage
  980. ;ce timer fonctionne ici suivant 2 alternances consecutives de durees inegales, mais dont la somme est constante
  981.  
  982.  
  983. inttimer2 btfss DECOUP_HF
  984. goto fin_int2
  985.  
  986. btfss PHASE_HF
  987. goto ph0
  988. goto ph1
  989.  
  990. ph0 bsf PHASE_HF
  991. movf rapcycl,w ;ici w=rapcycl
  992. sublw .255 ;ici w=255-rapcycl
  993. banksel PR2
  994. movwf PR2
  995. banksel AA
  996.  
  997. call BLOQUE ;bloque les MOSFETS du port A (pas le moteur!)
  998. goto fin_int2
  999.  
  1000. ph1 bcf PHASE_HF
  1001. movf rapcycl,w ;ici w=rapcycl
  1002. banksel PR2
  1003. movwf PR2
  1004. banksel AA
  1005.  
  1006. call sortie ;sortie physique des signaux vers les MOSFETS
  1007. goto fin_int2
  1008.  
  1009. fin_int2 return
  1010.  
  1011. ;===============================================================================================================
  1012. ;int Exterieure par bit 0 du port B
  1013. ;detecte les fronts du signal PPM du recepteur de radio-commande
  1014. ;mesure et memorise la duree des impulsions PPM de la voie gaz dans la variable T_PPM
  1015.  
  1016. intB0 btfss EDGE_PPM ;quel front vient-on de detecter ?
  1017. goto frontD ;le front descendant
  1018.  
  1019. frontM clrf TMR0 ;le front montant. RAZ Timer0
  1020. clrf count0
  1021. banksel OPTION_REG
  1022. bcf OPTION_REG,6 ;Interrupt on falling edge of RB0/INT pin (detectera le front descendant)
  1023. banksel AA ;BANK0
  1024. bcf EDGE_PPM ;pour eviter une lecture en bank1 au debut de cette procedure, on testera ce flag
  1025. return
  1026.  
  1027. frontD movf TMR0,w ;le timer0 a compte (l'horloge du PIC) depuis le front montant precedent
  1028.  
  1029. if vif == 1 ;voir directives en tout debut du listing
  1030. movwf T_PPM ;memorisation du temps mesure dans T_PPM, pour utilisation dans le reste du programme
  1031. else
  1032. ;-----------------------------------------
  1033. ;on va memoriser dans T_PPM le temps mesure, pour utilisation dans le reste du programme
  1034. ;ici, plutot qu'une affectation directe et brutale (comme T_PPM:=TMR0), on va proceder
  1035. ;par comparaison des deux valeurs, et on va faire tendre T_PPM vers TMR0 progressivement
  1036. ;ceci dans le but d'eliminer les valeurs aberantes qui peuvent se presenter
  1037. ;ce qui rendait la vitesse de rotation un peu fluctuante autour de certaines valeurs.
  1038.  
  1039. subwf T_PPM,w ; f-w(c=0 si negatif) w:= T_PPM - TMR0 (c=0 si TMR0 > T_PPM)
  1040. btfsc STATUS,Z
  1041. goto intB0_1 ;si egalite, on ne fait rien
  1042. btfsc STATUS,C
  1043. decf T_PPM,f
  1044. btfss STATUS,C
  1045. incf T_PPM,f
  1046. endif
  1047. ;-----------------------------------------
  1048.  
  1049. intB0_1 nop
  1050. banksel OPTION_REG
  1051. bsf OPTION_REG,6 ;(detectera le front montant)
  1052. banksel AA ;BANK0
  1053. bsf EDGE_PPM
  1054. clrf TMR0
  1055. clrf count0
  1056. return
  1057.  
  1058. ;===============================================================================================================
  1059. ;int Exterieure par bits 4a7 du port B
  1060. ;detecte les fronts des 3 signaux de BEMF
  1061. ;REMARQUE: contrairement a l'intRB0, les INT RB4-7 sont declenchees par les fronts montants ET descendants
  1062. ;sans que l'on puisse choisir lequel
  1063. ;RAPPEL: TMR1H,L est compteur 16 bits du timer1 (voir plus haut l'inttimer1)
  1064.  
  1065. intB4_7 movf TMR1H,w
  1066.  
  1067.  
  1068. if integration_PPM == 1 ;voir directives en tout debut du listing
  1069. addwf periodeH,f ;integre et memorise la valeur mesuree de la periode de rotation
  1070. rrf periodeH,f ;/2
  1071. ;il s'agit donc de la valeur maximale de TMRH,L d'autant plus grande que la vitesse est faible
  1072. movf TMR1L,w
  1073. addwf periodeL,f
  1074. rrf periodeL,f
  1075.  
  1076. else
  1077. movf TMR1H,w
  1078. movwf periodeH ;memorise la valeur mesuree de la periode de rotation
  1079. ;il s'agit donc de la valeur maximale de TMRH,L d'autant plus grande que la vitesse est faible
  1080. movf TMR1L,w
  1081. movwf periodeL
  1082. endif
  1083.  
  1084. clrf TMR1H
  1085. clrf TMR1L ;depart de la mesure suivante
  1086.  
  1087. saut2 call pasMot1 ;prepare l'enveloppe du signal
  1088. call sortie
  1089.  
  1090. return
  1091.  
  1092.  
  1093.  
  1094. ;===============================================================================================================
  1095. ; PROCEDURES de commande moteur
  1096. ;===============================================================================================================
  1097.  
  1098. ;cette routine est appelee par l'int ext: intB4_7
  1099. ;genere l'enveloppe du signal qui sera sorti par l'intimer2
  1100.  
  1101. pasMot1 movlw HIGH Tab_Ph
  1102. movwf PCLATH
  1103.  
  1104. movf n_ph,w
  1105. call Tab_Ph ;retourne la valeur de l'octet dans w
  1106. movwf signal ;signal pour commande des MOSFETs. sera utilise par intTimer2
  1107.  
  1108. IF stops == 1 ;voir directives en tout debut du listing
  1109. btfsc STOP_RADIO
  1110. clrf signal
  1111. ; btfsc STOP_ACCRO
  1112. ; clrf signal
  1113. ENDIF
  1114.  
  1115. incf n_ph,f
  1116. movlw 6 ;butee max
  1117. subwf n_ph,w ;w-f(c=0 si negatif)
  1118. btfsc STATUS,C
  1119. clrf n_ph
  1120.  
  1121. return
  1122.  
  1123. ;===============================================================================================================
  1124. ;bloque electriquement tous les MOSFETS relies au PORT A (uniquement) sauf pendqnt le freinage moteur
  1125. BLOQUE btfsc FREIN_En
  1126. return
  1127. movlw B'00001010'
  1128. movwf PORTA
  1129. return
  1130.  
  1131.  
  1132. ;===============================================================================================================
  1133. ;SORTIE PHYSIQUE DES SIGNAUX VERS LES MOSFETS
  1134. sortie nop
  1135. if frein_permis == 1 ;voir directives en tout debut du listing
  1136. btfsc FREIN_En
  1137. goto frein
  1138. ENDIF
  1139.  
  1140. movlw B'00001111' ;bits concernant le PORT A
  1141. andwf signal,w ;ne touche pas signal
  1142. xorlw B'00001010' ;les MOSFETS cote(+) sont pilotes par des transistors inversant la phase
  1143.  
  1144. movwf PORTA
  1145.  
  1146. btfss signal,4
  1147. bcf PORTB,1
  1148. btfsc signal,4
  1149. bsf PORTB,1
  1150.  
  1151. btfss signal,5
  1152. bsf PORTB,2 ;inverse le bit
  1153. btfsc signal,5
  1154. bcf PORTB,2 ;inverse le bit
  1155.  
  1156. return
  1157.  
  1158. frein bsf PORTB,2 ;bloque Q6 (MOSFET cote(+))
  1159. bsf PORTB,1 ;puis ensuite sature Q5 (MOSFET cote(-))
  1160. movlw B'00001111' ;sature les transistors cote(-), bloque ceux cote(+) (MOSFETS Q1,2,3,4)
  1161. movwf PORTA
  1162. return
  1163.  
  1164. ;===============================================================================================================
  1165. ;demarrage force du moteur. On ne passe ici que sur action du manche des GAZ en partant de zero
  1166. ; ATTENTION: routine appelee par un goto (N4 dans bcl pincipale) et pas par un call.
  1167. ; ne se termine donc pas par un return, mais par un goto N5
  1168. ; permet de gagner un niveau dans de pile, mais surtout permet de retourner ailleurs en cas d'arret d'urgence
  1169.  
  1170. demarre bcf STOP_RADIO
  1171. bcf VTS_LENTE
  1172. bcf STOP_ACCRO
  1173.  
  1174. bcf INTCON,3 ;bit3 RBIE=1 -> desable INT du port RB4 a RB7
  1175. bsf DECOUP_HF ;decoupage HF pendant le demarrage force
  1176.  
  1177. banksel PIR1
  1178. bsf PIR1,TMR2IE ;enable INT Timer2 pour decouper les signaux en HF pendant le demarrage
  1179.  
  1180. banksel AA ;BANK0
  1181. bsf INTCON,GIE ;enable INT's
  1182.  
  1183. movlw 20 ;20
  1184. movwf AA
  1185. ;======================================
  1186. dema1 movlw 4 ;8
  1187. movwf BB
  1188.  
  1189. call PPMzero? ;c=1 si oui
  1190. btfss STATUS,C
  1191. goto dema2 ;non
  1192.  
  1193. bsf STOP_RADIO ;oui, arret d'urgence et retour
  1194. call BLOQUE ;moteur en roue libre
  1195. bcf DECOUP_HF ;plus de decoupage 10kHz
  1196. banksel PIR1
  1197. bcf PIR1,TMR2IE ;disable INT Timer2
  1198. banksel AA ;BANK0
  1199. bsf DECOU_En ;decoupage PWM
  1200. bsf INTCON,RBIE ;enable INT du port RB4 a RB7; passe le cycle en mode automatique
  1201. goto N8 ;VERS boucle principale
  1202. ;--------------------------
  1203. dema2 call pasMot1
  1204. call sortie
  1205. ;pendant la phase de demarrage, les signaux sont physiquement sortis par l'int timer2 (qui decoupe en HF)
  1206.  
  1207. movlw 2
  1208. addwf AA,w
  1209. call Delay_ms ;delai proportionnel a AA +2 donc qui decroit avec AA -> f augmente
  1210. decfsz BB,f
  1211. goto dema2 ;boucle interieure courte, BB fois
  1212. ;--------------------------
  1213. decfsz AA,f
  1214. goto dema1 ;boucle exterieure, AA fois
  1215. ;======================================
  1216. bsf DECOU_En ;decoupage PWM
  1217. bsf INTCON,RBIE ;enable INT du port RB4 a RB7; passe le cycle en mode automatique
  1218.  
  1219. call BLOQUE ;moteur en roue libre
  1220. bcf DECOUP_HF ;plus de decoupage 10kHz
  1221. banksel PIR1
  1222. bcf PIR1,TMR2IE ;disable INT Timer2
  1223. banksel AA ;BANK0
  1224.  
  1225. movlw 128
  1226. movwf CCPR1L
  1227. movlw 120
  1228. movwf CCPR1H
  1229.  
  1230. movlw 10
  1231. call Delay_ms
  1232.  
  1233. bcf STOP_RADIO
  1234. bcf VTS_LENTE
  1235.  
  1236. goto N5 ;vers appelant dans la boucle principale
  1237.  
  1238.  
  1239. ;===============================================================================================================
  1240. ; ROUTINES MATH
  1241. ;===============================================================================================================
  1242.  
  1243. ;conversion sexadecimale -> binaire
  1244. ;entree: AA, BB
  1245. ;resultat: AH,AL = 60*AA+BB
  1246.  
  1247. convhbin movlw 60
  1248. call multi16 ;AA contient la donnee a multiplier
  1249. movf BB,w
  1250. addwf AL,f
  1251. btfsc STATUS,C
  1252. incf AH,f
  1253. return
  1254.  
  1255. ;===============================================================================================================
  1256. ;mutiplication 8 bits x 8 bits de w par AA (donnees sur 1 octet)
  1257. ;d'apres note AN526 Microchip
  1258. ;resultat (sur 2 octets) dans AH,AL (poids fort et poids faible)
  1259. ;principe: exactement celui de la multiplication faite 'a la main'
  1260. ;decallages (donc multiplications par le poids de chaque bit) et additions si le bit est un '1'
  1261.  
  1262. multi16 clrf AH ;RAZ de AH qui est ainsi pret a servir pour receptionner le resultat (poids fort)
  1263. movwf AL ;memo temporaire du contenu de w, on a en effet besoin de w a la ligne suivante
  1264. movlw 8 ;pour charger une constante dans le compteur de boucle (8 passes)
  1265. movwf count1 ;compteur de passages dans la boucle
  1266. movf AL,w ;on remet la valeur sauvegardee temporairement dans AL dans w
  1267. clrf AL ;RAZ de AL qui est ainsi pret a servir pour receptionner le resultat (poids faible)
  1268. bcf STATUS,C ;RAZ carry
  1269. loopm16 rrf AA,f ;lecture d'un bit de AA
  1270. btfsc STATUS,C
  1271. addwf AH,f ;si c' est un '1' on ajoute w a AH
  1272. rrf AH,f ;on decalle AH (poids forts) vers la droite, le bit de droite tombe dans c
  1273. rrf AL,f ;le bit de droite est recupere dans AL
  1274. decfsz count1,f ;compte les passages dans la boucle count1 = 0?
  1275. goto loopm16 ;non, on boucle
  1276. return ;oui, on sort
  1277. ;===============================================================================================================
  1278. ;multi24 ;mutiplication 8 bits x 16 bits de w par AH,L
  1279. ;resultat 24bits (sur 3 octets) dans A2,1,0
  1280. ;principe: exactement celui de la multiplication faite 'a la main'
  1281. ;decallages (donc multiplications par le poids de chaque bit) et additions si le bit est un '1'
  1282. ;remarque: CAPACITE MAX:
  1283. ;AH,L:=255,255 =65535 = 2^16 -1
  1284. ;w:=255 =2^8 -1
  1285. ;w * AH,L := 16711425 = (254,255,1) et pas (255,255,255)
  1286.  
  1287. multi24 clrf A2 ;RAZ de A2 qui est ainsi pret a servir pour receptionner le resultat (poids fort)
  1288. clrf A1 ;RAZ de A1 qui est ainsi pret a servir pour receptionner le resultat
  1289. movwf A0 ;memo temporaire du contenu de w, on a en effet besoin de w a la ligne suivante
  1290. movlw 16 ;pour charger une constante dans le compteur de boucle (16 passes)
  1291. movwf count1 ;compteur de passages dans la boucle
  1292. movf A0,w ;on remet la valeur sauvegardee temporairement dans AL dans w
  1293. clrf A0 ;RAZ de AL qui est ainsi pret a servir pour receptionner le resultat (poids faible)
  1294. loopm24 bcf STATUS,C ;RAZ carry
  1295. rrf AH,f ;decallage a droite, le bit de droite tombe dans c
  1296. rrf AL,f ;decallage a droite avec recup du bit ci-dessus, le bit de droite tombe dans c
  1297. btfsc STATUS,C ;lecture d'un bit de AH,L ; test de ce bit
  1298. addwf A2,f ;si c' est un '1' on ajoute w a A2
  1299. rrf A2,f ;on decalle A2 (poids forts) vers la droite, le bit de droite tombe dans c
  1300. rrf A1,f ;le bit de droite de A2 est recupere dans A1
  1301. rrf A0,f ;le bit de droite de A1 est recupere dans A0
  1302. decfsz count1,f ;compte les passages dans la boucle count1 = 0?
  1303. goto loopm24 ;non, on boucle
  1304. return ;oui, on sort
  1305. ;===============================================================================================================
  1306. ;division d'une valeur codee sur 16 bits (AH,AL) par 2
  1307. divi2 bcf STATUS,C ;RAZ carry
  1308. rrf AH,f ;le bit de poids faible tombe dans -> c ; le bit de poids fort de AH devient nul
  1309. rrf AL,f ;le bit de poids faible de AH devient le bit de poids fort de AL
  1310. return
  1311.  
  1312.  
  1313. ;===============================================================================================================
  1314. ;division 24 bits par 8 bits
  1315. ;(auteur I.M.B que je remercie)
  1316.  
  1317. Div24_8 movwf Diviseur
  1318. movlw 24
  1319. movwf Compteur1
  1320. clrf Aux+0
  1321.  
  1322. rlf Dividende+0,f
  1323. rlf Dividende+1,f
  1324. rlf Dividende+2,f
  1325.  
  1326. Div24_81 rlf Aux+0,f
  1327. rlf Aux+1,f
  1328. movf Diviseur,w
  1329. subwf Aux,w
  1330.  
  1331. btfsc Aux+1,0
  1332. bsf STATUS,C
  1333. btfsc STATUS,C
  1334. movwf Aux
  1335.  
  1336. rlf Dividende+0,f
  1337. rlf Dividende+1,f
  1338. rlf Dividende+2,f
  1339.  
  1340. decfsz Compteur1,f
  1341. goto Div24_81
  1342.  
  1343. return
  1344.  
  1345.  
  1346. ;===============================================================================================================
  1347. ;addition 16bits
  1348. ;(AH,AL)+(BH,BL) -> (AH,AL)
  1349.  
  1350. add16A movf BL,w
  1351. addwf AL,f ;(f+w) -> dest ; c=1 si retenue (a traiter)
  1352. btfsc STATUS,C
  1353. incf BH,f ;ajout retenue
  1354. movf BH,w
  1355. addwf AH,f ;(f+w) -> dest ; c=1 si retenue
  1356. return
  1357.  
  1358. ;===============================================================================================================
  1359. ;addition 16bits
  1360. ;(AH,AL)+(AH,AL) -> (BH,BL)
  1361. ;remarque seule la destination (B) est differente par rapport a la procedure add16A
  1362. add16B movf AL,w
  1363. addwf BL,f ;(f+w) -> dest ; c=1 si retenue (a traiter)
  1364. btfsc STATUS,C
  1365. incf AH,f ;ajout retenue
  1366. movf AH,w
  1367. addwf BH,f ;(f+w) -> dest ; c=1 si retenue
  1368. return
  1369.  
  1370. ;===============================================================================================================
  1371. ;complement a deux de la variable codee sur 2 octets situes aux adresses w et w+1
  1372. cpl16x movwf FSR
  1373. comf INDF,f ;w=complement (H)
  1374. incf FSR,f
  1375. comf INDF,f ;w=complement (L)
  1376. incf INDF,f ;w=complement a 2 de L
  1377. btfss STATUS,Z
  1378. return
  1379. decf FSR,f ;pointe H
  1380. incf INDF,f ;retenue
  1381. return
  1382. ;===============================================================================================================
  1383. ;mov la variable codee sur 2 octets situes aux adresses w et w+1 dans -> AH,AL
  1384. ;ATTENTION: AL doit etre stocke en RAM a (adresse de AH) +1
  1385. movxA movwf FSR
  1386. movf INDF,w
  1387. movwf AH
  1388. incf FSR,f
  1389. movf INDF,w
  1390. movwf AL
  1391. return
  1392. ;===============================================================================================================
  1393. ;mov AH,AL dans -> la variable codee sur 2 octets situes aux adresses w et w+1
  1394. ;ATTENTION: AL doit etre stocke en RAM a (adresse de AH) +1
  1395. movAx movwf FSR
  1396. movf AH,w
  1397. movwf INDF
  1398. incf FSR,f
  1399. movf AL,w
  1400. movwf INDF
  1401. return
  1402. ;===============================================================================================================
  1403. ;mov la variable codee sur 2 octets situes aux adresses w et w+1 dans -> BH,BL
  1404. ;ATTENTION: BL doit etre stocke en RAM a (adresse de BH) +1
  1405. movxB movwf FSR
  1406. movf INDF,w
  1407. movwf BH
  1408. incf FSR,f
  1409. movf INDF,w
  1410. movwf BL
  1411. return
  1412. ;===============================================================================================================
  1413. ;mov BH,BL dans -> la variable codee sur 2 octets situes aux adresses w et w+1
  1414. ;ATTENTION: BL doit etre stocke en RAM a (adresse de BH) +1
  1415. movBx movwf FSR
  1416. movf BH,w
  1417. movwf INDF
  1418. incf FSR,f
  1419. movf BL,w
  1420. movwf INDF
  1421. return
  1422.  
  1423. ;===============================================================================================================
  1424. ;comparaison de deux valeurs codees sur 16 bits (AH,L a BH,L)
  1425. ;resultat dans STATUS carry et zero
  1426. ;les valeurs doivent representer des nombres tous deux positifs (pas ok si valeurs codees en complement a 2
  1427. ;sauf pour le test d'egalite STATUS,Z ('z') ) ;16p-> p comme positifs
  1428. ;les valeurs des flags c et z qui sont retournees sont les meme que celles de l'instruction subwf
  1429. ;z indiquant l'egalite et c=o si negatif c.a.d si A>B
  1430.  
  1431. compar16p movf AH,w
  1432. subwf BH,w ;f-w c.a.d B-A c=0 si neg donc si AH>BH
  1433. btfss STATUS,Z ;z=1 si AH=BH il faut alors comparer AL a BL
  1434. return
  1435. movf AL,w
  1436. subwf BL,w ;z=1 si AL=BL et comme on sait deja que AH=BH, si z=1 -> A=B
  1437. return
  1438.  
  1439. ;===============================================================================================================
  1440. ;comparaison de deux valeurs codees sur 24 bits (A2,1,0 a B2,1,0)
  1441. ;resultat dans STATUS carry et zero
  1442. ;les valeurs doivent representer des nombres tous deux positifs (pas ok si valeurs codees en complement a 2
  1443. ;sauf pour le test d'egalite STATUS,Z ('z') ) ;16p-> p comme positifs
  1444. ;les valeurs des flags c et z qui sont retournees sont les meme que celles de l'instruction subwf
  1445. ;z indiquant l'egalite et c=o si negatif c.a.d si A>B
  1446.  
  1447.  
  1448. compar24p movf A2,w
  1449. subwf B2,w ;f-w c=0 si neg donc si AH>BH
  1450. btfss STATUS,Z ;z=1 si A2=B2 il faut alors comparer A1 a B1
  1451. return
  1452. movf A1,w
  1453. subwf B1,w
  1454. btfss STATUS,Z ;z=1 si A1=B1 et comme on sait deja que A2=B2, il faut alors comparer A0 a B0
  1455. return
  1456. movf A0,w
  1457. subwf B0,w ;z=1 si A0=B0 et comme on sait deja que A2,1=B2,1, si z=1 -> A=B
  1458. return
  1459.  
  1460.  
  1461.  
  1462. ;===============================================================================================================
  1463. ;DATA EN EEPROM
  1464. ;===============================================================================================================
  1465.  
  1466. ;ORG 0x2100 ; zone EEPROM
  1467.  
  1468. ;===============================================================================================================
  1469. end
  1470.  
  1471.  
  1472.  

9 Circuit imprimé de la version de test:

10 -

J'ai tout implanté sur un circuit simple face ! La version définitive sera en CMS. (Le schéma subira en conséquence des modifications, en particulier les transistors MOSFET seront des IRF7455 au lieu de IRL44)

Voici un prototype DE TEST en composants classiques. Masse 30g. La version définitive sera en CMS devrait faire moins de 10g.

Note: Le schéma a beaucoup évolué depuis cette version, la rendant totalement obsolete. En conséquence ne me demandez pas de vous fournir le typon du circuit imprimé.

11 Constitution du moteur

  • Le rotor est constitué d'une cloche à la périphérie de laquelle sont collés 12 aimants permanents très puissants.
  • Le stator, qui est fixe, se compose de 9 bobines ne comprenant chacune que quelques spires de fil émaillé. Ces bobines sont reliées en trois ensembles de trois  bobines en séries. Chacun de ces 3 ensembles a donc 2 fils d'alimentations. l'un de ces fils est relié à un point commun non accessible, reste trois fils qui constituent les 3 fils sortant du moteur (Montage en étoile, chaque branche de l'étoile constituée par 3 bobines en série). voir Fig1 ci-dessous.
  • A un instant donné seuls deux de ces trois fils sont reliés par le variateur à l'accu d'alimentation.

12 Principe de fonctionnement

Fig.1: Le stator fixe et son câblage

Fig.2: Le timing des courants (les numéros sont arbitraires, seul l'ordre compte)

13 -

On a vu plus haut qu'à un instant donné seul deux des trois fils du moteur sont reliés par le variateur à l'accu d'alimentation. Cela se traduit sur la Fig.2 ci-dessus par le fait que le courant entrant par une série de trois bobines produit trois pôles Sud, puis, via le point commun, ressortant par une des deux autres séries de trois bobines, produit trois pôles Nord.
  • En sélectionnant judicieusement dans quel ordre on alimente les branches de l'étoile, on obtient le timing de la Fig2. Les flèches vertes indiquent les courants électriques qui passent pour chacune des six temps. 

  • A un instant donné un seul de ces six courants est présent.


14 Timing des tensions de commande alimentant les six transistors MOSFET de puissance:

  • La lettre "H" désigne le transistor reliant une phase au +7V (celui du Haut sur le schéma), et la lettre "L" désigne celui du bas sur le schéma, reliant la phase à la masse. Ces transistors, je le rappelle, sont montés en "pont en H" (voir le schéma, transistors IRLZ44)
  • Les chiffres en haut indiquent les six temps.
  • Lorsque le signal en vert est en haut (1 logique), le transistor concerné conduit, sinon il reste bloqué.
  • Ainsi on voit par exemple qu'au temps 4 le transistor H de la phase 1 conduit en même temps que celui L de la phase2.  Il passe alors un courant entrant par le fil de la phase 1 et sortant par le fil de la phase 2.
  • Il y a toujours exactement 2 transistors en conduction, jamais plus, et jamais 2 de la même phase bien sûr ! (sinon court-circuit direct entre le plus et le moins de l'accu, aie, aie, aie, comptez 60 A sur un accu LIPO)

15 Capteur de position angulaire

Pour chacune de ces six phases, une des branches de l'étoile n'est pas reliée électriquement, et n'est parcourue par aucun courant.

Une force "contre-électromotrice", c'est à dire une tension induite est présente aux aux extrémités de cette branche "volante". Cette tension contre-électromotrice ( back EMF en anglais ou BEMF) est utilisée par le variateur pour ajuster le timing (asservissement de phase). Un circuit combinatoire analogique et trois comparateurs rapides permettent d'utiliser ces signaux de BEMF. Pour le schéma de ce réseau, et uniquement pour cela, je me suis inspiré d'une réalisation publiée en langue anglaise et surtout allemande (je ne comprend strictement pas un mot d'allemand ! ) et accessible par les liens au bas de cette page. Je remercie ici leur auteur pour le gain de temps que cela m'a permis. Tout le reste est de moi. ( les autres parties du schéma, le choix du microcontrôleur PIC16F628, le soft dans son intégralité, etc...). La note d'application AN857 de Microchip m'a toutefois été d'une grande utilité pour comprendre le principe de la commande des ces moteurs).

16 -

J'avais placé un capteur à effet Hall UGN 3503 externe POUR LES TESTS. Il "voyait passer" les aimants du rotor. Sa position était ajustable. FINI ! Plus de capteur externe !

17 La rotation analysée pas à pas

18 -

La séquence de photos ci-dessus nous montre le timing du champ tournant et la réponse du moteur:

Entre chaque image le moteur tourne de 10 degrés. Il faut 36 images (dont je ne représente ci-dessous que les 4 premières) pour effectuer un tour mécanique complet.

Faut-il le rappeler ? : les pôles de même signe (Nord-Nord ou Sud- Sud) se repoussent, ceux de signe contraire (Nord- Sud) s'attirent. J'ai représenté les pôles Sud en rouge et les pôles Nord en bleu. Un des aimants est repéré par un "x" jaune afin de mieux visualiser la rotation.

On constate que:
  • l'espacement angulaire des bobines est de 360/9= 40 degrés
  • l'espacement angulaire entre les aimants est de 360/12= 30 degrés
  • à chaque pas, l'aimant suivant (orienté +30 deg) fait face à la bobine suivante (orientée +40 deg) donc le stator tourne de 40-30 = 10 degrés, soit 6 fois moins vite que le champ.
  • un tour moteur (360º mécanique) se décompose électroniquement en 36 phases électriques.
  • la période de récurrence des signaux électriques est de 6 temps. (il y a six états distincts de commutations, puis le cycle reprend à l'identique)
  • A l'issue de ces 6 phases temporelles, le programme retombe dans le même cycle.
  • Lorsque le champ magnétique engendré par les bobines du stator (qui est fixe, au centre du moteur) fait 1 tour(*) (360 degrés soit 36 phases électriques) le rotor (cloche) ne tourne que de 60 degrés: SIX FOIS MOINS VITE.
(*) notion ambiguë ici vu les lignes de forces au formes complexes et mouvantes du champ en question...

19 C'est simple non ?

En fait pas tant que ça !

Je vous ai en effet expliqué comment le moteur, lorsqu'on lui applique les bons signaux, veut bien se donner la peine de tourner. Oui mais ces signaux, il faut les produire ! Et ça ce n'est pas si simple. Analysons le problème:

Il semblerait qu'il suffise de générer trois signaux rectangulaires déphasés de 120 degrés (2pi/3), un courant triphasé en quelque sorte, (plus exactement des tensions) et l'appliquer au moteur pour que celui-ci se mette à tourner. Hé bien ça ne marche pas ! Imaginez qu'on applique un tel courant triphasé ayant une certaine fréquence, par exemple 60Hz... le moteur au repos ne peux pas se mettre INSTANTANÉMENT à tourner à une dizaine de tours à la seconde, comme ça clac ! On pourrait penser qu'il va se mettre à accélérer progressivement depuis zéro jusqu'à la bonne vitesse correspondant à la fréquence du courant... hé bien justement, les vitesses intermédiaires qu'il devrait prendre ne correspondent PAS à la fréquence du courant ! Et le moteur ne se mettra donc pas à tourner, il entrera en vibration, c'est tout ! (Les moteurs de machines à laver un peu anciennes savaient le faire, mais c'était des moteurs ASYNCHRONES à champ glissant, sans aimants permanents. Les Brushless dont je parle sont plutôt des moteurs SYNCHRONES )

Bon, me direz vous, si le moteur ne s'adapte pas à la fréquence du courant, adaptons la fréquence au moteur . On lui applique d'abord une fréquence nulle... heu c'est quoi une fréquence nulle ? Bon d'accord, disons une fréquence très faible, genre 1 Hz qui le fera vibrer, puis on augmente la fréquence progressivement en laissant le temps au moteur d'accélérer pour suivre docilement cette fréquence. Ce n'est pas une mauvaise idée, il s'agit d'un moteur dit synchrone, ça marche, mais ça pose des problèmes...

En simplifiant un peu, si on augmente le couple (on freine le moteur) une fois la vitesse désirée obtenue, il décrochera brusquement. La vitesse de rotation ne pouvant plus suivre la fréquence d'alimentation, le moteur arrêtera de tourner et se mettra à vibrer à la place, et pourrait même être détruit ! Il faudrait pour éviter le décrochage, soit augmenter l'intensité du courant d'alimentation, soit... diminuer la fréquence. Ce qui est très compliqué à réaliser. Détecter le couple ? comment ? On peut mesurer le courant. Pas simple... Et surtout: si le couple augmente très brusquement, même une fraction de seconde, le moteur décrochera quand même. Et un moteur synchrone décroché ne raccroche pas. Il faut alors détecter le fait qu'il ne tourne plus, et ré-appliquer une fréquence partant de zéro... Sans compter que si le moteur propulse une voiture... elle risque de se vendre très mal.

Mais alors que faire ? le moteur ne s'adapte pas à la fréquence du courant, et il est difficile d'adapter le fréquence au régime du moteur et aux aléas de la tension d'alimentation, du couple etc...

L'IDEE : Et si c'était le moteur qui indiquait au montage électronique ce qui lui convient comme signaux de commande, à tout moment ? V'la que c'est le moteur qui commande au courant maintenant !

Mais réfléchissons un peu à ce qui se passe dans un moteur à courant continu, à collecteur, balais et charbons. C'est la rotation du rotor qui par l'intermédiaire des secteurs (bagues) du collecteur tournant sous les charbons, DECOUPE le courant continu d'alimentation pour en faire, vu des bobines du rotor un courant alternatif exactement adapté à tout moment à la position du rotor dans le champ magnétique des aimants fixes. Et bien sûr, forcément toujours à la bonne fréquence ! Bon, nous on a un moteur brush-less, on ne va quand même pas y rajouter un collecteur et des balais ! Non mais certaines réalisations utilisent trois capteurs magnétiques extérieurs à la cage tournante, qui renseignent l'électronique sur la position du rotor et donc sur les tensions à appliquer. Et ces réalisation se trouvent par exemple sur certains lecteurs de CD... C'est mécaniquement compliqué, fragile (près des parties tournantes du moteur), encombrant, cher...

C'est donc ici que nous retrouvons notre BEMF, la tension induite par les aimants en rotation dans les bobines fixes... et tout à fait exploitable. Le circuit analogique combinatoire (voir le schéma) produit en sortie des trois comparateurs (LM139) trois tensions rectangulaires déphasées de 2pi/3, synchrones non pas avec les tensions d'alimentation, mais avec la vitesse de rotation effective du moteur. Et le microprocesseur PIC16F628 fera commuter les six transistors MOSFET en cadence avec ces tensions au moyen des interruptions logicielles des bits 4 à 7 de son port B. (Il s'agit d'une des sources d'interruptions sur ce microcontrôleur).

La variation de vitesse est obtenue par découpage des signaux de sortie, avec rapport cyclique fonction F(x) des signaux de la télécommande, et en proportion de la période de base du cycle (une "simple" règle de trois, avec division sur 24 bits quand même ). Voir le timing ci-dessous.

Enfin, lors de la phase de démarrage, la mise en service temporaire du Timer2 découpe le signal de sortie avec une fréquence relativement haute, afin de limiter le courant.

Voir le soft minutieusement commenté, je vous dévoile tout et... en français !

20 Découpage des signaux de sortie afin de faire varier la vitesse:

  • T0-T2 = période de base générée par l'interruption portB4-7 (déclenchée par les signaux BEMF ) et comptée par le Timer1 du PIC. 
  • T0-T1=période de conduction.
  • En T1 le module de comparaison du PIC détecte que TMR1H,L = CCPR1H,L (consigne = f(T_PPM)) et provoque le blocage du signal de sortie.
  • de T1 à T2 les MOSFETS ne conduisent pas.

21 Photos des signaux sur l'oscillo:

Signaux sur RA0 et RA2 du PIC : deux phases consécutives Manche des gaz au mini.

Manche des gaz presque au maxi.

22 -

Signaux sur RA0 et RA1 du PIC : même phase, mais attaque MOSFETS coté (-) et coté (+)
Manche des gaz en position moyenne.

23 Le moteur sur le banc de test:

(Je fais aussi des essais avec une hélice 9x5, mais ce banc de test bricolé avec un tambour de magnétoscope comme volant d'inertie monté sur roulements est beaucoup moins dangereux)

24 -

Pour les essais avec hélice, (moins d'inertie et plus de résistance ) ce carénage évite les accidents.

25 Journal et compte rendu des essais:

3 Mai 2005:  
  • J'ai enfin trouvé la solution logicielle qui permet de se passer de capteur de position externe. 
  • Le régime du moteur est variable et il est obtenu par découpage des signaux de phases -> bon rendement.
  • SECURITE: pas de démarrage à la mise sous tension

CA FONCTIONNE ! 

Démarrage instantané, prise de vitesse foudroyante,  régime stable tout comme un moteur à courant continu à balais. PAS DE DECROCHAGE !!!!! La vitesse s'adapte tout simplement au couple. Et bien sûr, les avantages des moteurs brushless: pas de frottement ! et un MOSFET qui conduit, a une résistance plus faible que le contact d'un charbon frottant sur les bagues en cuivre.

Avec une alim de 8V, le moteur tourne à 10 000 tours/mn (à vide)

Le courant consommé est fonction du couple.

Ah, j'oubliais: la fonction BEC  n'est pas implémentée. Je pense le faire très prochainement, ça ne pose pas de problème. 

Il reste également à traiter la question de l'antiparasitage.

Je vais faire le circuit imprimé en CMS et le publierai dès que possible. A très bientôt ici même !

Améliorations restant à apporter:

  • la fonction BEC (arrêt si tension d'alim faible afin de garder de l'énergie pour alimenter le récepteur radio, et afin de ne pas détériorer les accus LiPO. Facile à faire.
  • antiparasitage (qq petits condos... et un circuit imprimé bien conçu)

7 Mai 2005:  

  • J'ai réécrit une bonne partie du soft afin de le rendre plus structuré et plus lisible.
  • Cette version (v10) du soft me satisfait assez, au point que je vais maintenant attaquer le circuit imprimé en CMS.

8 Mai 2005: 

  • J'ai ajouté (v12) un découpage des signaux de sortie en HF lors de la phase de démarrage (évite les sur-intensités lors de cette phase). Bon faut que je me calme sur le soft, passons au circuit imprimé !

9 Mai 2005:

  • Ca y est, le circuit imprimé en CMS avance: (il reste beaucoup de travail, je n'ai pas routé GND, Vcc, +8V et +16V ni les 3 phases en sortie! Pour GND j'avais prévu un plan de masse sur l'autre face... 
  • A moins que... puisque c'est de la CMS... je pourrais faire du double face en répartissant les composants sur les 2 faces. Le PIC et les MOSFETS sur une face, le réseau de résistances et le comparateur sur l'autre face. Oui, je pense que je vais faire ça. Les dimensions seront de l'ordre de 25mm x 50mm. Mais c'est un peu difficile à réaliser.

11 Mai 2005:

  • Le dessin du CI en double face avance:
  • Dans un premier débordement d'enthousiasme, j'avait configuré le routeur afin qu'il accepte le passage de pistes entre les pattes des CI en CMS ce qui revient à travailler au 1/100 pouce soit au 1/4mm. Mais je pense qu'une gravure si fine n'est pas réalisable par un amateur avec une simple imprimante laser pour réaliser le typon.


26 16 Mai 2005: Voici le routage provisoire du circuit imprimé:

C'est un double face mais avec tous les composants du même côté. On peut réduire les dimensions du board en plaçant des composants des deux côtés, mais... mon routeur, même configuré aux petits oignons, explose le nombre de vias! J'ai donc décidé de placer tous les composants sur la même face.

27 -

Côté éléments CMS

Côté éléments classiques

28 L'implantation des composants:

29 -

Détails

30 Le typon double face:

Le typon double face est prêt ! (Le vrai est bien net, pas comme cette image JPG un peu floue...)

Reste maintenant à attendre que le soleil se montre... Pourquoi le soleil ? Parce que lorsque je veux obtenir des pistes bien fines aux bords bien nets j'expose le typon et le CI présensibilisé 1mn au rayons bien parallèles du soleil, et pas aux UV de l'insoleuse qui ne m'a jamais satisfait.

D'ailleurs les termes 'insolation' et 'insoleuse' ne viennent-ils pas de 'soleil' ?

31 Bonne nouvelle

je viens de vérifier que mon variateur, sans aucune modification, fonctionne parfaitement bien avec un petit moteur brushless de Disque Dur. (il s'agit d'un moteur à 3 fils, ce qui est rare apparemment). Ce petit moteur non seulement démarre, mais tourne très bien, même à vide. Le couple est important, et la variation de vitesse fonctionne également très bien. Le courant absorbé reste inférieur à 1A.

32 21 Mai 2005 - Soudure des composants en cours:

Vous remarquerez qu'on peut resserrer tout ça, quoi que.. La partie 'aérée' du bas va recevoir les quelques composants discrets sur l'autre face (quartz, condensateurs tantale.

Il me manque des 11k CMS pour terminer! je viens de les commander.

Il est tout à fait possible de faire passer une piste entre les pattes d'un composant CMS format 0805

Des pistes passant sous les petits transistors et reliant les MOSFETS à la masse sont à doubler extérieurement de fils de cuivre, sinon...

33 -

Ensuite il faut... le souder!

34 Suite du compte rendu...

Merci déjà à tous ceux qui m'envoient, qui son soutien, qui une idée pour améliorer le timing, qui une petite routine de division trois fois plus compacte que la mienne.

28 Mai 2005: (schéma 14)

J'ai enfin reçu mes trois R de 11k CMS, et j'ai donc pu tester le le circuit. C'est la première fois donc que je fais tourner le montage avec des IRF7455 SMD à la place des IRFZ44. Et là surprise ! les appels de courant sur l'alim (pas sur l'accu) sont tels que le PIC reset et que le LM339 oscille(au démarrage, qui foire donc). La solution à été d'ajouter une diode et un condensateur de 3300uF en tête de l'alim 5V. Ce n'est pas très élégant et j'espère trouver (ou peut-être vous...) une autre solution plus légère.

J'ai dû aussi rajouter trois résistances de 100 ohm (R34,35,36) parce que le PIC ne supporte pas de débiter sur la charge capacitive que représente la gate des IRF7455 (3,5 nF + l'effet Miller, le double que pour les IRFZ44). En fait, dans ce cas, le port concerné configuré en sortie se bloque à GND après une impulsion avortée à peine visible à l'oscillo.

Comme quoi le simple remplacement d'une référence par une autre très proche peut tout remettre en cause. Comme quoi aussi des composants plus performant peuvent engendrer des problèmes nouveaux.

2 Juin 2005:
Pour (et pendant) la programmation du PIC in-situ, il faut couper les 2 pistes reliant RB6 et RB7 du PIC à respectivevent pin1 et pin2 du LM339. (Microchip préconise de rajouter des résistances en série...). Je n' ai pas testé avec les résistances, parce que mon programmateur est très limite...

13 Juin 2005:
Suite aux conseils judicieux de I.M.B, j' ai apporté un certain nombre d'améliorations au soft (maintenant version 15) : Il devient peu à peu modulaire et plus structuré. J'utilise d'avantage les puissantes directives d'assemblages mises à notre disposition.

Nous entrons maintenant dans le domaine des essais en vol (sur un avion modèle réduit) et de l'optimisation....

14 septembre 2005
Nouvelle version du soft
(maintenant version 19):

  • Détection du signal "manche gaz à zéro" AU SEIN de la procedure de démarrage (tout démarrage intempestif provoqué par un parasite est immédiatement inhibé)
  • Détection tension accu faible (sytème BEC) activé.
Mais il subsiste des ratés moteur plein pot.(voir la solution plus bas, le 25 septembre)

MAIS,
et surtout... cette version a  quitté le labo des vaches et A FAIT VOLER UN MOTOPLANEUR
  • Fuselage + moteur (celui de la photo) + ce variateur + accu LiPo 2S 850mAh + radio + servos =362g
  • Ailes = 225g
soit 587g en vol. 25 septembre 2005
(Après plusieurs vols satisfaisants effectués la veille: )

Légères modifications du soft (maintenant version 20):
  • arrêt du découpage des signaux de sortie si manche des gaz "à fond" : Le moteur gagne des tours ! et ne cafouille plus à fond.


25 septembre 2005:
(Après plusieurs vols satisfaisants effectués la veille: )
Légère modification du schéma:
  • ajout d'un C=100nF dans le circuit collecteur du transistor de détection de la tension accu faible. Supprime le "cafouillage" du moteur plein pot. (voir plus haut, le 14 septembre)

Maitenant, le REX 220 FLYWARE avec ce variateur et une hélice 9x5 a VRAIMENT la pêche.

Il faudra juste que j'ajoute une fonction FREIN et que je remplace l'hélice par un modéle repliable, ce qui permettra d'allonger notablement les temps de vol.

Et suite à toutes les améliorations de l'électronique, je suis bon pour refaire le circuit imprimé CMS !


35 Photos en vol:

 27 septembre 2005:

Après plusieurs vols toujours aussi satisfaisants effectués la veille, en voici les photos :

Vous pouvez cliquer sur ces vues pour les agrandir.

J'ai réussi à piloter d'une main en prenant les photos de l'autre !

L'objet blanc sous le planeur sur la cinquième photo est un avion de ligne qui passait par là, un peu plus haut toutefois.

Le planeur est un 2 axes auquel j'ai rajouté des ailerons. L'hélice touche le sol à l'atterrissage, mais elle est extrêmement flexible.

Vous remarquerez que j'ai ajouté un petit radiateur sur les 6 MOSFETS, toutefois il reste pratiquement froid.
Concernant le variateur, après maintenant une dizaine de vols, je n'ai pas constaté de brouillages de la radio en 41MHz - FM.
Je pense toutefois qu'il serait raisonnable de placer quelques de petites capas ici et là...


36 -

37 -

38 Détail de l'électronique emabarquée:

39 Suite de la mise au point:

29 septembre 2005:


Légères modifications du soft (maintenant version 21:
  • Le FREIN est implémenté et fonctionne.
  • Quelques a-coups réguliers dans la vitesse du moteur à fond sont dus à la fonction BEC un peu trop sensible aux appels de courant (disparraissent totalement si je court-circuite la zener 5V6). Je dois donc revoir soit le circuit de détection de tension, soit le soft afin de supprimer ce (dernier?) inconvéniant.

J'ai remplacé l'hélice par un modèle repliable (9x5 Graupner) mais pour l'intant le vent m'empêche de faire des essais en vol.
Je pense pouvoir remplacer les diodes Schottky 1N5822 (40V 3A) par des 1N5819 (1A) bien plus petites.


7 octobre 2005

Pour ne rien vous cacher voici le récit d'un incident:

Après un vol sans problème et après rechargement de l'accu, le moteur semble tourner légèrement  moins vite et fait un drôle de bruit à plein régime. Une sorte de son plus grave que d'habitude. Ayant entre-temps vu voler un avion à moteur thermique, j'ai signalé au copain que le bruit de son moteur m'avait certainement "faussé l'oreille " ! Et j'ai lancé le planeur électrique qui a pris de l'altitude, mais a semblé un peu poussif.
Une fois rentré chez moi, je teste tout, et je trouve
à l'oscillo un signal  non verouillé à Vcc sur Phi3.
Cause: le transistor Q6 ( MOSFET -  IFR7455 côté(+) ) grillé : court-circuit franc entre GATE et SOURCE. (donc dans le circuit de commande)
Et maintenant que j'étudie le datasheet de la bête, je vois dans les 'absolute max ratings' un Vgs max de +/- 12 V (ce qui ne fait pas 24!)... Et sur mon schéma on constate que j'alimente la gate avec du +16V... (en fait un peu plus lorsque l'accu est bien chargé). Donc à mon avis il va falloir légèrement modifier le schéma... Snif, snif... hum, ça sent la diode ça, même peut-être la zéner...
Connaissant les performances des accus LiPO les jours de grande forme, dois-je m'attendre à voir mon planeur se transformer en étoile filante ?

9 octobre 2005

Je n'ai pas encore eu le temps de me pencher sérieusement sur ce problème de claquage Gate-Source, avec le secours de l'oscillo. Toutefois je vous livre mes premières reflexions:
Je m'étais dit que lorsque le transistor driver Q9 se bloque la tension sur la Gate de Q6 monte effectivement à +16V/masse, mais que la conduction dudit transistor Q6 (le MOSFFET) entrainait l'élévation du potentiel de sa source (à +8V), de sorte que la tension Vgs n'atteignait jamais des valeurs critiques. Mais je vais regarder cela de plus près, car le potentiel de la source suit celui de la gate AVEC RETARD... (temps de saturation de Q6). L'oscillo en mode différentiel entre G et S me confirmera la chose.

Il faut aussi que je vois de plus près ce qui se passe pendant la phase de freinage... et aussi pendant les périodes de découpage des signaux....

10 octobre 2005

Après examen à l'oscillo, il s'avère que la tension Vgs ne dépasse jamais les spécifications du datasheet... Je ne vois donc pas, pour l'instant, ce qui a pu griller l'espace G-S du MOSFET. Je me souvient toutefois avoir déconecté le variateur de l'accu, du moteur, et du récepteur, l'avoir montré au copain présent sur la piste, puis l'avoir remis en place juste avant de constater la panne. Donc il se peut qu'une décharge électrostatique sur la connexion phi3 soit la cause du claquage.

Voici une bonne nouvelle pour changer un peu: je viens de voir sur le nouveau catalogue 2005-2006 d'Electronique Diffusion l'apparition des MOSFET Si4463DY - SMD, canal P , 11A,  12 milli-Ohm
(prix = 1 euro, sur commande)! Voilà qui ouvre de nouvelles perspectives (les Américains les employaient depuis longtemps). Fini le circuit élévateur de tension pour alimenter des Gates ! on va gagner 2 grosses diodes Schottky,  2 gros condensateurs, 3 résistances, 3 transistors !!!!!!! Vous voyez bien qu'il ne fallait pas vous précipiter à réaliser le circuit imprimé !

D'autre part concernant le microcontroleur PIC utilisé, il en est un autre qui me fait des clins d'oeil... l' ATMEGA 8 d'ATMEL

31 Octobre 2005

L' ATMEGA 8 m'a paru tellement intéressent que je lui consacre une page sur ce site:

Je vous y donne toutes les informations permettant de les utiliser facilement et à moindres frais.

6 décembre 2005:
Je me suis familiarisé avec les ATMEGA en réalisant un capacimètre, ainsi qu'un Générateur haute Fréquence. J'ai donc décidé de refaire mon variateur brushless avec un ATMEGA8 et des
MOSFET Si4463DY - SMD, canal P.
Je vous tiens bien évidemment au courant.


26 mai 2006:
Je connais suffisamment les ATMEGA pour me lancer dans la réalisation d'un variateur utilisant un ATMEGA8-16.
Je décris les étapes de nouveau montage sur ce site, ICI.

40 -



80405