Multitasking with timer0 on atmega128, does anyone have experience?

Status
Not open for further replies.

bianchi77

Advanced Member level 4
Joined
Jun 11, 2009
Messages
1,313
Helped
21
Reputation
44
Reaction score
20
Trophy points
1,318
Location
California
Visit site
Activity points
9,442
Guys,

I tried to follow the tutorial from :
https://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=95490

But I didn't see any blinks on PB4 or PB5,

perhaps I did a wrong timer init ?
my CPU is ATMEGA128 with 8Mhz clock

Thanks in advance

here's the code :
Code:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>

void init_devices(void);
void timer0_init(void);
void reset_task(char tsk);
void set_task(char tsk);
void task_dispatch(void);
void task0(void);
void task1(void);
void task2(void);
void task3(void);
void task4(void);
void task5(void);
void task6(void);
void task7(void);

#define NUM_TASKS 8
char task_bits = 0;  /* lsb is hi priority task */
volatile char tick_flag = 0;    /* if non-zero, a tick has elapsed */
unsigned int task_timers[NUM_TASKS]={0,0,0,0,0,0,0,0};                  /* init the timers to 0 on startup */
static const PROGMEM char bit_mask[]={1,2,4,8,16,32,64,128};            /* value -> bit mask xlate table */

int main(void)
{

  init_devices();
//
//   start at least one task here
//
set_task(7);   //task7 runs
set_task(6);   //task6 runs

//      main loop

  while(1)
    {
    if (tick_flag)
      {
      tick_flag = 0;
     task_dispatch();              // well....
     }
   }
  return 0;
}
//
//   a task gets dispatched on every tick_flag tick (10ms)
//
void task_dispatch(void)
{
  /* scan the task bits for an active task and execute it */

  char task;
   

/* take care of the task timers. if the value ==0 skip it
   else decrement it. If it decrements to zero, activate the task associated with it */

  task=0;
  while (task < NUM_TASKS )
    {
    if (task_timers[task])
      {
        task_timers[task]--;            /* dec the timer */
      if (task_timers[task] == 0 )
            {
          set_task(task); /* if ==0 activate the task bit */
         }
      }
    task++;
    }

  task = 0; /* start at the most significant task */
  while (task <= NUM_TASKS )
    {
     if ((task_bits & pgm_read_byte(&bit_mask[task])))
           {
           break; /* if activate task found..*/
         }
      task++;         /* else try the next one */
    }
  switch(task)            /* if task bit is active..execute the task */
    {
    case 0:
      task0();
      break;
    case 1:
      task1();
      break;
    case 2:
      task2();
      break;
    case 3:
      task3();
      break;
    case 4:
      task4();
      break;
    case 5:
      task5();
      break;
    case 6:
      task6();
      break;
    case 7:
      task7();
      break;
    default:
      break;                  /* no task was active!! */
    }                       
}

// enable a task for execution
void set_task(char tsk)
{
  task_bits |= pgm_read_byte(&bit_mask[tsk]);       /* sets a task bit */
}
// disable a task from executing
void reset_task(char tsk)
{
  task_bits &= (~pgm_read_byte(&bit_mask[tsk]));  /* resets a task bit */
}

void task0(void)
{
  reset_task(0);
}
void task1(void)
{
  reset_task(1);
}
void task2(void)
{
  reset_task(2);
}
void task3(void)
{
  reset_task(3);
}
void task4(void)
{
  reset_task(4);
}
void task5(void)
{
  reset_task(5);
}
//
//   flash PORTB.4 at 2hz
//
void task6(void)
{
PORTB ^= (1<<4);
task_timers[6] = 25;      //every 250ms
reset_task(6);
}
//
//   flash PORTB.5 at 1hz
//
void task7(void)
{
PORTB ^= (1<<5);
task_timers[7] = 50;      //every 500ms 
reset_task(7);
}
//call this routine to initialize all peripherals
void init_devices(void)
{
 //stop errant interrupts until set up
 cli(); //disable all interrupts


 DDRB = 0x30;   //port 4 & 5 as outputs

 timer0_init();
 
 MCUCR = 0x00;
 EICRA = 0x00; //extended ext ints
 EIMSK = 0x00;
 
 TIMSK = 0x02; //timer 0 interrupt sources
 
 //PRR = 0x00; //power controller
 sei(); //re-enable interrupts
 //all peripherals are now initialized
}
//TIMER0 initialize - prescale:1024
// WGM: CTC
// desired value: 10mSec
// actual value: 10.048mSec (-0.5%)
void timer0_init(void)
{
 TCCR0|=(1<<CS02)|(1<<CS00); //prescale 1024
 TCCR0 = 0x00; //stop
 TCNT0 = 0x00; //set count
 TCCR0 = (1 << WGM01 );//CTC mode
 
 
  
 TIMSK|=(1<<TOIE0);
  OCR0 = 0x4E;
  TCCR0 = 0x00; //start timer
}

ISR(TIMER0_COMPA_vect)
{
 //TIMER0 has overflowed
    tick_flag = 1;
}
 

I don't want to use OS now, may be later.....any ideas to solve it without OS ?thanks
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…