Ceci est une ancienne révision du document !
Le timer 0 est un compteur 8 bits qui permet de générer un signal PWM. Nous allons utiliser la carte Arduino Duemilanove.
En mode « Fast PWM », le compteur compte de BOTTOM à TOP puis recommence à compter de BOTTOM. Les bits WGM2:0 des registres TCCR0x permettent de définir la valeur de TOP (0xFF ou OCR0x) : WGM2:0 = 3 pour TOP = 0xFF et WGM2:0 = 7 pour TOP = OCR0A.
En mode « Phase correct PWM », le compteur compte de BOTTOM à TOP puis décompte de TOP à BOTTOM. Les bits WGM2:0 des registres TCCR0x permettent de définir la valeur de TOP (0xFF ou OCR0x) : WGM2:0 = 1 pour TOP = 0xFF et WGM2:0 = 5 pour TOP = OCR0A.
Il existe 2 mode possibles pour les sorties OC0x. Les bits COM0x1:0 du registre TCCR0A permettent de configurer ces modes : COM0x1:0 = 2 pour le mode direct et COM0x1:0 = 3 pour le mode inverse.
La figure suivante montre les chronogrammes des signaux TCNT0, OC0A en mode direct et OC0A en mode inverse. TCNT0 est comparé à chaque instant à OCR0x.
En mode direct, la sortie OC0x passe à « 1 » quand TCNT0 < OCR0x et passe à « 0 » quand TCNT0 > OCR0x. En mode inverse, la sortie OC0x passe à « 1 » quand TCNT0 > OCR0x et passe à « 0 » quand TCNT0 < OCR0x.
Il est possible de configurer la fréquence du signal PWM : En mode « Fast PWM », la fréquence est FPWM = FCLK/(N.256) En mode « Phase correct PWM », la fréquence est FPWM = FCLK/(N.510)
N = 1, 8, 64, 256 ou 1024. Les bits CS02:0 du registre TCCR0B permettent de configurer N.
TCCR0A et TCCR0B : registres qui configure le timer 0 en mode PWM. TCNT0 : registre qui contient la valeur du compteur. OCR0A : registre qui contient la valeur référence pour la comparaison avec TCNT0.
L'exemple suivant permet la génération de 2 signaux PWM sur OC0A et OC0B en mode « Phase correct PWM » direct à une fréquence de 31.4 KHz (N=1). TCNT0 compte de 0 à 255. Le seuil sur OCR0A est 127 (PWM de 50% sur OC0A et le seuil sur OCR0B est 64 (PWM de 25% sur OC0B).
/* * pwm.c * * Created on: Mar 7, 2012 * Author: ldo * * arduino duemilanove ATMEGA328P * crystal 16MHz */ #include<avr/io.h> /* TIMER0 */ #define DDR_TIM0 DDRD /* TIMER0 : PORTD */ #define DD_OC0A 6 /* OC0A : PD6 */ #define DD_OC0B 5 /* OC0B : PD5 */ void initTimer0(void) { DDR_TIM0 = (1<<DD_OC0A) | (1<<DD_OC0B); /* set output OC0A and OC0B */ TCCR0A = (1<<COM0A1) | (1<<COM0B1) /* non-inverted PWM output*/ | (1<<WGM00); /* phase correct PWM mode */ TCCR0B = (1<< CS00); /* no prescaling */ PRR &= ~(1<<PRTIM0);/* the PRTIM0 bit must be written to zero to enable timer0 module */ TCNT0 = 0; /* clear Timer/Counter Register */ OCR0A = 127; /* Set Output Compare Register A */ OCR0B = 64; /* Set Output Compare Register B */ } int main(void) { initTimer0(); while(1) { } return 1; }