Informatique embarquée Gestion des temporisations créées par programme
Problématique Comment faire une temporisation avec un micro-contrôleur simplement? Le but est de «consommer» du temps «inutilement» Le moyen le plus simple d'y arriver est d'exécuter un grand nombre d'instructions qui n'ont pas d'influence sur le fonctionnement du programme d'une manière générale. En C, cela passe par une boucle.
Problématique Fonction de temporisation en C : Rôle de cette fonction : attendre un certain temps Par exemple 0,5 seconde. Prototype : void tempo(void) ; Une tempo d'une durée fixe n'a pas de paramètre d' entrée, ni de valeur de sortie. Contenu de cette fonction : Que faut-il écrire dans cette fonction?
Fonction tempo() Boucle «for» : for(i=0;i<???;i++)??? Type de la variable «i»? Prenons par exemple un «int» Valeur maximale? Que faut-il mettre dans cette boucle? Comment connaître le temps pris par cette boucle? Il faut compiler et tester...
Fonction tempo() Boucle «for» : Variable «i» de type «int» for(i=0;i<127;i++) Voir Exemple1 sur MPLAB Environ 1 ms for(i=0;i<128;i++) Voir Exemple1 sur MPLAB Que se passe-t-il?
Fonction tempo() Boucle «for» : Variable «i» de type «uns16» Quelle est la valeur max que peut prendre «i»? for(i=0;i<35000;i++) Voir Exemple1 sur MPLAB Environ 490 ms 0.5s Pouvions-nous prévoir cette durée? Pour i MAX = 127 environ 1 ms Pour i MAX = 35000 environ 0.5s 35000 / 127 = 276...
Fonction tempo() Boucle «for» : D'où sort cette écart? C'est le compilateur qui détermine les instructions en assembleur à exécuter pour réaliser la boucle. Une variable sur 2 octets est plus complexe (donc plus long) à gérer que sur 1 octet...
Fonction tempo() : variantes Durées fixes (environ 0.5s) Durée variable void tempo (void) uns16 i; for (i=0; i < 35000; i++); void tempo (void) uns16 i = 0; do i++ ; while (i<35000) ; void tempo (void) uns16 i = 0; while (i<35000) i++ ; void tempo (uns16 X) // à faire en TP!
Langage C / Langage assembleur Comment ces programmes sont-ils «traduits» pour être exécutés par le micro-contrôleur? Regardez dans la documentation constructeur du PIC16F887 : aucun programme en langage C n apparaît C'est normal, ce n'est pas le langage que comprend ce composant! Le seul qu'il connaisse, c'est l'assembleur. L'assembleur est le langage qui permet de réaliser des opérations qui touchent directement le matériel (l'alu, les mémoires, les registres, etc) C'est un langage de bas niveau.
Langage C / Langage assembleur Le but de la phase de compilation du programme est précisément de traduire des instructions en langage C vers des instructions en assembleur, qui seront ensuite exprimées en code binaire. Pour connaître le temps d'exécution d'un code écrit en langage C, il est donc nécessaire de regarder comment celui-ci a été traduit en assembleur.
Traduction en assembleur Programme en C void tempo (void) uns8 i; for (i=0; i < 254; i++); void main (void) tempo(); Traduction en assembleur Carry EQU 0 RP0 EQU 5 RP1 EQU 6 i EQU 0x20 GOTO main tempo BCF 0x03,RP0 BCF 0x03,RP1 CLRF i m001 MOVLW 254 BCF 0x03,RP0 BCF 0x03,RP1 SUBWF i,w BTFSC 0x03,Carry GOTO m002 INCF i,1 GOTO m001 m002 RETURN main CALL tempo SLEEP GOTO main END
Traduction en assembleur Temps mis par ce programme : (Les temps de cycle sont visualisable dans la documentation du PIC à la page 232) Programme en assembleur Temps de cycle CALL tempo 2 cycles tempo BCF 0x03,RP0 BCF 0x03,RP1 CLRF i m001 MOVLW 254 BCF 0x03,RP0 BCF 0x03,RP1 SUBWF i,w BTFSC 0x03,Carry GOTO m002 INCF i,1 GOTO m001 m002 RETURN 1 cycle 1 cycle 1 cycle 1 cycle 1 cycle 1 cycle 1 cycle 1cycle ou 2 cycles 2 cycles 1 cycle 2 cycles 2 cycles La boucle est faite 254 fois ( pour i=0, pour i =1 pour i =253) La boucle est commencée une 255 FOIS mais elle passe par la ligne GOTO m002
Traduction en assembleur Temps mis par ce programme : 5 cycles ( lignes CALL tempo, BCF 3,RP0, BCF 3,RP1 et CLRF i) + 254 * 9 cycles ( contenu de la boucle) + 1 * 7 cycles ( lignes MOVLW 254,BCF, BCF, SUBWF, BTFSC, GOTO m002) + 2 cycles ( ligne RETURN) Soit 2300 cycles Le temps d'une instruction est égal à 4 temps de cycle du quartz. Notre quartz est à 4MHz donc notre temps de cycle est de 1µs (fosc /4). Soit 2300 μs
Traduction en assembleur Traduction en assembleur Carry EQU 0 RP0 EQU 5 RP1 EQU 6 i EQU 0x20 GOTO main tempo BCF 0x03,RP0 BCF 0x03,RP1 CLRF i m001 MOVLW 254 BCF 0x03,RP0 BCF 0x03,RP1 SUBWF i,w BTFSC 0x03,Carry GOTO m002 INCF i,1 GOTO m001 m002 RETURN main CALL tempo SLEEP GOTO main END La variable «i» est stockée dans la case mémoire d'adresse 0x20 On saute au programme principal On fait appel à la fonction tempo On efface la variable «i» On rentre dans une boucle : On charge 254 dans W On soustrait W à i On teste si le bit Carry vaut 0. Si c'est le cas, l'instruction suivante est ignorée et on incrémente «i», puis on reboucle. Si i=254, l'instruction GOTO m002 est exécutée et on sort de la fonction (RETURN)
Rôle du compilateur Le compilateur joue un grand rôle sur le programme généré en assembleur et donc sur le temps mis par une fonction. Dans les deux programmes en C ci-dessous, nous avons modifié la valeur max de i, et le programme en assembleur se trouve changé. void tempo (void) uns8 i; for (i=0 ;i < 255; i++); void main (void) tempo(); void tempo (void) uns8 i; for (i=0 ;i < 254; i++); void main (void) tempo();
Rôle du compilateur void tempo (void) uns8 i; for (i=0 ;i < 255; i++); void tempo (void) uns8 i; for (i=0 ;i < 254; i++); void main (void) tempo(); tempo m001 m002 main GOTO main BCF 0x03,RP0 BCF 0x03,RP1 CLRF i BCF 0x03,RP0 BCF 0x03,RP1 INCF i,w BTFSC 0x03,Zero_ GOTO m002 INCF i,1 GOTO m001 RETURN CALL tempo SLEEP GOTO main END void main (void) tempo(); GOTO main tempo BCF 0x03,RP0 BCF 0x03,RP1 CLRF i m001 MOVLW 254 BCF 0x03,RP0 BCF 0x03,RP1 SUBWF i,w BTFSC 0x03,Carry GOTO m002 INCF i,1 GOTO m001 m002 RETURN main CALL tempo SLEEP GOTO main END Temps = 2053µs Temps = 2300µs
Utilisation de MPLABSIM Simulateur sous MPLAB N'a pas besoin de kit pour fonctionner Permet de connaître les temps d'exécution d'une fonction ou d'un bout de programme Démo sous MPLAB Prenez des notes! Cela pourra vous servir beaucoup pour debugger vos programmes en TP...
Utilisation de MPLABSIM Programme de test : void tempo(void) uns8 i ; for(i=0;i<254;i++) ; void main(void) TRISB=0xF0 ; tempo() ; PORTB=0x01 ; while(1) ;