I'm a newbie to uC programming and I have a doubt regarding the PIT.
I'm using the PE to configure the PIT0 for 1ms. For a system frequency of 80MHz, (PIT clock = system frequency/2) I'm using:
Prescaler =4 and Modulus register=10000.
I'm required to generate interrupts at 1ms, 30ms and 300ms. Can I use the same PIT0 function configured for 1ms and change the values of the modulus registers to generate interrupts at 30ms and 300ms?
Can only one interrupt be generated for each PIT channel?
Thanking you in advance for your reply.
Regards,
PRao
Solved! Go to Solution.
One PIT can generate only one interrupt.
If you need know when 1, 30ms and 300ms pass, use the 1 ms interrupt handler to count to 30 and 300, respectively.
// The interrupt handler for PIT0 running at 1 hHz
irq_handler{
static unsigned int tickCount = 0;
// Clear interrupt
PCSR0 |= PIF;
tickCount++;
// Executed each 1 millisecond
do_tick_1ms();
// Executed each 30 milliseconds
if (tickCount % 30 == 0) {
do_tick_30ms();
}
// Executed each 300 milliseconds
if (tickCount >= 300) {
do_tick_300ms();
tickCount = 0;
}
}
Obviously PIT0 should be in "Set-and-Forget" operation and your "do_tick_Xm()" functions should not do anything time-consuming.
One PIT can generate only one interrupt.
If you need know when 1, 30ms and 300ms pass, use the 1 ms interrupt handler to count to 30 and 300, respectively.
// The interrupt handler for PIT0 running at 1 hHz
irq_handler{
static unsigned int tickCount = 0;
// Clear interrupt
PCSR0 |= PIF;
tickCount++;
// Executed each 1 millisecond
do_tick_1ms();
// Executed each 30 milliseconds
if (tickCount % 30 == 0) {
do_tick_30ms();
}
// Executed each 300 milliseconds
if (tickCount >= 300) {
do_tick_300ms();
tickCount = 0;
}
}
Obviously PIT0 should be in "Set-and-Forget" operation and your "do_tick_Xm()" functions should not do anything time-consuming.
hi DaStone,
i also want to do same task , but i hv no idea about coldfire.I hv 52233DEMO with 25Mhz crystal
i aslo read 52233RM and 52233DS , but still not getting it, can u plz help me out??
From Abhijit
My interrupts seem to work fine using the do_tick_Xms( ) function when they are doing less time consuming operations like u mentioned earlier.
What I need to do now is:
- to check for key press action every 30ms and take appropriate actions depending on the key pressed. I would also like to refresh LEDs every 30 ms. If the key press action occurs, lot of time consuming steps have to be implemented.
- To read battery voltage every 300ms and blink LEDs every 300 ms.
- And check for action of a particular key every 2ms.
How do I ensure that all these operations are done using a base 1ms timer.
Do I use both the PITs and divide the timer work between the two?
Or I use separate timers for each , like both PITs and the GPTs.
Kindly help.
Regards.
Prao wrote:
How do I ensure that all these operations are done using a base 1ms timer.
Do I use both the PITs and divide the timer work between the two?
Or I use separate timers for each , like both PITs and the GPTs.
Don't use PIT-s directly. If you try to do any actual work inside interrupts, you are entering a world of pain.
I assume you have a simple main() function which contains a never-ending loop. Is that correct?
All processing MUST be done inside the main loop. It's very simple to implement.
You add some flags which are accessible for both interrupts and main loop. You need one flag for each period - 1ms, 30 ms and 300ms. They're just volatile integers in global scope. The interrupt handler only sets the flag (well, actually your do_tick_Xms() function does).
The main loop polls the flags. When main loop finds that a flag has been set, it does the processing for this period. It doesn't get any simpler than this
----- begin main.c -----
volatile unsigned int g_tick1ms = 0;
volatile unsigned int g_tick30ms = 0;
volatile unsigned int g_tick300ms = 0;
int main(void) {
while (1) {
if (g_tick1ms) {
// Clear the flag
g_tick1ms = 0;
// Process the 1 ms tick
// ... your stuff here ...
}
if (g_tick30ms) {
// Clear the flag
g_tick30ms = 0;
// Process the 30 ms tick
// ... your stuff here ...
}if (g_tick300ms) {
// Clear the flag
g_tick300ms = 0;
// Process the 300 ms tick
// ... your stuff here ...
} }
}
----- end main.c -----
----- begin interrupts.c -----
extern volatile unsigned int g_tick1ms;
extern volatile unsigned int g_tick30ms;
extern volatile unsigned int g_tick300ms;
void do_tick_1ms() {
g_tick1ms = 1;
}
void do_tick_30ms() {
g_tick30ms = 1;
}
void do_tick_300ms() {
g_tick300ms = 1;
}
----- end interrupts.c -----
A word of warning: sharing any data between an interrupt handler and main loop is tricky. If you only exchange an integer (or any other atomic data) just declare it volatile and you'll be fine. Any non-atomic data (strings, arrays, structs, doubles etc) must be protected from simultaneous access. It's done by locking the data and this is where it gets complicated Hopefully you don't need that, however.
This IS the simplest way to implement my routines! I configured a set and forget timer outside the while loop and was trying to set my flags within the interrupt and calling a function within it too. It just didn't seem to make sense.
You are right, I would not encounter a situation where locking of data has to be done.
Thank you for the lucid explanation
DaStoned,
Thank you for reply. It makes more sense now.
P.S. Sorry I didn't check this earlier, due to internet access problems.