Enviat per: Matias | 29 Agost 2010

Interrupcions

Ja hem vist el funcionament del rellotge del processador, i també hem parlat de com volem generar el PWM. Però el PWM no s’ha de programar mitjançant retards en el rellotge (amb delays de ms, per exemple), perquè sinó tindrem un bucle que ocuparà gairebé el 100% del temps de processador només esperant, així que s’han d’utilitzar les interrupcions de rellotge.

La idea és modificar l’ample de pols a cada periode del PWM, de manera que acabem generant una sinusoidal com he explicat anteriorment. Per tant cal aconseguir que a cada T (periode) del PWM es generi una interrupció que ens permeti reconfigurar els registres necessaris per modificar l’ample de pols. D’aquesta manera, només ocuparem un temps molt parcial del processador, i podrem utilitzar la resta del temps (que serà molt) per processar les imatges, que és l’altre part que ens falta.

El rellotge té les seves pròpies interrupcions, però resulta que el PWM també porta incorporats uns registres per servir interrupcions a un nivell diferent de les del rellotge, i aquestes són les que hem de tractar. Per utilitzar les interrupcions només hem d’entendre la part de registres que ho configura, i posar els valors correctes:

Primer de tot hem de configurar el periode del PWM. Tenim un preescaler que fa de divisor pels tics de rellotge i el match register és el que marca el final del comptatge. Quan el comptador (que incrementa a cada valor de preescaler) arriba al valor del match register, es produeix l’acció que haguem configurat (es pot resetejar, parar, fer interrupcions…). Per tant primer configurem un periode qualsevol:

REG(PWM0_PR) = 1000;
REG(PWM0_MR0) = 45900;

Amb aquests valors aconseguim més o menys una interrupció cada segon. Perquè el valor de MR0 es faci efectiu, hem d’actualitzar el bit del registre PWM0_LER. Això ho fem posant-ho a 1, ja que és el primer bit del registre.

REG(PWM0_LER) = 1;

Per veure una mica més com funciona, vegem la imatge de blocs de PWM:

L’actualització del Latch Register es necessaria per passar els valors del Match Register X al Shadow Register X, on es farà efectiu el valor que s’utilitzarà per les sortides del PWM que es veuen a la dreta.

Un cop posat el període del PWM, encara hem de configurar un parell de registres més:

REG(PWM0_TCR) = 0x01;

PWM0_TCR serveix per indicar quin us fem dels comptadors. Necessitem posar el primer bit a 1, perquè així el timer i el preescaler s’activen per començar a comptar, sinó estan aturats.

REG(PWM0_MCR) = 0x03;

PWM0_MCR serveix per configurar les accions adients quan es crea un match en els registres de Match del PWM. En el nostre cas, el que volem és que es generi una interrupció, però a més a més, també volem que els comptadors es posin a 0, perquè sinó, no tornaran a fer match mai (o almenys fins que desbordi el comptador i torni a començar…). Així doncs, posem els 2 primers bits a 1 (0x03) de manera que creem interrupció i fem un reset als comptadors cada cop que hi ha un match.

Ara ja tenim configurat el PWM com voliem, però ara necessitem capturar les interrupcions en el software, anem-ho a veure:

El processador té la llibreria de funcions a la carpeta lpc2106-cmucam3. Nosaltres, de tots els fitxers, editarem el “interrupt.c” per proporcionar un punt d’accés al nostre codi. En aquest fitxer, hi ha una rutina “interrupt()” que es genèrica per totes les interrupcions del processador, i allà, comprovant registre per registre, es van determinant de quin tipus de interrupcions es tracten. Així doncs, nosaltres capturarem les interrupcions del PWM, i cridarem una funció que estarà declarada en el nostre codi, de manera que no haurem de modificar mai més el fitxer “interrupt.c”. És el seguent:

if (REG (PWM0_IR) == 0x1) {

pwm_interrupt();
REG (PWM0_IR) = 0x01;

}

Comprovem el registre PWM0_IR, en el bit 0, ja que tractem les interrupcions que genera el match register 0, i si és d’aquest tipus entra i crida la nostra funció pwm_interrupt(). Un cop fet el que volem dins la funció, resetejem el bit d’interrupció per indicar que ja s’ha servit (en el mateix registre IR, posant el bit 0 a 1)  i esperarem a que ens arribi la pròxima.

Finalment en el nostre codi, posem per exemple un flag que ens vagi encenent i apagant un led de la placa a cada interrupció, i veiem clarament com funciona.

La següent part serà veure a quant podem ajustar la freqüència de les interrupcions, que serà en definitiva la resolució de la nostra senyal, i modificar l’ample de pols a cada interrupció.

Anuncis

Deixa un comentari

Fill in your details below or click an icon to log in:

WordPress.com Logo

Esteu comentant fent servir el compte WordPress.com. Log Out / Canvia )

Twitter picture

Esteu comentant fent servir el compte Twitter. Log Out / Canvia )

Facebook photo

Esteu comentant fent servir el compte Facebook. Log Out / Canvia )

Google+ photo

Esteu comentant fent servir el compte Google+. Log Out / Canvia )

Connecting to %s

Categories

%d bloggers like this: