Timers are very useful hardware modules for embedded systems. They can be used for a variety of purposes, including: generation of waveforms, timing of events, generation of interrupts, etc. The registers for Timer 1 are as follows:
| Register | Address | |
| MBARx | 0x1000 0000 | module base address |
| TMR1 | MBARx + 0x0100 | TIMER1 Mode Register, 16-bit, RW |
| TRR1 | MBARx+0x0104 | TIMER1 TIMER1 ref Register, 16-bit, RW |
| TCR1 | MBARx+0x0108 | TIMER1 Capture Register, 16-bit, R |
| TCN1 | MBARx+0x010C | TIMER1 Counter, 16-bit, RW |
| TER1 | MBARx+0x0111 | TIMER1 Event Register, 8-bit, RW |
Let's look at an example assembler program that sets up the timer and produces a square wave. Download the assembly program timer1s.s:
/* timer1s.s
test of timer 1 - square wave
*/
.text
.even
.global main
main:
/****************
* TMR1 register *
*******************************************************************
* Bits 15:8 sets the prescale to 1 (0x00) or [256 - FF ]
* Bits 7:6 set for no interrupt ("00") *
* Bits 5:4 sets output mode for "toggle". No interrupts("10") *
* Bits 3 set for "restart" ("1")
* Bits 2:1 set the clocking source to system clock/16 ("10") *
* Bits 0 enables/disables the timer ("0")
*******************************************************************/
move.w #0x0000,%d0 /* first clear TRM1 */
move.w %d0,TMR1
move.w #0xFF2C,%d0 /*Setup the Timer mode register (TMR1) */
move.w %d0,TMR1 /*Bit 1 is set to 0 to disable the timer */
move.w #0x0000,%D0 /* writing to the timer counter with */
move.w %D0,TCN1 /* any value resets it to zero */
/*****************
* TRR1 register *
*******************************************************************
* The TRR register is set to 0xAFAF. The timer will count up to *
* this value (TCN = TRR), toggle the "TOUT" pin, and reset the *
* TCN to 0x0000.
*******************************************************************/
move.w #0x0010,%d0 /* Setup the Timer reference register */
move.w %d0,TRR1
/* timer 1 main test code - square wave */
clr.l %d0
clr.l %d1
move.b #0x03,%d1 /* reset REF and CAP bits of TER1 */
move.b %d1,TER1
move.w TMR1,%d0 /* enable the timer, using above settings */
bset #0,%d0 /* ie set bit 0 of TMR1 */
move.w %d0,TMR1
/* a square wave now appears at pin tout0 */
rts /* return to monitor */
MBARx = 0x10000000 /* Module Base Address value */
TMR1 = MBARx+0x0100 /*TIMER1 Mode Register, 16-bit, RW */
TRR1 = MBARx+0x0104 /*TIMER1 TIMER1 ref Register, 16-bit, RW */
TCR1 = MBARx+0x0108 /*TIMER1 Capture Register, 16-bit, R */
TCN1 = MBARx+0x010C /*TIMER1 Counter, 16-bit, RW */
TER1 = MBARx+0x0111 /*TIMER1 Event Register, 8-bit, RW */
Examine this code carefully, and notice:
Exercise.
go 10000
A C version is available in the file timer1c.c:
/* timer1c.c
tests timer 1 - square wave
*/
#define MBARx 0x10000000 /* Module Base Address value */
#define TMR1 (* (short int *) (MBARx+0x0100))
/*TIMER1 Mode Register, 16-bit, RW */
#define TRR1 (* (short int *) (MBARx+0x0104))
/*TIMER1 TIMER1 ref Register, 16-bit, RW */
#define TCR1 (* (short int *) (MBARx+0x0108))
/*TIMER1 Capture Register, 16-bit, R */
#define TCN1 (* (short int *) (MBARx+0x010C))
/*TIMER1 Counter, 16-bit, RW */
#define TER1 (* (char *) (MBARx+0x0111))
/*TIMER1 Event Register, 8-bit, RW */
int main() {
int i;
short int j;
TMR1 = 0x0000; /* first clear TMR1*/
TMR1 = 0xff2c; /* set up TMR1 */
TCN1 = 0x0000; /* clear timer 1 counter */
TRR1 = 0x0020; /* set reference value */
TER1 = 0x03; /* reset REF and CAP bits of TER1 */
j = TMR1;
TMR1 = j | 0x0001; /* enable timer 1 */
/* a square wave now appears at pin tout0 */
return 0;
}
The next example includes a delay routine that uses the timer and the polling technique.
Download the C program timer2c.c:
/* timer2c.c
pdelay - delay fn using polling
*/
#define MBARx 0x10000000 /* Module Base Address value */
#define TMR1 (* (short int *) (MBARx+0x0100))
/* TIMER1 Mode Register, 16-bit, RW */
#define TRR1 (* (short int *) (MBARx+0x0104))
/* TIMER1 TIMER1 ref Register, 16-bit, RW */
#define TCR1 (* (short int *) (MBARx+0x0108))
/* TIMER1 Capture Register, 16-bit, R */
#define TCN1 (* (short int *) (MBARx+0x010C))
/* TIMER1 Counter, 16-bit, RW */
#define TER1 (* (char *) (MBARx+0x0111))
/* TIMER1 Event Register, 8-bit, RW */
#include <stdio.h>
void pdelay(int i);
int main() {
int i;
i = 0;
while (1) {
printf("%d",i); printf("\n");
if (i == 9) i=0; else i = i+1;
pdelay(1000); /* delay for ... seconds */
};
return 0;
}
void pdelay(int dly) {
/* 1 time unit is 1ms, so for a 2 sec delay use 2000 */
int i;
short int j;
/* set up timer 1 */
TMR1 = 0x0000; /* first clear TMR1*/
TMR1 = 0xff2c; /* set up TMR1 */
TCN1 = 0x0000; /* clear timer 1 counter */
TRR1 = 0x0006; /* set reference value */
TER1 = 0x03; /* reset REF and CAP bits of TER1 */
j = TMR1;
TMR1 = j | 0x0001; /* enable timer 1 */
/* delay loop */
for (i=0; i < dly; i++) {
while ((TER1 & 0x0002) == 0x0000) {};
TER1 = 0x02; };
j = TMR1;
TMR1 = j & 0xfffe; /* disable timer 1 */
};
Exercise.
go 10000
ANU Engineering - ENGN3213