Newbie question: Programming the PIT in MCF52256

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Newbie question: Programming the PIT in MCF52256

Jump to solution
3,454 Views
Prao
Contributor I

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

Labels (1)
0 Kudos
Reply
1 Solution
1,226 Views
DaStoned
Contributor II

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.

 

Message Edited by DaStoned on 2009-04-28 02:58 PM

View solution in original post

0 Kudos
Reply
7 Replies
1,227 Views
DaStoned
Contributor II

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.

 

Message Edited by DaStoned on 2009-04-28 02:58 PM
0 Kudos
Reply
1,226 Views
MCF52233
Contributor III

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

0 Kudos
Reply
1,226 Views
Prao
Contributor I

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.

 

 

0 Kudos
Reply
1,226 Views
DaStoned
Contributor II

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 :smileyhappy:

 

   ----- 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 :smileysad: Hopefully you don't need that, however.

Message Edited by DaStoned on 2009-05-08 03:01 PM
0 Kudos
Reply
1,226 Views
Prao
Contributor I

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:smileymad:.

 

You are right, I would not encounter a situation where locking of data has to be done.

 

Thank you for the lucid explanation :smileyvery-happy: 

0 Kudos
Reply
1,226 Views
DaStoned
Contributor II
You're welcome.

Some years ago I did my first embedded work. Task was almost the same - keyboard, LED-s, LCD etc running of a PIT. It's so simple, yet it took me embarrassingly long to find the correct solution :smileywink:

Scanning the key matrix and eliminating key bounce took even longer.
0 Kudos
Reply
1,226 Views
Prao
Contributor I

DaStoned,

 

Thank you for reply. It makes more sense now:smileyvery-happy:.

 

P.S. Sorry I didn't check this earlier, due to internet access problems.

 

 

0 Kudos
Reply