In this post
you will learn to work with timer and to trigger required interrupts.
Every
micro controller has at least 2 (maybe wrong..!) timer units - Timer0 and
Timer1. The RX-63N processor in GR-Sakura has 4 Timers Timer 0 – Timer 3 (8
bit). Also Timer0 and Timer1 as well as Timer2 and Timer3 can be combined
(cascaded) to provide two 16 bit timer units.Timer speed is based on the clock source provided to it. An 8 bit timer/counter counts from 0 to 255 (2^8), whereas a 16 bit timer/counter counts from 0 – 65535 (2^16). A clock source defines in what speed the timer counts (increment/decrement) these values.
For example,
Consider
an 8 bit timer with clock source as 20MHz. Then the timer will increment (from
0) for each 1/20000000 =
1/2000000 * 255 =
0.05u * 255 = 12.75u seconds
Similarly for a 16 bit timer,
1/2000000 * 65535 = 0.05u * 65535
= 3.27m seconds
Since
the timer units are within the microcontroller, you may think that whatever
clock is given to microcontroller is available for the timer units. The
microcontroller’s clock input is referred as Primary Clock (PCLK). Either you
can use this clock or change the clock source to a timer unit. This is achieved
with the TCCR (Timer Counter Control) Register as in Sakura’s case. The clock
source can be PCLK, PCLK/2, PCLK/4, ……, PCLK/8192 (Refer datasheet).
We will see what is the use in
dividing the clock source..,
If
you select the clock source to be PCLK/4, then clock will be 5 MHz (For PCLK = 20MHz)
and the time to count for a 8 bit timer will be
1 / 5000000 * 255 =
51u sec
Thus you can increase the timing.
Ok.. The timer
starts and finishes its counting.. what’s in there for us and what to do with
that.?
1.
delay() functions can be replaced with such
timers. Because delay() functions make the processor to do nothing and just
simply wait. Whereas if you use a timer, you can perform other functions when
the timer is counting (probably multitasking). 2. Can be used to trigger certain on chip peripherals such as ADC, periodically using interrupts.
A timer either
1. counts
from 0-255 for 8 bit timer and 0-65535 for a 16 bit timer and Overflows
2. a
specific value can be written and the timer counts from that specific value
3. a
specific value can be written and the timer counts up to that specific value
8 bit Timer Overflow Interrupt:
A simple timer
program for GR-Sakura – The following code involves enabling Timer0 (8 bit).
Once the timer overflows, it generates Timer0
Overflow Interrupt which increments the cnt variable. And once
the value of cnt reaches 50, it changes the state of the on board LED.
Note: GR-Sakura’s clock source (PCLK) is 48MHz.
--------------------------------------------------------------------------------------------------------------------------
#include
<rxduino.h>
#include
<iodefine_gcc63n.h>#include"intvect.h"
void
Excep_TMR0_OVI0 (void) __INTTERUPT_FUNC;
void
init_tmr();
int cnt=0;
volatile int
state=0;int main ()
{
pinMode (PIN_LED0, OUTPUT);
init_tmr();
while(1)
{if(cnt>50)
{
cnt=0;
state=!state;
digitalWrite
(PIN_LED0, state); }
}
}
void
init_tmr()
{
MSTP(TMR0) = 0; // Timer unit enable
TMR0.TCCR.BIT.CKS = 0b110; // Clock Select Bit (refer below image) –
PCLK/8192
TMR0.TCCR.BIT.CSS = 0b01; // Clock Source Select Bit (refer below image)
TMR0.TCR.BIT.OVIE = 0b1; // Timer 0 overflow interrupt enable bit
IEN (TMR0, OVI0) = 1; // Timer 0 overflow
interrupt Enable MACRO
IPR (TMR0, OVI0) = 2; // Interrupt priority
– Level 2
}
void
Excep_TMR0_OVI0(void)
{cnt++;
}
Compare Match Interrupt Program:
Other
than starting from 0 and count to 255/65535, you can write a specific value to
registers TCORA/TCORB, and when the timer reaches that value, it stops and
clears the TCNT (Timer Counter) register.
--------------------------------------------------------------------------------------------------------------------------#include"intvect.h"
void
Excep_TMR0_CMIA0 (void) __INTTERUPT_FUNC;
void
init_tmr();
int cnt=0;
volatile int
state=0;
int main ()
{pinMode (PIN_LED0, OUTPUT);
init_tmr();
while(1)
{
if(cnt>50)
{
cnt=0;
state=!state;
digitalWrite
(PIN_LED0, state); }
}
}
void
init_tmr()
{
MSTP(TMR0) = 0; // Timer unit enable
TMR0.TCCR.BIT.CKS = 0b110;
TMR0.TCCR.BIT.CSS = 0b01;
TMR0.TCR.BIT.CCLR = 0b01; // Automatic
clearing enabled
TMR0.TCR.BIT.CMIEA = 0b1; // Compare match A
interrupt enable
TMR0.TCORA=118; // write the required value
to TCORA register (in this case timer starts from 118 and ends at 255)
IEN (TMR0, CMIA0) = 1;
IPR (TMR0, CMIA0) = 2;}
void
Excep_TMR0_CMIA0(void)
{cnt++;
}
-------------------------------------------------------------------------------------------------------------------------
Compare Match can be used to provide precision timings. For example, if you need an accurate
1 sec delay, then you can write the required value at which the timer starts so
that a 1 sec delay is achieved. Need to do some math…!!!!!
Cascading two
8 bit timers to obtain a 16 bit Timer:
Here two 8 bit timers namely
Timer2 and Timer3 are cascaded to achieve a single 16 bit timer. The concept is
that whenever the lower 8 bit timer overflows, then the upper 8 bit is
incremented once.
In this code
Timer2 is the upper register and Timer3 is the lower register.
#include
<rxduino.h>
#include
<iodefine_gcc63n.h>
#include
<intvect.h>
void Excep_TMR2_CMIA2(void) __INTTERUPT_FUNC;
void init();
int k;
main()
{Serial.begin(9600);
delay(7000);
init();
while(1)
{
if(k>5)
{
Serial.print(k);
Serial.println("
Counted");
}
}
}
void
Excep_TMR2_CMIA2(void)
{k++;
}
void init()
{MSTP(TMR2)=0;
TMR3.TCCR.BYTE=0;
TMR2.TCCR.BIT.CSS=0b11; // clock
source is the a Timer3 overflow signal
TMR23.TCNT=0;
TMR2.TCR.BIT.CCLR=0b01; //
cleared by Compare Match A
TMR2.TCR.BIT.CMIEA=1;
IEN(TMR2,CMIA2)=1;
IPR(TMR2,CMIA2)=1;
TMR23.TCORA=60000; // change this value and notice the change in
timings
TMR3.TCCR.BIT.CSS=0b01;
TMR3.TCCR.BIT.CKS=0b100;}
--------------------------------------------------------------------------------------------------------------------------
Hope it helps somebody..!!!
No comments:
Post a Comment