Utiliser les PIC 16F et 18F/Le mode PWM du module CCP (Capture Compare PWM)

Leçons de niveau 16
Une page de Wikiversité, la communauté pédagogique libre.
Début de la boite de navigation du chapitre
Le mode PWM du module CCP (Capture Compare PWM)
Icône de la faculté
Chapitre no 12
Leçon : Utiliser les PIC 16F et 18F
Chap. préc. :Le mode capture du module CCP (Capture Compare PWM)
Chap. suiv. :Sommaire

Exercices :

Le mode PWM du module CCP (Capture Compare PWM)
fin de la boite de navigation du chapitre
En raison de limitations techniques, la typographie souhaitable du titre, « Utiliser les PIC 16F et 18F : Le mode PWM du module CCP (Capture Compare PWM)
Utiliser les PIC 16F et 18F/Le mode PWM du module CCP (Capture Compare PWM)
 », n'a pu être restituée correctement ci-dessus.

PWM signifie « Pulse Width Modulation », ce qu’on pourrait traduire par modulation de largeur d’impulsion. Son objectif est de changer une valeur moyenne en jouant sur le rapport cyclique. Puisque ce module utilise essentiellement le timer 2, nous commençons donc à le décrire.

Description du timer 2[modifier | modifier le wikicode]

Le timer 2 est identique sur le PIC® 16F877 et le 18F4550. Il s'agit d'un timer 8 bits dont la description schématique est présentée maintenant.

Documentation interne du timer2

Sa seule entrée est l'entrée horloge du PIC® divisée par 4 suivie d'un pré-diviseur géré par deux bits. Un comparateur donne un signal qui sert de reset au timer2 et d'entrée à un post-diviseur capable de diviser par un nombre entre 1 et 16.

Fonctionnement du timer 2[modifier | modifier le wikicode]

  • On part du quartz car il s'agit d'un timer. Il est comme d'habitude divisé par 4, puis passe dans un nouveau diviseur programmable qui utilise les bits T2CKPS1 et T2CKPS0 du registre T2CON.
  • On arrive ensuite à un ET logique qui laisse entendre que l’on peut couper cette horloge qui arrive au Timer2 (le timer 2 peut s'arrêter). Cela se fait à l'aide du bit TMR2ON du registre T2CON.
  • Ce timer utilise son propre dispositif de comparaison : sa valeur est sans cesse comparée au registre PR2.
  • La comparaison est ensuite "filtrée" par les bits TOUTPS3 ... TOUTPS0 du registre T2CON.
  • Cette comparaison filtrée aboutit au bit TMR2IF du registre PIR1.
  • Remarquez aussi que cette comparaison réalise un reset du timer 2 (avant le "filtrage").

La période T peut être calculée par :

T = (PR2 + 1) x (Timer2 input clock period) soit :


Les bits des registres concernés avec le compilateur Hitech C[modifier | modifier le wikicode]

Comme d'habitude, on cherche les valeurs des bits des registres T2CON et PIR1 à l'aide des fichiers d'inclusion :

/* Definitions for T2CON register */
               bit	T2CKPS0		@ ((unsigned)&T2CON*8)+0;
               bit	T2CKPS1		@ ((unsigned)&T2CON*8)+1;
               bit	TMR2ON		@ ((unsigned)&T2CON*8)+2;
               bit	TOUTPS0		@ ((unsigned)&T2CON*8)+3;
               bit	TOUTPS1		@ ((unsigned)&T2CON*8)+4;
               bit	TOUTPS2		@ ((unsigned)&T2CON*8)+5;
               bit	TOUTPS3		@ ((unsigned)&T2CON*8)+6;

/* Definitions for PIR1 register */
volatile       bit	TMR1IF		@ ((unsigned)&PIR1*8)+0;
volatile       bit	TMR2IF		@ ((unsigned)&PIR1*8)+1;
volatile       bit	CCP1IF		@ ((unsigned)&PIR1*8)+2;
volatile       bit	SSPIF		@ ((unsigned)&PIR1*8)+3;
volatile       bit	TXIF		@ ((unsigned)&PIR1*8)+4;
volatile       bit	RCIF		@ ((unsigned)&PIR1*8)+5;
volatile       bit	ADIF		@ ((unsigned)&PIR1*8)+6;

Le PWM[modifier | modifier le wikicode]

Quand on s'intéresse au PWM le choix de la période est réalisé simplement comme dans l'exercice 1. Puisque le timer2 est sur 8 bits, la résolution de la période est de 256. Le choix du rapport cyclique est par contre défini par le contenu d'un registre 8 bits CCPR1L avec deux bits supplémentaires DC1B1 et DC1B0. Ceci est montré dans la documentation ci-contre. Nous allons donner quelques explications.

Documentation complète du PWM
  • On utilise le timer 2 et son RESET par comparaison. Cela permet d’avoir une période constante.
  • Le timer 2 est donc l'élément central. Il est sur 8 bits mais on voit facilement sur le schéma qu'on lui a ajouté 2 bits supplémentaires pour en faire une valeur sur 10 bits.
  • Ces deux bits ajoutés sont pilotés directement par le quartz et, chose exceptionnelle, sans passer par le diviseur par 4 (flèche rouge du dessin).
  • On a donc maintenant une valeur du timer2 sur 10 bits. Pour simplifier les explications, on appellera cette valeur timer2_10b.
  • La valeur timer2_10b est comparée (on discutera avec quoi un peu plus tard) et le résultat de cette comparaison va sur un reset. Autrement dit nos 10 bits gèrent ton.

Arrivé à ce point, on sait que la période se gère sur 8 bits (comparaison avec PIR2), tandis que ton se gère sur 10 bits. C'est tout à fait normal quand on y réfléchit car on a besoin de peu de précision pour la période (d'un hacheur par exemple) mais de beaucoup de précision pour le rapport cyclique. En effet, c’est ce rapport cyclique qui gère la vitesse et augmenter sa résolution revient à augmenter la précision de gestion de la vitesse.

Mais continuons nos explications.

  • La comparaison de timer2_10b se fait avec CCPR1H (8 bits) auxquels on a ajouté 2 bits. Pour comprendre d'où viennent ces deux bits il nous faut comprendre comment on écrit dans CCPR1H ?
  • L'écriture dans CCPR1H se fait à l'aide de CCPR1L (registre 8 bits) auquel on ajoute deux bits DC1B1 et DC1B0 du registre CCP1CON. Le passage des valeurs de CCPR1L vers CCPR1H ne se fait qu'après une comparaison de tmer2_10b, c'est-à-dire à la fin d'un ton (flèche verte sur le dessin).
  • On peut remarquer aussi que la sortie générale de tout cela se fait dans le bit RC2 de PORTC.

Le PWM ne fonctionnera correctement que si .

La formule permettant de calculer est :




Librairie Mikro C[modifier | modifier le wikicode]

Prototype :

          void Pwm_Init(long freq);

Exemple :

        Pwm_Init(5000); // Initialize PWM module at 5KHz

Prototype :

          void Pwm_Change_Duty(char duty_ratio);

Description :

           Changes PWM duty ratio. Parameter duty_ratio takes values from 0 to 255, where 0
           is 0%, 127 is 50%, and 255 is 100% duty ratio. Other specific values for duty ratio can
           be calculated as (Percent*255)/100.

Exemple :

        Pwm_Change_Duty(192); // Set duty ratio to 75%

Prototype :

          void Pwm_Start(void);

Prototype :

          void Pwm_Stop(void);

Exemple[modifier | modifier le wikicode]

/*The example changes PWM duty ratio on pin RC2 continually. If LED is connected
to RC2, you can observe the gradual change of emitted light. */
char i = 0, j = 0;
void main() {
  PORTC = 0xFF;           // PORTC is input
  Pwm_Init(5000);         // Initialize PWM module at 5KHz
  Pwm_Start();            // Start PWM
  while (1) {
    // Slow down, allow us to see the change on LED:
    for (i = 0; i < 20; i++) Delay_us(500);
    j++;
    Pwm_Change_Duty(j);   // Change duty ratio
  }
}