View previous topic :: View next topic |
Author |
Message |
muhibraza1
Joined: 26 Jul 2013 Posts: 23
|
How to do Multitasking with PIC18F |
Posted: Thu Jun 18, 2015 6:52 am |
|
|
hello all !
I am working on a project where I have multiple tasks to perform. Can someone help me find out an efficient multitasking methodology that I could use ?
here's a simple version of my code :
Code: |
#include <18f26k22.h>
#FUSES HSH,NOPLLEN,NOBROWNOUT
#use delay(clock=20M)
#define _A_TICKS 1
#define _B_TICKS 2
#define _C_TICKS 3
#define _D_TICKS 4
volatile int a;
volatile int b;
volatile int c;
volatile int d;
void func_a(void)
{
output_toggle(PIN_C0);
a = _A_TICKS;
}
void func_b(void)
{
output_toggle(PIN_C1);
b = _B_TICKS;
}
void func_c(void)
{
output_toggle(PIN_C2);
c = _C_TICKS;
}
void func_d(void)
{
output_toggle(PIN_C3);
d = _D_TICKS;
}
#INT_TIMER0
void timer0_isr()
{
if (a) a--;
if (b) b--;
if (c) c--;
if (d) d--;
set_timer0(46004);
}
void main(void)
{
set_timer0(46004);
setup_timer_0(T0_INTERNAL | T0_DIV_256);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
do
{
if(!a) func_a();
if(!b) func_b();
if(!c) func_c();
if(!d) func_d();
}while(TRUE);
}
|
are there any cons in this type of coding ? if yes then please give any suggestion for improvement. _________________ PCWHD Compiler v4.124
ICD U-64 Hardware Rev 2 & 3
CCSLOAD 4.053 |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9244 Location: Greensville,Ontario
|
|
Posted: Thu Jun 18, 2015 7:02 am |
|
|
First comment... add comments !
Really. They cost NOTHING yet provide valuable information to us (and you, 3 weeks from now) as to what you're doing and what variables are for.
Code like...
should have a comment saying what it does. I know it's the 'refresh rate' of a timer but have no idea if it's 1 second, .1 seconds, maybe every 34us ?
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19541
|
|
Posted: Thu Jun 18, 2015 8:35 am |
|
|
Have a look at the thread:
<http://www.ccsinfo.com/forum/viewtopic.php?t=54041>
This is one of the critical things for multi-tasking. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
Re: How to do Multitasking with PIC18F |
Posted: Thu Jun 18, 2015 3:22 pm |
|
|
muhibraza1 wrote: | are there any cons in this type of coding ? if yes then please give any suggestion for improvement. | Your code is a nice clean example of creating a multitasking program in the PIC.
Just a few minor issues:
1) I don't like macro's or variable names starting with an underscore character, '_'. In the C++ language the names starting with a single or double underscore are reserved for compiler internal names. Since I often use a C++ compiler for my C-code it is a habit preventing me from getting into trouble.
2) Code: | #INT_TIMER0
void timer0_isr()
{
if (a) a--;
if (b) b--;
if (c) c--;
if (d) d--;
set_timer0(46004);
} | The time it takes for executing all the if-statements will differ depending on the outcomes. For best timer stability you should set the new timer value immediately at the ISR start.
Also, the time it takes to enter your ISR will sometimes be unknown when you have other interrupts active. This can be solved by reading the Timer first and adding to your new value like: Code: | #INT_TIMER0
void timer0_isr()
{
set_timer0(46004 + get_timer(0));
if (a) a--;
if (b) b--;
if (c) c--;
if (d) d--;
} |
|
|
|
muhibraza1
Joined: 26 Jul 2013 Posts: 23
|
|
Posted: Thu Jun 25, 2015 1:29 am |
|
|
Thank you all for you valuable guidance.... _________________ PCWHD Compiler v4.124
ICD U-64 Hardware Rev 2 & 3
CCSLOAD 4.053 |
|
|
guy
Joined: 21 Oct 2005 Posts: 297
|
|
Posted: Thu Oct 19, 2017 1:44 pm |
|
|
Hi! I once made a 60-channel PWM controller and wanted to get the highest, most efficient timing. Turning to assembly improved the efficiency significantly. You can adapt it to your needs.
Code: |
byte rgbISR[70]; // RGB array (global)
short tmr2flag=0; // set on every int.call
#INT_TIMER2
void tmr2isr() {
byte b;
// do one PWM period and handle all channels' PWM
// execution time: 2ms for 255 steps
for(b=RESOLUTION;b>0;b--) {
#asm
movf b,w
// LED 1
cpfslt rgbISR[0]
bsf (PIN_H3>>3),(PIN_H3&7)
cpfslt rgbISR[1]
bsf (PIN_E1>>3),(PIN_E1&7)
cpfslt rgbISR[2]
bsf (PIN_E0>>3),(PIN_E0&7)
// LED 2
cpfslt rgbISR[3]
bsf (PIN_G0>>3),(PIN_G0&7)
cpfslt rgbISR[4]
bsf (PIN_G3>>3),(PIN_G3&7)
cpfslt rgbISR[5]
bsf (PIN_G4>>3),(PIN_G4&7)
// LED 3
cpfslt rgbISR[6]
bsf (PIN_F6>>3),(PIN_F6&7)
cpfslt rgbISR[7]
bsf (PIN_F5>>3),(PIN_F5&7)
cpfslt rgbISR[8]
bsf (PIN_F4>>3),(PIN_F4&7)
...
#endasm
}
exitISR:
tmr2flag=1;
#asm
clrf 0xF89 // clear port latches
clrf 0xF8A
clrf 0xF8B
clrf 0xF8C
clrf 0xF8D
clrf 0xF8E
clrf 0xF8F
clrf 0xF90
clrf 0xF91
#endasm
} |
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9244 Location: Greensville,Ontario
|
|
Posted: Thu Oct 19, 2017 2:18 pm |
|
|
GUY points out a very important point.
Any 'high level' language like C can have several ways to code an 'tak' or 'operation' or 'function'. Some will be fast, some use little memory,etc. so if you never look at the listing you'll never see HOW a task is reduced to machine code.
When using assembler, you tend to be very 'close' to the PIC and can see how to create more efficient code.
In the past I've had to 'merge' assembler into C or BASIC to get the performance I needed. CCS does allow this as well.
Jay |
|
|
|