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