View previous topic :: View next topic |
Author |
Message |
nico_b
Joined: 15 Dec 2004 Posts: 2 Location: Netherlands
|
multitasking not possible with pic? |
Posted: Wed Dec 15, 2004 9:20 am |
|
|
Hello,
Done a lot off programming in Dynamic C for Zworld board's.
Using the Co_state feature you can blink a led, look for input , etc at the same time. Delayms instructions in a Costate will not effect other Co-state's
With PIC it seems not that easy. Due to delay_ms (200) instructions main is busy all the time. Interrupts seems to be the answer . Set a timer and wait for an timeroverflow in main. Or use a delay_ms(10) in for next loop .
Anyone a suggestion,
Nick
Last edited by nico_b on Wed Dec 15, 2004 2:47 pm; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
|
Posted: Wed Dec 15, 2004 10:27 am |
|
|
I run a clock at 1mS and call each function once per mS. To time performance of functions, within the functions decrement counters in each function. When the counter gets to zero perform the function and reload the counter. I posted code that was the core for this a while back. This is quite effective and accurately timed as long as the functions do not take longer than 1mS to perform. When it takes longer than 1mS the processor is running at full capasity and will still keep reasonable timing.
http://www.ccsinfo.com/forum/viewtopic.php?t=19252 |
|
|
BelmareM
Joined: 15 Dec 2004 Posts: 2
|
|
Posted: Wed Dec 15, 2004 4:16 pm |
|
|
Hello,
I wrote a small program with 3 tasks that are switched every 10ms. This can be changed to 1ms. But some things are missing like saving of registers or reentry of functions. I can post my code tomorrow if you are interrested. It is for a 18F452. |
|
|
nico_b
Joined: 15 Dec 2004 Posts: 2 Location: Netherlands
|
Thanks for all the responses so far |
Posted: Wed Dec 15, 2004 4:17 pm |
|
|
Great help
Nick
|
|
|
BelmareM
Joined: 15 Dec 2004 Posts: 2
|
|
Posted: Thu Dec 16, 2004 6:06 am |
|
|
Hello,
here is if.
Code: |
//////////////////////////////////////////////////////////////////////////////
// Projekt: Multitasking mit dem PIC18F452
// Datei: "MultiTask_Test.c"
//
//////////////////////////////////////////////////////////////////////////////
#include "18F452.h"
#device *=16 ADC=10
#org 0x07E00, 0x07FFF {} //void loader18F452(void) {} //protect bootloader code
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#zero_ram
//////////////////////////////////////////////////////////////////////////////
//
#define Max_Number_of_Task_ub 3
#define Task_Setup_ub 0
#define Task_Run_ub 1
#define TOSH 0xffe
#define TOSL 0xffd
long Task_Adr_PTR_ul[Max_Number_of_Task_ub];
byte Task_Aktuell_ub = 0;
long ISR_Counter_ul;
long x0_ul;
long x1_ul;
long x1a_ul;
long x2_ul;
long x2a_ul;
//////////////////////////////////////////////////////////////////////////////
//
#INT_TIMER1
void timer1_interupt()
{
long Old_Task_Adr_PTR_ul = 0;
long New_Task_Adr_PTR_ul = 0;
set_timer1(65535 - (500 - 32)); // 100 µs = 1 Interrupt = 10.000 Hz
ISR_Counter_ul++;
if (ISR_Counter_ul > 99) // 10ms then next task
{
// get old address from stack
#asm
movff TOSL, &Old_Task_Adr_PTR_ul
movff TOSH, &Old_Task_Adr_PTR_ul + 1
#endasm
Task_Adr_PTR_ul[Task_Aktuell_ub] = Old_Task_Adr_PTR_ul;
Task_Aktuell_ub++;
if (Task_Aktuell_ub == Max_Number_of_Task_ub)
{
Task_Aktuell_ub = 0;
}
New_Task_Adr_PTR_ul = Task_Adr_PTR_ul[Task_Aktuell_ub];
// put new address on stack
#asm
movff &New_Task_Adr_PTR_ul + 1, TOSH
movff &New_Task_Adr_PTR_ul, TOSL
#endasm
}
else // other ISR when you want
{
}
}
//////////////////////////////////////////////////////////////////////////////
//
void SetupPIC()
{
setup_timer_1(0b10000101);
}
//////////////////////////////////////////////////////////////////////////////
//
void Task0(byte Task_Control)
{
if (Task_Control > 0)
{
enable_interrupts(INT_TIMER1); // Timer 1
enable_interrupts(GLOBAL);
Task0_lbl:
do
{
x0_ul++;
printf("x0 = %04lu x1 = %04lu x2 = %04lu \r\n", x0_ul, x1_ul, x2_ul);
}
while(1);
}
else
{
Task_Adr_PTR_ul[0] = label_address(Task0_lbl);
}
}
//////////////////////////////////////////////////////////////////////////////
//
void Task1(byte Task_Control)
{
if (Task_Control > 0)
{
Task1_lbl:
do
{
x1a_ul++;
if (x1a_ul == 0)
{
x1_ul++;
}
}
while(1);
}
else
{
Task_Adr_PTR_ul[1] = label_address(Task1_lbl);
}
}
//////////////////////////////////////////////////////////////////////////////
//
void Task2(byte Task_Control)
{
if (Task_Control > 0)
{
Task2_lbl:
do
{
x2a_ul++;
if (x2a_ul == 0)
{
x2_ul++;
}
}
while(1);
}
else
{
Task_Adr_PTR_ul[2] = label_address(Task2_lbl);
}
}
//////////////////////////////////////////////////////////////////////////////
//
void Task_Init()
{
Task0(Task_Setup_ub);
Task1(Task_Setup_ub);
Task2(Task_Setup_ub);
printf("Task 1 = %04lx \r\n", Task_Adr_PTR_ul[0]);
printf("Task 2 = %04lx \r\n", Task_Adr_PTR_ul[1]);
printf("Task 3 = %04lx \r\n", Task_Adr_PTR_ul[2]);
getc(); // waiting for a keypressed
}
//////////////////////////////////////////////////////////////////////////////
//
void main ()
{
Task_Init();
SetupPIC();
Task0(Task_Run_ub);
do
{ }
while(1);
}
|
[/code] |
|
|
jds-pic
Joined: 17 Sep 2003 Posts: 205
|
Re: multitasking not possible with pic? |
Posted: Thu Dec 16, 2004 10:20 am |
|
|
nico_b wrote: | Using the Co_state feature you can blink a led, look for input , etc at the same time. |
nick,
it's *not* doing two things at the same time.
it's simply managing the avaliable time across multiple [functions | features | processes | LWPs | threads | whatever you want to call them]. you can implement this same type of management on a PIC, using your own state machine and timers, along with interrupts. examples are above and via the search button.
jds-pic |
|
|
|