Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

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
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;
}
 

Hi,

For true multitasking you can refer ucos-II from micrim.com which is free with source code for study purpose.

Regards,
 

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

Run the code under debugger control and find out what's not working.
 

yes, i also agree with FvM, run the code under debugger control or you can simply use simulator of IDE and simulate code.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top