510 likes | 548 Views
YES. NO. RI. PWML = 170. PWML = 90. END=1. RI=1. FF. RIGHT. 120 120. END=1. 90 120. RI=0. Techniques de programmation. Procédurale séquentielle. Basé sur les Automates. ISR. Utilisant les Interruption. Avec un RTOS. Prenons un exemple concret. PWML. Départ: . ST. µContrôleur.
E N D
YES NO RI PWML = 170 PWML = 90 END=1 RI=1 FF RIGHT 120 120 END=1 90 120 RI=0 Techniques de programmation Procédurale séquentielle Basé sur les Automates ISR Utilisant les Interruption Avec un RTOS
Prenons un exemple concret PWML Départ: ST µContrôleur LE PONT H MOTEUR Gauche: PORTA PWM Droite: MOTEUR PONT H RI Stop: PWMR END
PWML PWMR 170/255 170/255 MOT G MOT D Principe du suivi de ligne
PWML PWMR 170/255 170/255 MOT G MOT D Principe du suivi de ligne
PWML PWMR 90/255 170/255 MOT G MOT D Principe du suivi de ligne
90/255 170/255 MOT G MOT D Principe du suivi de ligne PWML PWMR
La GAMELLE de CACHAN MCU: PIC 16F877 DETECTEUR DE BARRE FINALE DETECTEUR DE LIGNE DETECTEUR ULTRASON
Programmation procédurale séquentielle Le programmeur (débutant) ne pense qu’à Un seul événement à la fois
YES NO RI PWML = 170 PWML = 90 ST=0 NO YES NO END=0 LE=1 YES YES NO PWMR = 170 PWMR = 90 PWML = 0 PWMR = 0 STOP Programmation procédurale séquentielle MAIN PWML = 0 PWMR = 0
MAIN Programmation procédurale séquentielle void main (void){ Mais … la complexité du programme croît trop vite avec le nombre de cas à prendre en compte. Les éléments du modèle utilisé se traduisent directement * PWM1_DUTY = 0; * PWM2_DUTY = 0; PWML = 0 PWMR = 0 ST=0 while (*PORTA & 0x80); NO YES LE=1 YES NO if (*PORTA & 0x40) { * PWM2_DUTY = 120; } else { * PWM2_DUTY = 90; } PWMR = 120 PWMR = 90 …
Programmation basés sur les automates IDLE while (TRUE){ switch (STATE){ case IDLE : … break; case FF : … break; case RIGHT : … break; case LEFT : … break; case STOP : … break; } } 0 0 ST=0 END=1 END=1 LE=1 RI=1 FF LEFT RIGHT 120 90 END=1 120 120 END=1 90 120 LE=0 RI=0 … case IDLE : * PWM1_DUTY = 0; * PWM2_DUTY = 0; if ((*PORTA & 0x80)==0){ STATE = FF; break; ……… END=0 END=0 END=0 STOP 0 0
Echo Ultrason Batterie faible Emetteur ultrason Température excessive TIMER PORTB Référence atteinte Fin de conversion Octet Émis/reçu RS232 ADC Limite de l’automate sans interruption Trop d’événements => Automate trop complexe µContrôleur PWML Départ: ST LE PONT H MOTEUR Gauche: PORTA PWM Droite: MOTEUR PONT H RI Stop: PWMR END
Programme d’Arrière plan et Interruption interrupt INT1 void INT1_ISR (void){ // Traiter l’événement // Acquitter l’interruption } • PROGRAMME • D’ARRIERE PLAN • Initialisations • des périphériques • Initialiser les • Interruptions • Boucle principale • [Automates] • ou • while (TRUE){} interrupt INT2 void INT2_ISR (void){ // Traiter l’événement // Acquitter l’interruption } interrupt INT3 void INT3_ISR (void){ // Traiter l’événement // Acquitter l’interruption }
Vecteurs d’interruption MCU à table de vecteurs MCU à vecteurs figés
La vie d’une interruption Sauvegarde du contexte Programme normal Routine d’interruption Déclenchement de l’interruption Reprise du Programme normal Restauration du du contexte
Programme d’arrière plan CCR CCR NOP PC PC MainLoop : D D NOP BRA *-2 X X STACK Y Y LDAA $100 ISR_XX : SP STAA $00 LDAA #01 STAA 05 VECTOR_XX : ISR_XX : RTI
Programme d’arrière plan CCR CCR NOP MainLoop : D D NOP PC BRA *-2 X X STACK Y Y LDAA $100 ISR_XX : SP STAA $00 LDAA #01 STAA 05 VECTOR_XX : ISR_XX : RTI
Programme d’arrière plan CCR CCR NOP MainLoop : D D NOP PC BRA *-2 X X STACK Y Y LDAA $100 ISR_XX : SP STAA $00 LDAA #01 STAA 05 VECTOR_XX : ISR_XX : RTI
Programme d’arrière plan CCR CCR NOP PC MainLoop : D D NOP BRA *-2 X X STACK Y Y LDAA $100 ISR_XX : SP STAA $00 LDAA #01 STAA 05 VECTOR_XX : ISR_XX : RTI
Déclenchement d’une interruption Autorisation Locale Autorisation Globale IE I 1 0 0 0 INT 0 IRQ Set Q IACK Reset IF READ WRITE
Déclenchement d’une interruption Autorisation Locale Autorisation Globale IE I 1 0 0 1 1 0 0 INT 1 IRQ Set Q IACK Reset 1 IF READ WRITE
INT XX Sauvegarde du contexte CCR CCR NOP PC MainLoop : D D NOP BRA *-2 X X STACK Y Y LDAA $100 ISR_XX : RETURN @ PC SP STAA $00 LDAA #01 STAA 05 VECTOR_XX : ISR_XX : RTI
INT XX CCR D X Y Sauvegarde du contexte CCR CCR NOP PC SP MainLoop : D D NOP BRA *-2 X X STACK Y Y SP LDAA $100 ISR_XX : RETURN @ STAA $00 LDAA #01 STAA 05 VECTOR_XX : ISR_XX : RTI
INT XX CCR D X Y LDX $100 STX $00 LDAA #01 STAA 05 RTI Branchement sur la routine de service CCR CCR NOP PC SP MainLoop : D D NOP BRA *-2 X X STACK Y Y LDAA $100 PC ISR_XX : ISR_XX : RETURN @ STAA $00 LDAA #01 STAA 05 ISR_XX: VECTOR_XX : VECTOR_XX : ISR_XX : RTI
INT XX CCR D X Y LDX $100 STX $00 LDAA #01 STAA 05 RTI Exécution de l’ISR CCR CCR CCR NOP SP MainLoop : D NOP BRA *-2 X X X STACK Y Y LDAA $100 PC ISR_XX : ISR_XX : RETURN @ STAA $00 LDAA #01 STAA 05 ISR_XX: VECTOR_XX : VECTOR_XX : ISR_XX : RTI
INT XX CCR D X Y LDX $100 STX $00 LDAA #01 STAA 05 RTI Exécution de l’ISR CCR CCR CCR NOP SP MainLoop : D D NOP BRA *-2 X X X STACK Y Y LDAA $100 ISR_XX : ISR_XX : RETURN @ STAA $00 PC LDAA #01 PC STAA 05 PC ISR_XX: VECTOR_XX : VECTOR_XX : ISR_XX : RTI
Accuser réception de l’interruption (IACK) Autorisation Locale Autorisation Globale IE I 1 0 1 0 1 0 INT 1 0 IRQ Set Q 1 IACK 1 Reset interrupt XYZ void ISR_XYZ (void){ …. * XYZ_IF = 1; } IF READ 1 WRITE 1 1
INT XX CCR CCR D D X X Y LDX $100 STX $00 LDAA #01 STAA 05 RTI Restaurer le contexte CCR CCR NOP SP MainLoop : D NOP BRA *-2 X X STACK Y Y LDAA $100 ISR_XX : ISR_XX : RETURN @ STAA $00 LDAA #01 STAA 05 PC ISR_XX: VECTOR_XX : VECTOR_XX : ISR_XX : RTI
CCR CCR CCR D D D X X X Y Y LDX $100 STX $00 LDAA #01 STAA 05 RTI Restaurer le contexte CCR CCR NOP SP MainLoop : D NOP BRA *-2 X X STACK Y Y LDAA $100 ISR_XX : ISR_XX : RETURN @ RETURN @ STAA $00 LDAA #01 STAA 05 ISR_XX: VECTOR_XX : VECTOR_XX : ISR_XX : RTI PC
CCR D X Y LDX $100 STX $00 LDAA #01 STAA 05 RTI Restaurer le contexte CCR CCR NOP MainLoop : D NOP BRA *-2 X X STACK Y Y LDAA $100 ISR_XX : ISR_XX : SP RETURN @ RETURN @ STAA $00 LDAA #01 STAA 05 ISR_XX: VECTOR_XX : VECTOR_XX : ISR_XX : RTI PC
CCR D X Y LDX $100 STX $00 LDAA #01 STAA 05 RTI Restaurer le contexte CCR CCR NOP MainLoop : PC D NOP BRA *-2 X X STACK Y Y LDAA $100 ISR_XX : ISR_XX : SP RETURN @ RETURN @ STAA $00 LDAA #01 STAA 05 ISR_XX: VECTOR_XX : VECTOR_XX : ISR_XX : RTI
Reprendre le programme d’arrière plan CCR CCR NOP PC PC MainLoop : D D NOP BRA *-2 X X STACK Y Y LDAA $100 ISR_XX : SP STAA $00 LDAA #01 STAA 05 VECTOR_XX : ISR_XX : RTI
Reprendre le programme d’arrière plan CCR CCR NOP MainLoop : D D NOP PC BRA *-2 X X STACK Y Y LDAA $100 ISR_XX : SP STAA $00 LDAA #01 STAA 05 VECTOR_XX : ISR_XX : RTI
Reprendre le programme d’arrière plan CCR CCR NOP MainLoop : D D NOP PC BRA *-2 X X STACK Y Y LDAA $100 ISR_XX : SP STAA $00 LDAA #01 STAA 05 VECTOR_XX : ISR_XX : RTI
Reprendre le programme d’arrière plan CCR CCR NOP PC MainLoop : D D NOP BRA *-2 X X STACK Y Y LDAA $100 ISR_XX : SP STAA $00 LDAA #01 STAA 05 VECTOR_XX : ISR_XX : RTI
Application sur STAR12 • Table des vecteurs du MC9S12DP256-B • Autorisation / Inhibition Globale des interruptions • Autorisation /Inhibition Locale pour le PORT H • Exemple sur STAR12 avec CodeWarrior
Extrait du fichier 6812DP256.H /********************************************/ /* PORT H */ /********************************************/ volatileunsignedchar PTH _IO_AT(0x260); volatileunsignedchar PTIH _IO_AT(0x261); volatileunsignedchar DDRH _IO_AT(0x262); volatileunsignedchar RDRH _IO_AT(0x263); volatileunsignedchar PERH _IO_AT(0x264); volatileunsignedchar PPSH _IO_AT(0x265); volatileunsignedcharPIEH _IO_AT(0x266); volatileunsignedcharPIFH _IO_AT(0x267); Autorisation Locale IE Indicateur IF
Exemple de programme avec Interruptions sur STAR12 ///////////////////////////// // DEMO INTERRUPT HC12 // // TARGET = 9S12DP526 // // Compiler = CodeWarrior // ///////////////////////////// #include <hidef.h> // for "EnableInterrupts" macro #include "interrupt.h" // for "PORTH_ISR" macro #include "6812dp256.h" // for 9S12dp256's registers void main(void){ PIEH = 0x0F; // Enable interrupt on port H3-0 PERH = 0xFF; // Enable Pull-Up on Port H DDRA = 0xFF; // Port A OUT (Bargraph) DDRM |= 0xC0; // Port M 7-6 OUT (Bargraph) EnableInterrupts // Idem {__asm CLI;} while(TRUE); // Infinite loop. } interrupt PORTH_ISR // Is vector num 25 void KWH_isr(void){ PTM ^= 0x80; // Toggle Port M bit 7 PIFH = 0xFF; // Write 1s in port H IT falgs // to clear them. } ////////////////////END OF DEMO///////////////// Autorisation Locale Autorisation Globale Boucle Infinie Déclaration ISR Accusé Réception De l’interruption