next up previous contents

[ENGN3213 Home]

Timer

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.

1.
Make the necessary hardware connections, including ground. Refer to the Appendix 18.5 describing the SBC cable pins.

2.
Assemble and link the program.

3.
Load the program timer1s.x into the SBC.

4.
Run the code:
go 10000

5.
Use an osilloscope to measure the voltages at the timer 1 output: tout0. Sketch the waveform and determine the frequency.

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.

1.
Examine the code and determine what the program does and how.

2.
Assemble and link the program.

3.
Load the program timer2c.x into the SBC.

4.
Run and test the code:
go 10000

5.
Terminate the program with the black ABORT button.


next up previous contents

[ENGN3213 Home]

ANU Engineering - ENGN3213