Module 9Módulo 9

TimersTemporizadores

A counter in hardware that keeps time so the CPU does not have to. Un contador en hardware que mide el tiempo para que la CPU no tenga que hacerlo.

Santi Scagliusi, PhD

Where we are goingA dónde vamos

An LED that blinks while the CPU sleeps.Un LED que parpadea mientras la CPU duerme.

        mov.w #49, &TA0CCR0
        mov.w #CCIE, &TA0CCTL0
        mov.w #TASSEL__ACLK|MC__UP|TACLR, &TA0CTL
dormir  bis.w #LPM3|GIE, SR   ; zzz
        nop
        jmp   dormir
TA00ISR xor.b #BIT0, &P1OUT   ; LED1
        reti
WatchObserva

TA0R ramps 0→49. Every wrap: one interrupt, one LED toggle. The PC stays still in between.TA0R sube 0→49. Cada vuelta: una interrupción, una conmutación. Entre medias el PC no se mueve.

PausePausa

Who is keeping time if the CPU is asleep?Si la CPU duerme, ¿quién lleva la cuenta?

▶ SimulatorSimulador · M9 · Demo: LED por interrupción (CPU dormida)

Why a hardware timerPor qué un temporizador en hardware

Same wait. One way burns the CPU through it, the other sleeps.La misma espera. Una forma quema la CPU durante ella, la otra duerme.

delay loopbucle de retardo CPU spins at full speedCPU girando a tope ~100 µA @1MHz hardware timertimer en hardware CPU asleep · LPM3CPU dormida · LPM3 timer counts on its own clockel timer cuenta con su propio reloj wakedespierta 0.9 µA

Same wait: about 100 µA spinning, under 1 µA asleep. La misma espera: unos 100 µA girando, menos de 1 µA dormida.

The timers on the FR6989Los temporizadores del FR6989

Four Timer_A instances plus one Timer_B. All 16-bit counters.Cuatro instancias de Timer_A más un Timer_B. Todos contadores de 16 bits.

MSP430FR6989 peripheral space 0x0100–0x0FFFespacio de periféricos 0x0100–0x0FFF WE USEUSAMOS TA0 3 channels3 canales 0x0340 TA1 3 ch · 0x03803 can · 0x0380 TA2 2 ch · 0x04002 can · 0x0400 TA3 5 ch · 0x04405 can · 0x0440 TB0 Timer_B · 7 ch double-buffered · 0x03C0Timer_B · 7 can doble buffer · 0x03C0 five timer modules · all 16-bit counterscinco módulos de timer · todos contadores de 16 bits

All five share the same programming model. Learn TA0 and the rest follow. Los cinco comparten el mismo modelo de programación. Aprende TA0 y el resto se deduce.

Inside Timer_ADentro del Timer_A

A clock feeds a divider, which feeds the 16-bit counter TAxR. The mode decides how it counts.Un reloj alimenta un divisor, que alimenta el contador de 16 bits TAxR. El modo decide cómo cuenta.

TASSEL
TACLK
ACLK
SMCLK
INCLK
clock sourcefuente de reloj
▶
ID · IDEX
/1 /2 /4 /8
divider, down to /64 combineddivisor, hasta /64 combinado
▶
TAxR
16-bit
counter
contador
16 bits
the heart of the timerel corazón del temporizador
▶
MC
StopParado
UpArriba
ContinuousContinuo
Up/DownArriba/Abajo
count modemodo de cuenta

Every one of these choices is a field of a single register: TAxCTL. Cada una de estas elecciones es un campo de un solo registro: TAxCTL.

The control register, in one writeEl registro de control, en una escritura

Pick a source, a divider and a mode, OR them together, store once.Elige fuente, divisor y modo, los unes con OR, y escribes una vez.

mov.w #TASSEL__ACLK|ID__8|MC__UP|TACLR, &TA0CTL
0
0
0
0
0
0
0
1
1
1
0
1
0
1
0
0
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
TASSEL = ACLK ID = /8 MC = Up TACLR = 0x01D4

Four ways to countCuatro formas de contar

Field MC selects the shape of TAxR over time.El campo MC selecciona la forma de TAxR en el tiempo.

StopParado MC=0

Halted. The counter holds.Detenido. El contador no avanza.

UpArriba MC=1
CCR0

0 to CCR0, then 0. Sets the period.0 a CCR0, luego 0. Fija el periodo.

ContinuousContinuo MC=2
FFFF

0 to 0xFFFF, then 0. Free running.0 a 0xFFFF, luego 0. Cuenta libre.

Up/DownArriba/Abajo MC=3
CCR0

Up to CCR0, then back down. Symmetric.Sube a CCR0, luego baja. Simétrico.

Up mode is the workhorse: CCR0 is the period, the rest is timing inside it. El modo Up es el caballo de batalla: CCR0 es el periodo, lo demás es temporizar dentro de él.

Compare mode and the CCR registersModo comparación y los registros CCR

Each channel watches the counter for one value and acts when it matches.Cada canal vigila el contador buscando un valor y actúa cuando coincide.

TAxR t TAxCCRn matchcoincide CCIFG = 1 → drive output · request IRQ→ mueve salida · pide IRQ
CCR0 is specialCCR0 es especial

Sets the period and owns its own interrupt vector.Fija el periodo y tiene su propio vector de interrupción.

CCR1, CCR2, ...CCR1, CCR2, ...

Extra compare points inside the same period: a PWM edge or a second event.Puntos de comparación extra dentro del periodo: un flanco PWM o un segundo evento.

Polling the flagSondeando el flag

No interrupts yet: main watches CCIFG.Aún sin interrupciones: main vigila CCIFG.

espera  bit.w #CCIFG, &TA0CCTL0
        jz    espera
        bic.w #CCIFG, &TA0CCTL0  ; ¡borrar!
        xor.b #BIT0, &P1OUT
        inc.w R10
        jmp   espera
WatchObserva

One LED toggle every 20 counts of TA0R. Then comment out the bic.Una conmutación cada 20 cuentas de TA0R. Después comenta el bic.

PausePausa

Without the bic, how often does the LED toggle?Sin el bic, ¿cada cuánto conmuta el LED?

▶ SimulatorSimulador · M9 · Demo: sondeo de CCIFG (sin interrupciones)

Two interrupt pathsDos caminos de interrupción

CCR0 gets a private vector. Everything else shares one and is decoded by TAxIV.CCR0 tiene un vector privado. Todo lo demás comparte uno y se decodifica con TAxIV.

CCR0 CCIFG (TA0CCTL0) 0xFFE8 TIMER0_A0 flag cleared automaticallybandera borrada sola CCR1·CCR2 CCIFG TAIFG TA0IV 0xFFE6 TIMER0_A1 reading TA0IV clears the flagleer TA0IV borra la bandera

CCIFG: a compare matched. TAIFG: the counter rolled over. CCIFG: coincidió una comparación. TAIFG: el contador se desbordó.

Two rhythms, one timerDos ritmos, un solo timer

Continuous mode: CCR0 is just another appointment, with its own vector.Modo continuo: CCR0 es una cita más, con su propio vector.

; CCR0: vector propio, flag se borra solo
ritmoB  add.w #50, &TA0CCR0
        xor.b #BIT7, &P9OUT
        reti
; CCR1: el flag es cosa tuya
ritmoA  bic.w #CCIFG, &TA0CCTL1
        add.w #30, &TA0CCR1   ; re-armar
        xor.b #BIT0, &P1OUT
        reti
WatchObserva

TA0CCR1 climbs 30, 60, 90… and TA0CCR0 50, 100, 150… (no reset in continuous mode); R10/R11 ≈ 5/3.TA0CCR1 sube 30, 60, 90… y TA0CCR0 50, 100, 150… (en continuo no reinicia); R10/R11 ≈ 5/3.

PausePausa

Remove the add: when does LED1 toggle again?Quita el add: ¿cuándo vuelve a conmutar LED1?

▶ SimulatorSimulador · M9 · Demo: dos ritmos con un solo timer

Worked example: a 300 Hz square waveEjemplo: una onda cuadrada de 300 Hz

ACLK = 32768 Hz, Up mode, toggle in the ISR: 600 interrupts/s. fout = fclk / (CCR0+1) / 2.ACLK = 32768 Hz, modo Up, conmutar en la ISR: 600 interrupciones/s. fsal = fclk / (CCR0+1) / 2.

ACLK / 8 = 4096 HzACLK / 8 = 4096 Hz
CCR0 = 4096/600 − 1 = 5.83 → 5
4096 / 6 / 2 = 341.3 Hz
+14 %
No divider: 32768 HzSin divisor: 32768 Hz
CCR0 = 32768/600 − 1 = 53.6 → 53
32768 / 54 / 2 = 303.4 Hz
+1 %

Big divider = long range, coarse steps. For high frequencies, don't divide.Divisor grande = rango largo, pasos gruesos. Para frecuencias altas, no dividas.

Capture mode, the mirror imageModo captura, la imagen espejo

Compare drives an event at a known time. Capture records the time of an external event.Comparación provoca un evento en un instante conocido. Captura registra el instante de un evento externo.

Compare (CAP = 0) · time in → event outComparación (CAP = 0) · tiempo entra → evento sale
CCRn (you write)CCRn (lo escribes) eventevento TAxR
Capture (CAP = 1) · event in → time outCaptura (CAP = 1) · evento entra → tiempo sale
TAxR edgeflanco → CCRn

CM picks the edge, CCIS picks the input. The captured number is just TAxR frozen. CM elige el flanco, CCIS elige la entrada. El número capturado es simplemente TAxR congelado.

PWM with output mode 7PWM con modo de salida 7

Up mode plus reset/set output: CCR0 is the period, CCR1 is the duty cycle. No CPU involved.Modo Up más salida reset/set: CCR0 es el periodo, CCR1 es el ciclo de trabajo. Sin CPU.

CCR0 CCR1 TA0.1
set at CCR0set en CCR0
reset at CCR1reset en CCR1
duty = CCR1 / (CCR0+1)duty = CCR1 / (CCR0+1)

CCR1 sets the pulse width. The brightness of an LED, fixed by one register. CCR1 fija la anchura del pulso. El brillo de un LED, fijado por un registro.

Run it: square wave + CCR0 interruptPruébalo: onda cuadrada + interrupción de CCR0

The 300 Hz example, no divider: CCR0 = 53.El ejemplo de 300 Hz, sin divisor: CCR0 = 53.

CCR0    .equ  53       ; 32768/54/2 = 303 Hz
        bis.b #BIT0, &P1DIR
        mov.w #CCR0, &TA0CCR0
        mov.w #CCIE, &TA0CCTL0
        mov.w #TASSEL__ACLK|ID__1|MC__UP|TACLR, &TA0CTL
dormir  bis.w #LPM3|GIE, SR
        jmp   dormir
TA00ISR xor.b #BIT0, &P1OUT
        inc.w R10
        reti
What to watchQué observar

In the Timer_A panel, TA0R ramps 0 to CCR0, CCIFG sets, the ISR toggles LED1; R10 counts 606.8 interrupts/s.En el panel Timer_A, TA0R sube de 0 a CCR0, se activa CCIFG, la ISR conmuta LED1; R10 cuenta 606,8 interrupciones/s.

▶ Try it in the simulatorPruébalo en el simulador · M9 · Demo: LED por interrupción (CPU dormida) CCR0 → 53

Run it: continuous mode, two channelsPruébalo: modo continuo, dos canales

Shared vector without TA0IV: test each CCIFG, clear it, re-arm.Vector compartido sin TA0IV: prueba cada CCIFG, bórrala y re-arma.

P1      .equ 30
P2      .equ 50
main    mov.w #P1, &TA0CCR1
        mov.w #P2, &TA0CCR2
        mov.w #CCIE, &TA0CCTL1
        mov.w #CCIE, &TA0CCTL2
        mov.w #TASSEL__ACLK|MC__CONTINUOUS|TACLR, &TA0CTL
        eint
loop    nop
        jmp   loop
TA01ISR bit.w #CCIFG, &TA0CCTL1
       jz    chk2
       bic.w #CCIFG, &TA0CCTL1
       add.w #P1, &TA0CCR1
chk2    bit.w #CCIFG, &TA0CCTL2
       jz    fin
       bic.w #CCIFG, &TA0CCTL2
       add.w #P2, &TA0CCR2
fin     reti

       .intvec TIMER0_A1_VECTOR, TA01ISR
What to watchQué observar

CCR1 fires every 30 ticks, CCR2 every 50, through the same ISR.CCR1 dispara cada 30 ticks, CCR2 cada 50, por la misma ISR.

▶ Try it in the simulatorPruébalo en el simulador · M9 · Demo: dos ritmos con un solo timer

Run it: PWM with no interruptsPruébalo: PWM sin interrupciones

8-bit PWM on P1.0 / TA0.1. The timer drives the output by itself, the CPU is free.PWM de 8 bits en P1.0 / TA0.1. El timer mueve la salida solo, la CPU queda libre.

pwm     mov.w #__STACK_END, SP
        mov.w #WDTPW|WDTHOLD, &WDTCTL
        bic.w #LOCKLPM5, &PM5CTL0
        bis.b #BIT0, &P1SEL0  ; P1.0 = TA0.1
       bis.b #BIT0, &P1DIR
       mov.w #OUTMOD_7, &TA0CCTL1 ; reset/set
       mov.w #64, &TA0CCR1   ; 64/256 = 25%
       mov.w #255, &TA0CCR0  ; period
       mov.w #TASSEL__ACLK|ID__1|MC__UP|TACLR, &TA0CTL
done    nop
        jmp   done

       .intvec RESET_VECTOR, pwm
What to watchQué observar

Click LaunchPad, Run. TA0R counts to 255; the P1.0 output goes high at CCR0 and low at CCR1, no ISR at all.Pulsa LaunchPad, Run. TA0R cuenta hasta 255; la salida P1.0 sube en CCR0 y baja en CCR1, sin ninguna ISR.

▶ Try it in the simulatorPruébalo en el simulador · M9 · Demo: PWM, brillo sin CPU

Three ideas to take with youTres ideas para llevarte

A timer is a counter the CPU configures once and then forgets.Un temporizador es un contador que la CPU configura una vez y luego olvida.

TAxR

One counter, four modes.Un contador, cuatro modos.

Source, divider and mode are all fields of TAxCTL, written in one instruction.Fuente, divisor y modo son campos de TAxCTL, escritos en una instrucción.

CCRn

Compare or capture.Comparar o capturar.

Compare turns time into events and PWM. Capture turns events into timestamps.Comparar convierte el tiempo en eventos y PWM. Capturar convierte eventos en marcas de tiempo.

0xFFE8

CCR0 has its own vector.CCR0 tiene su propio vector.

Everything else shares the second vector, decoded by TAxIV. CCIFG vs TAIFG.Todo lo demás comparte el segundo vector, decodificado por TAxIV. CCIFG vs TAIFG.