Interface logicielle (API) - Timers, Compteurs, PWM

De Wiki Techno-Innov
< Technique‎ | Logiciel‎ | API‎ | Use‎ | Drivers
Sauter à la navigation Sauter à la recherche


Présentation

#include "drivers/timers.h"

L'implémentation du support des timers a été découpée en deux parties pour en simplifier l'utilisation : une partie commune à tous les types de timers, qui représente l'interface d'utilisation des timers dans cette API, et une partie spécifique à chaque type de timer, abstraite par cette API, et dont l'utilisateur n'a pas besoin de se préoccuper s'il n'a pas de contraintes extrêmement précises et spécifique au type de timer présent sur le micro-contrôleur. (Dans le cas contraire il pourra s'inspirer du code spécifique comme base pour son implémentation).

Le fichier d'entête "drivers/timers.h" définit le nombre de timers présents, et le nombre maximum de canaux (channels) disponibles, ainsi que les noms des timers disponibles (en fait un numéro).

#define NUM_TIMERS
#define MAX_CHANNELS

/* Timer numbers to be used for functions from this driver. */
enum lpc_timers {
   [....]
};

les fichiers d'entête spécifiques à chaque type de timer définissent d'autres valeurs spécifiques, et sont inclus directement par le fichier d'entête "drivers/timers.h".

Le premier paramètre de toutes les fonctions relatives à l'utilisation des timers est toujours ce nom de timer ('timer_num'). Voir la sous-section "Spécificités liées aux différents micro-contrôleurs" ci-dessous pour les nom des timers présents pour chaque micro-contrôleur.

Avant toute utilisation, chaque timer doit être initialisé et configuré. Il peut ensuite être démarré, arrêté, mis en pause, ou remis à zéro à l'aide des fonction correspondantes.

Toutes les fonctions qui renvoient un entier renvoient 0 en cas de succès, ou une valeur négative correspondant à un code d'erreur en cas d'erreur. Voir la liste des codes d'erreur supportés dans le fichier d'entête "lib/errno.h".

Initialisation

int timer_on(uint8_t timer_num, uint32_t clkrate, void (*callback)(uint32_t));
int timer_off(uint8_t timer_num);

Avant toute utilisation ou configuration un timer doit être initialisé avec la fonction timer_on().
Comme pour toutes les autres fonctions, le premier paramètre est le nom du timer (numéro compris entre 0 et NUM_TIMERS).
Le paramètre 'clkrate' est utilisé pour configurer le "prescaler" et ainsi diviser l'horloge principale pour que le timer compte moins vite. Si 'clkrate' vaut 0 le prescaler n'est pas utilisé. Il est aussi possible de spécifier une valeur spécifique pour le prescaler lors de la configuration en mode "compteur timer".
Le paramètre 'callback' permet d'enregistrer un callback pour ce timer, qui sera appelé si un événement du timer (match ou capture) est configuré pour générer une interruption.

La fonction timer_off() désactive le timer sélectionné soit en désactivant l'horloge associée, soit en coupant son alimentation, selon le fonctionnement interne du micro-contrôleur.

Configuration initiale

La configuration des timers se fait par l'une des fonctions timer_pwm_config() ou timer_counter_config() selon le mode de fonctionnement désiré.
Chaque mode de fonctionnement dispose d'une structure spécifique pour la configuration du timer.

Configuration en mode "Timer / Compteur"

int timer_counter_config(uint8_t timer_num, const struct lpc_tc_config* conf);

struct lpc_tc_config
   uint16_t mode;
   uint32_t prescale_val;
   uint8_t count_control;
   uint8_t count_chan;
   uint8_t reset_on_cap;
   uint8_t match_control[NUM_CHANS];
   uint32_t match[NUM_CHANS];
   uint8_t ext_match_config[NUM_CHANS];
   uint8_t cap_control[NUM_CHANS];

};

La configuration en mode compteur ou timer permet d'accéder aux fonctionnalités "match" et "capture" des timers. L'incrémentation du compteur peut se faire soit par l'horloge interne, soit par l'une des entrées "capture" du micro-contrôleur. Le fonctionnement précis du timer est configuré à l'aide de la structure "lpc_tc_config" passée par le paramètre 'conf'. Les fonctions des champs de la structure "lpc_tc_config" sont détaillées ci-dessous.
les champs 'match_control[]', 'match[]', 'ext_match_config[]' et 'cap_control[]' sont des tableaux, avec une entrée pour chaque canal du timer. Le entrées correspondant aux canaux non utilisés sont laissées à 0.

  • Le champ 'mode' permet de préciser le mode de fonctionnement désiré. Il s'agit d'un masque entre les valeurs suivantes :
LPC_TIMER_MODE_TIMER ou LPC_TIMER_MODE_COUNTER
Une seule des deux valeurs possible
LPC_TIMER_MODE_CAPTURE
Active les fonctionnalités de capture décrites dans le champ cap_control[]
LPC_TIMER_MODE_MATCH
Active les fonctionnalités de "match" décrites dans les champs match_control[], match[] et ext_match_config[]
  • Si il est non nul, le champ 'prescale_val' permet de remplacer la valeur calculée lors de l'appel à timer_on(). Si 'prescale_val' vaut 0 la valeur actuelle du "prescaler" est conservée.
  • Le champ 'count_control' définit quels fronts de l'entrée "CAP" sélectionnée par le champ 'count_chan' incrémentent le compteur. Ce champ est ignoré en mode "timer". Les valeurs possibles sont les suivantes :
LPC_COUNTER_INC_ON_RISING
LPC_COUNTER_INC_ON_FALLING
LPC_COUNTER_INC_ON_BOTH
  • Le champ 'count_chan' définit quelle entrée "CAP" est utilisée pour incrémenter le compteur en mode "compteur". Ce champ est ignoré en mode "timer".
  • Le champ 'reset_on_cap' permet d'activer la fonctionnalité de ré-initialisation du compteur sur événement extérieur ("CAP"). Cette fonctionnalité simplifie la mesure de durée d'une impulsion. Ce champ doit contenir la valeur "LPC_COUNTER_CLEAR_ON_EVENT_EN" ajouté à l'une des valeurs "LPC_COUNTER_CLEAR_ON_***" (*** est à remplacer par CHAN0_RISE, CHAN0_FALL, CAHN1_RISE, ..., CHAN3_FALL).
  • Chaque valeur du tableau 'match_control[]' est une combinaison des valeurs suivantes servant à configurer le fonctionnement "interne" du timer lors des événements "match" :
LPC_TIMER_INTERRUPT_ON_MATCH
Une interruption est générée quand le compteur atteins la valeur "match" du canal correspondant.
LPC_TIMER_RESET_ON_MATCH
Le compteur est remis à 0 quand le compteur atteins la valeur "match" du canal correspondant.
LPC_TIMER_STOP_ON_MATCH
Le compteur est arrêté quand le compteur atteins la valeur "match" du canal correspondant.
LPC_TIMER_INT_RESET_AND_STOP_ON_MATCH
Combinaison des trois valeurs précédentes.
  • Le tableau 'match[]' contient les valeurs à placer dans les registres "match" correspondants pour permettre le déclenchement d'événements lorsque le compteur du timer atteins la valeur correspondante.
  • Les valeurs du tableau 'ext_match_config[]' servent à définir le comportement "extérieur" du timer lors des événements "match". Il s'agit d'une des valeurs suivantes:
LPC_TIMER_NOTHING_ON_MATCH
LPC_TIMER_CLEAR_ON_MATCH
LPC_TIMER_SET_ON_MATCH
LPC_TIMER_TOGGLE_ON_MATCH
  • Les valeurs du tableau 'cap_control[]' servent à définir les événements déclenchés par le changement d'état le l'entrée "capture" correspondante. Il s'agit d'une combinaison des valeurs suivantes:
LPC_TIMER_CAP_ON_RISING_EDGE
La valeur actuelle du compteur est copiée dans le registre "capture" du canal correspondant lors d'un front montant.
LPC_TIMER_CAP_ON_FALLING_EDGE
La valeur actuelle du compteur est copiée dans le registre "capture" du canal correspondant lors d'un front descendant.
LPC_TIMER_INTERRUPT_ON_CAPTURE
Une interruption est générée lorsque le registre capture correspondant est chargé avec la valeur actuelle du compteur.

Note :
Les entrées "capture" et les sorties "match" doivent être configurées à l'aide des fonctions pio_config() ou set_pins() (Voir le chapitre sur la configuration des ports d'entrée/sortie).

Configuration en mode PWM (Pulse Width Modulation)

int timer_pwm_config(uint8_t timer_num, const struct lpc_timer_pwm_config* pwm_conf);

struct lpc_timer_pwm_config {
   uint8_t nb_channels;
   uint8_t period_chan;
   uint32_t period;
   uint8_t outputs[MAX_CHANNELS];
   uint32_t match_values[MAX_CHANNELS];
   uint32_t outputs_initial_state;
};

La configuration en mode PWM permet d'accéder aux fonctionnalités "Pulse Width Modulation" des timers. L'incrémentation du compteur est obligatoirement faire par l'horloge interne (avec utilisation ou non du prescaler quand il est disponible).
Le fonctionnement précis du timer en mode PWM est configuré à l'aide de la structure "lpc_pwm_config" passée par le paramètre 'conf'. Les fonctions des champs de la structure "lpc_pwm_config" sont détaillées ci-dessous.
les champs 'outputs[]' et 'match_values[]' sont des tableaux.

  • Le champ 'nb_channels' définit combien de sorties PWM sont utilisées.
  • Le champ 'period_chan' définit quel canal est utilisé pour générer la période. Certains micro-contrôleurs ignorent ce champ.
  • Le champ 'period' définit la période du cycle PWM, en nombre de cycles d'horloge du timer.
  • Le tableau 'outputs[]' contient les numéros des sorties correspondantes aux valeurs présentes dans le tableau 'match_values[]'
  • Le tableau 'match_values[]' contient les valeurs permettant de contrôler le rapport cyclique des sorties PWM. Chaque valeur est reliée à la sortie définie dans le tableau outputs[] pour l'indice correspondant. Ces valeurs doivent être inférieures à la valeur du champ 'périod'. Il s'agit de la valeur du compteur à laquelle la sortie changera d'état.
  • Le champ 'outputs_initial_state' permet de définir l'état initial des sorties PWM lorsque le micro-contrôleur le permet Chaque bit correspond à l'état initial de la sortie correspondante (bit 0 pour la sortie 0, bit 1 pour la sortie 1, ....). L'ordre correspond au numéro des sorties et non pas à l'ordre dans le tableau 'outputs[]'. L'état initial des sorties inutilisées est sans importance.

Note :
Les sorties "match" doivent être configurées à l'aide des fonctions pio_config() ou set_pins() (Voir le chapitre sur la configuration des ports d'entrée/sortie).

Utilisation

Contrôle du compteur

void timer_start(uint8_t timer_num);
void timer_continue(uint8_t timer_num);
void timer_pause(uint8_t timer_num);
void timer_stop(uint8_t timer_num);
void timer_halt(uint8_t timer_num);
void timer_restart(uint8_t timer_num);

Ces fonctions permettent de contrôler le compteur correspondant au timer sélectionné.

  • timer_start() permet de démarrer un timer qui n'a pas encore compté ou a été stoppé ou de reprendre le compte sans remise à zéro si le timer a été mis en pause.
  • timer_continue() permet de reprendre le compte sans remise à zéro après que le timer ait été mis en pause.
  • timer_pause() permet de mettre en pause un timer sans changer la valeur du compteur.
  • timer_stop() et timer_halt() permettent d'arrêter un compteur, en remettant la valeur du compteur à 0.
  • timer_restart() permet de reprendre le compte à zéro sans interrompre le compte. Si le timer était en pause, il est redémarré.

Lecture des valeurs actuelles

int timer_get_counter_val(uint8_t timer_num, uint32_t* val);
int timer_get_capture_val(uint8_t timer_num, uint8_t channel, uint32_t* val);

Ces fonctions permettent de récupérer la valeur actuelle du compteur pour timer_get_counter_val() ou de la dernière capture effectuée sur le canal 'channel' pour timer_get_capture_val(). La valeur demandée est placée à l'adresse pointée par 'val'.

Changement des valeurs "match"

int timer_set_match(uint8_t timer_num, uint8_t channel, uint32_t val);

La fonction timer_set_match() permet de remplacer la valeur du registre "match" par la valeur 'val' pour le canal 'channel'.
cette fonction permet notamment de changer la période ou le rapport cyclique d'une sortie lors du fonctionnement en PWM.

Spécificités liées aux différents micro-contrôleurs

LPC82x

  • Nombre de timers: 4
  • Modes de fonctionnement :
  • Nom des timers :
LPC_SCT
LPC_SCT16_T0
LPC_SCT16_T1
LPC_MRT
  • État initial des sorties PWM : configurable par sortie.
  • Paramètre 'period_chan' ignoré. Aucun canal de sortie utilisé pour la gestion de la période.

LPC11A04

  • Nombre de timers :
  • Modes de fonctionnement :

LPC122x

  • Nombre de timers : 4
  • Modes de fonctionnement : Timer/Counter et PWM
  • Nom des timers :
LPC_TIMER_16B0
LPC_TIMER_16B1
LPC_TIMER_32B0
LPC_TIMER_32B1
  • État initial des sorties PWM : 0 (état bas).

LPC176x

  • Nombre de timers :
  • Modes de fonctionnement :