Avant propos :

Ce site contient des informations volontairement partielles, ne s'appliquant en l'état qu'à la programmation des micro-contrôleurs PIC (Microchip) et aux développements dans le cadre du projet intégrateur SyCIMPLE.
M.C.



29.12.2009

Les Timers

Le timer est un compteur binaire : une case mémoire (RAM) qui s'incrémente à chaque front montant ou descendant d'un signal en créneaux de référence, extrait de l'horloge interne du micro ou provenant de l'extérieur par une patte (pin) du composant.

Les opérations de base permises sont : modifier la valeur du timer, lancer le timer (ie autoriser l'incrémentation à chaque front de l'horloge), le stopper. La configuration minimale consiste à fixer la source du signal d'horloge (externe ou interne) et un coefficient de division pour la fréquence de ce signal. (une puissances de 2). Une fois lancé, le timer s'incrémente indéfiniement : il fait passer à 1 un bit d'un registre (un "flag" ou drapeau) lorsqu'il passe de la valeur maximale (255 pour 8 bits) à 0, mais ne s'arrête pas.

Par exemple, pour le PIC18F14K50, le Timer0 est un timer sur 8 ou 16 bits, capable de compter à partir de l'horloge interne ou de la pate T0CKI. Il dispose d'un prescaller (diviseur). Le registre de contrôle de ce timer est T0CON qui comprend les bits suivants :

  • bit7 : TMR0ON: Timer0 On/Off Control bit

1 = Lancement du Timer0
0 = Arrêt du Timer0

  • bit 6 : T08BIT: Timer0 8-bit/16-bit Control bit

1 = Timer0 configuré en 8-bit timer/counter
0 = Timer0 configuré en 16-bit timer/counter

  • bit 5 T0CS: Timer0 Clock Source Select bit

1 = Transition on T0CKI pin : horloge à l'extérieur du pic
0 = Internal instruction cycle clock (CLKOUT) : horloge interne du pic

  • bit 4 : T0SE: Timer0 Source Edge Select bit

1 = Incrementation sur les front descendants de T0CKI pin
0 = Incrementation sur les front montants de T0CKI pin

  • bit 3 : PSA: Timer0 Prescaler Assignment bit

1 = Pas de prescaller (diviseur)
0 = Incrémentation à travers le prescaller

  • bit 2-0 T0PS<2:0>: Timer0 Prescaler Select bits : coefficient de division de l'horloge :

111 = 1:256 prescale value
110 = 1:128 prescale value
101 = 1:64 prescale value
100 = 1:32 prescale value
011 = 1:16 prescale value
010 = 1:8 prescale value
001 = 1:4 prescale value
000 = 1:2 prescale value

Fonctionnement :

Si on choisit l'horloge interne du PIC pour incrémenter le timer, alors on compte des incréments de TEMPS, on peut donc mesurer des durées.

Si on utilise la patte avec un signal externe, on peut soit mesurer des durées, soit compter des évènements. (D'ou le nom timer/compteur).

Admettons que l'on veuille mesurer des durées : on configure donc par exemple, bit 4 et 5 à 0. Il faut ensuite avoir une bonne idée de la valeur des durées que l'on souhaite mesurer pour configurer  T0CON. Supposons que la durée qui nous intéresse soit de l'ordre de 1 ms. L'horloge du pic étant fixée à 20MHz, le signal brute de l'horloge qui attaque le Timer0 est de Fosc/4, soit 5MHz.... Entre deux front descendant ou montant du signal d'horloge, il s'écoulera donc 200ns. On remarque tout de suite que 256x200ns = 51µs, c'est la période maximale que l'on peut "générer" avec ce timer sans utiliser de diviseur (durée entre deux débordement sur 8 bits). Si on divise l'horloge par 256, on peut donc avoir 13,107200 ms entre deux débordement : c'est plus qu'il nous en faut !

Conclusion :

On fixe les bits 0,1,2 de T0CON à 1 et le bit 3 à 0. On met (256-13) = 243 dans Timer0 et on lance le timer en faisant passer le bit 7 de T0CON à 1, on aura alors un passage à 1 du flag TMR0IF au bout de 1,008ms (à peu près), il faut donc tester cet évènement régulièrement dans le programme pour l'utiliser. On peut aussi utiliser l'interruption générée par ce timer, il se produira alors une interruption toutes les 1,008 ms ce qui dispense de faire un test dans le programme... Ce n'est cependant pas la seule solution... (utiliser un timer 16bits ?)

Le temps de cycle

C'est la période du signal que fournit l'horloge. C'est en général une période fixé par un composant externe : quartz, oscillateur piezo-électrique, horloge externe ou réseau résistance-condensateur (qui impose donc une fréquence fixe F). Sur certains composants comme le PIC18F14K50, elle est générée par un organe interne ce qui permet de l'ajuster dans le code programme (en configurant une fréquence de base et ensuite ce qu'on appelle un préscaller = diviseur).

Ce qu'il faut retenir, c'est que cette horloge cadence tout ce qui se passe dans le microcontrôleur : de l'exécution d'une instruction à l'incrémentation d'un Timer. C'est la base par exemple pour calculer le temps mis par le µC pour exécuter un seule instruction du programme (en assembleur). En général pour un PIC (Microchip), il faut 4 temps de cycle pour exécuter un instruction simple (ie qui ne demande pas de test).

Exemple : sur un PIC16F876 connecté à un quartz de 4MHz, Tcy=1/4000000=250ns, il faut donc 4x250 = 1ms pour qu'une instruction simple soit exécutée. De plus, si on utilise un Timer, l'incrémentation maximale sera dans ce cas d'une unité toutes les 250ns.

25.12.2009

Les périphériques

USART, PWM, E/S, Timer, RTC, ADC, ECCP, etc... bienvenue dans le monde des périphériques !

Les périphériques sont des entités (ie physique) à peu près autonomes situées à l'intérieur du micro-contrôleur et permettant soit un dialogue avec l'extérieur (PORT E/S, USB, etc...) soit un traitement du temps (Timer, RTC). Des registres internes et des interruptions leurs sont systématiquement associés ainsi qu'une ou plusieurs pattes du composant (pin) permettant d'interagir directement avec le monde extérieur.

Les plus courants sont :

  • USART ou EUSART : émetteur-récepteur synchrone-asynchrone, soit le périphérique de communication série le plus universel (dialogue avec les PC, des robots, entre autre...)
  • ADC : convertisseur analogique->numérique
  • RTC : real time clock
  • SPI : communication série mono fil.
  • PWM : MLI en français, modulation de largeur d'impulsion

 

En général, les registres (case mémoire volatile : RAM) associés comprennent :

  • un ou plusieurs registres contenant la donnée "utile"
  • un ou plusieurs registres de configuration du périphérique
  • un registre contenant des flags (drapeaux indiquant le déroulement des opérations)
  • un registre contrôlant la ou les interruptions associées

 

Par exemple dans le cas d'un PIC (Microchip) 18F14K50, prenons le périphérique EUSART employé en émission et réception de données série (RS232 par exemple) :

  • PIE1* : registre qui contrôle le déclenchement des interruptions (Interrup Enable)
  • PIR1* : registre qui contrôle les flags du périphérique
  • IPR1* : registre qui contrôle les priorités des interruptions
  • INTCON* : registre qui contrôle les demandes d'interruptions
  • RCSTA : registre du statut de la réception des données
  • RXSTA : registre du statut de l'envoi des données
  • RCREG : registre contenant la donnée à envoyer
  • RXREG : registre contenant la donnée reçue
  • BAUDCON : registre de configuration de la vitesse de transmission
  • SPBRGH : registre contenant l'octet de poids fort de la vitesse de transmission
  • SPBRG : pareil pour l'octet de poids faible

A noter : ces registres (*) ne sont pas associés spécifiquement à ce périphérique, mais utilisés de façon globale par le micro contrôleur.

L'utilisation de ces modules autonomes permet de décharger le code (programme) du traitement des tâches afférentes. Bien souvent, il est en effet possible de programmer tout ou partie d'un périphérique mais pendant le traitement de cette portion de code, on ne peut rien exécuter d'autre (sauf en utilisant intelligemment des interruptions). Il est des cas ou on ne peut faire autrement, par exemple lorsque les pattes correspondantes à une interface qui nous intéresse (USART, I²C, etc...) sont déjà utilisées par une autre fonction. Très concrètement, si l'on veut utiliser deux port de communications séries sur le même micro-contrôleur, il faut soit choisir un µC qui contient deux USART, soit en coder un des deux.