Electronic Projects, forums and more.

Go Back   Electronic Circuits Projects Diagrams Free > Electronics Categories > Micro Controllers


Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc.

Reply
 
Thread Tools Display Modes
Old 2nd May 2007, 02:10 PM   (permalink)
Default PIC's multi-tasking

Well I'm still playing with Swordfish, and am simply loving it, my latest little app 'multi-tasks' a bunch of tasks together, but servicing each at certain timed intervals.

The 4 tasks in this example are (chosen at random as examples);

* Check if a Button is pressed, and increment a counter on an LCD
* Update the current time on the LCD
* Frequency Generator 1
* Frequency Generator 2

You wouldn’t want to check if the button was pressed every mS, or else it would increment the counter at phenomenal speeds, but you would want to sample it faster than each update of the current time on the LCD.

The two frequency generators were just addons to display how more tasks can be added, and yet maintain excellent timing. With all this in mind, the following task intervals were chosen;


Check Button & Update Counter: 500mS
Update Current Time: 1000mS
Frequency Generator 1: 100mS
Frequency Generator 2: 5mS

Code:
Device = 18F452
Clock = 20

#option LCD_DATA = PORTD.4
#option LCD_RS = PORTE.0
#option LCD_EN = PORTE.1

Include "LCD.bas" 
Include "utils.bas"
Include "convert.bas"

Dim 
    TMR2_Int_Enable As PIE1.1,    // TMR2 interrupt enable
    TMR2_Overflow As PIR1.1,      // TMR2 overflow flag
    TMR2_On As T2CON.2,           // Enables TMR2 to begin incrementing
    mS As Word,                   // Time Registers
    S As Byte,                    //
    M As Byte,                    //
    H As Byte,                    //
    Task_1_Timer As Word,         // Task 1 = Check if button pressed
    Task_2_Timer As Word,         // Update Time on LCD
    Task_3_Timer As Word,         // Frequency output 1
    Task_4_Timer As Word,         // Frequency output 2            
    Task_1 As Boolean,            //
    Task_2 As Boolean,            //
    Task_3 As Boolean,            //
    Task_4 As Boolean,            //
    Example_Counter As Byte,      // Counter register for the button
    Button As PORTA.0             // Assing the button Pin
    
Const
    Task_1_Interval = 500,        // mS interval for button check
    Task_2_Interval = 1000,       // mS interval between time updates
    Task_3_Interval = 100,        // mS interval for frequency output 1
    Task_4_Interval = 5           // mS interval for frequency output 2
    
Interrupt TMR2_Interrupt()
    Save(0)
    If TMR2_Overflow = 1 And TMR2_Int_Enable = 1 Then
        TMR2_Overflow = 0                           // Reset TMR2 Overflow flag
        mS = mS + 1
        If mS = 1000 Then                           // Code for current time
            mS = 0
            S = S + 1
            If S = 60 Then
                S = 0
                M = M + 1
                If M = 60 Then
                    M = 0
                    H = H + 1
                    If H = 24 Then
                        H = 0
                    EndIf
                EndIf
            EndIf
        EndIf
        Task_1_Timer = Task_1_Timer + 1             // Increment all Task handlers
        Task_2_Timer = Task_2_Timer + 1
        Task_3_Timer = Task_3_Timer + 1
        Task_4_Timer = Task_4_Timer + 1                
        If Task_1_Timer = Task_1_Interval Then      // Check if a task interval is
            Task_1_Timer = 0                        //   ready to be flagged
            Task_1 = True
        EndIf
        If Task_2_Timer = Task_2_Interval Then
            Task_2_Timer = 0        
            Task_2 = True
        EndIf               
        If Task_3_Timer = Task_3_Interval Then
            Task_3_Timer = 0        
            Task_3 = True
        EndIf 
        If Task_4_Timer = Task_4_Interval Then
            Task_4_Timer = 0        
            Task_4 = True
        EndIf                 
    EndIf
    Restore
End Interrupt

Private Sub TMR2_Initialize()
    TMR2_On = 0               // Disbale TMR2
    TMR2_Int_Enable = 0       // Turn off TMR2 interrupts

    INTCON.6 = 1              // Peripheral Interrupts Enabled       
    T2CON.0 = 1               //  00 = Prescaler is 1
    T2CON.1 = 0               //  01 = Prescaler is 4
            	          	  //  1x = Prescaler is 16 
    PR2 = 249             	  // TMR2 Period register PR2   
    T2CON.3 = 0               //  0000 = 1:1 postscale
    T2CON.4 = 0               //  0001 = 1:2 postscale
    T2CON.5 = 1               //  0010 = 1:3 postscale
    T2CON.6 = 0               //  1111 = 1:16 postscale    
    TMR2 = 0                  // Reset TMR2 Value    
    TMR2_Int_Enable = 1       // Enable TMR2 interrupts
    TMR2_On = 1               // Enable TMR2 to increment
    Enable(TMR2_Interrupt)
End Sub

Private Sub Check_Button()
    If Button = 1 Then
        Example_Counter = Example_Counter + 1
        WriteAt(1,11,DecToStr(Example_Counter,3))
    EndIf
End Sub

Private Sub Update_Time()
    WriteAt(2,7,DecToStr(H,2), ":", DecToStr(M,2), ":", DecToStr(S,2))
End Sub

Private Sub Freqency_Output_1()
    PORTB.0 = 1
    PORTB.0 = 0
End Sub

Private Sub Freqency_Output_2()
    PORTB.1 = 1
    PORTB.1 = 0
End Sub


DelayMS(200)                  // Allow LCD to warm up
SetAllDigital                 // Make all pins digital I/O's
Cls                           // Clear the LCD screen

WriteAt(1,1,"Counter = 000")  // Send text that only needs to be sent once
WriteAt(2,1,"Time:")          //   to the LCD

mS = 0                        // Reset all registers
S = 0                         //
M = 30                        //
H = 12                        //
Example_Counter = 0           //
Task_1_Timer = 0              //
Task_2_Timer = 0              //
Task_3_Timer = 0              //
Task_4_Timer = 0              //
Task_1 = False                //
Task_2 = False                //
Task_3 = False                //
Task_4 = False                //

Input(Button)                 // Make the button an input
Low(PORTB.0)                  // Make frequency 1 signal an output and low
Low(PORTB.1)                  // Make frequency 2 signal an output and low

TMR2_Initialize               // Turn on TMR2 (with settings for 1mS interrupt)


While 1 = 1                   // Main program loop that is multi-tasked
    If Task_1 = True Then
        Task_1 = False
        Check_Button
    EndIf
    If Task_2 = True Then
        Task_2 = False    
        Update_Time
    EndIf
    If Task_3 = True Then
        Task_3 = False    
        Freqency_Output_1
    EndIf
    If Task_4 = True Then
        Task_4 = False    
        Freqency_Output_2
    EndIf        
Wend
The result;

Click here to watch the circuit in action

With the use of task intervals, you can get your PIC doing heaps at the same time, well, appear as if it’s at the same time
__________________
Spency.

PIC Micro's - Your mind is the limit

PIC's and interfacing with other devices - a PIC Basic Guide @ digital-diy.net
gramo is offline   Reply With Quote
Old 3rd May 2007, 02:48 AM   (permalink)
Default

I understand you are using Swordfish as your compiler...but what program are you using to simulate you circuit??

Thx
jbarnaby2000 is offline   Reply With Quote
Old 3rd May 2007, 06:38 AM   (permalink)
Default

A quick check of my examples (or Video tutorial page) would reveal all! The VSM is called Proteus
__________________
Spency.

PIC Micro's - Your mind is the limit

PIC's and interfacing with other devices - a PIC Basic Guide @ digital-diy.net
gramo is offline   Reply With Quote
Old 3rd May 2007, 10:25 AM   (permalink)
Default

Thx, and how is that Swordfish compiler working for you?? Do you like it so far??
jbarnaby2000 is offline   Reply With Quote
Old 3rd May 2007, 11:38 AM   (permalink)
Default

Thank you for the example. Do you think the 'overhead' associated with handling the variables as arrays make it less efficient?

Code:
dim RTC(3)                    ' hrs, mins, secs
dim TMR(3)                    ' hrs, mins, secs
Code:
' within your ISR
'
mS = mS + 1
if mS = 1000 then             ' if 1 second interval
  mS = 0                      ' perform once-per-second operations
  '
  ' increment real-time-clock
  '
  n = 2                       ' index 'seconds' element
  while RTC(n) = 59           ' while element (secs or mins) = 59
    RTC(n) = 0                ' set to 00 and
    n = n - 1                 ' bump index
  wend                        '
  RTC(n) = RTC(n) + 1         ' post increment (secs, mins, or hrs)
  RTC(0) = RTC(0) mod 24      ' change 24:00:00 to 00:00:00
  '
  ' decrement count down timer (photo timer, appliance timer, etc.)
  '
  if TMRON
    n = 2                     ' index 'seconds' element
    while TMR(n) = 0          ' while element (secs or mins) = 00
      TMR(n) = 59             ' set to 59 and
      n = n - 1               ' bump index
    wend                      '
    TMR(n) = TMR(n) - 1       ' post decrement (secs, mins, or hrs)
    if not (TMR(0) | TMR(1) | TMR(2))
      TMRON = 0               ' turn off timer and
                              ' perform timed out function here
    endif
  endif
endif

Last edited by Mike, K8LH; 3rd May 2007 at 11:40 AM.
Mike, K8LH is offline   Reply With Quote
Old 3rd May 2007, 01:00 PM   (permalink)
Default

Not too sure, nice thought though.
__________________
Spency.

PIC Micro's - Your mind is the limit

PIC's and interfacing with other devices - a PIC Basic Guide @ digital-diy.net
gramo is offline   Reply With Quote
Old 3rd May 2007, 01:15 PM   (permalink)
Default

The free version of Swordfish limits you too 200 Variables. A quick way to tell if the code was optimized is to compile it, although not completely accurate, but close enough.

A much more accurate way would be to simulate the program with a simple signal like the following at the start and end of the interrupt routine.

Code:
PORTB.7 = 1
PORTB.7 = 0
Run this with each program variation with an external Timer device similar to the frequency counters shown in the first post, and you could time how long your ISR is
__________________
Spency.

PIC Micro's - Your mind is the limit

PIC's and interfacing with other devices - a PIC Basic Guide @ digital-diy.net
gramo is offline   Reply With Quote
Old 3rd May 2007, 01:19 PM   (permalink)
Default

Oh, you've got to be kidding?

Isn't there a way to look at the intermediate assembly code like I do with C18?
Mike, K8LH is offline   Reply With Quote
Old 3rd May 2007, 01:31 PM   (permalink)
Default

Download it and find out. Of course you can, but that is not going to give you a very accurate overall time scale of the ISR.

I have found the timing method to be the best as some conditions are not met on each interrupt, and in return some code will not run (If statements for example). Now you can form a cumulative average of the time required for your ISR as it goes through different conditions
__________________
Spency.

PIC Micro's - Your mind is the limit

PIC's and interfacing with other devices - a PIC Basic Guide @ digital-diy.net
gramo is offline   Reply With Quote
Old 3rd May 2007, 01:51 PM   (permalink)
Default

I did download it and install it last week after reading your comments (and Bill's) and after taking a quick look through the manual. It does look like an incredibly nice BASIC implementation. Bravo on a nice find....

If it has intermediate assembly files then I'll look at the generated code in there. That's really simpler for me and should show how many instruction cycles 'overhead' associated for accessing the array compared to direct variables.

Thanks, Mike
Mike, K8LH is offline   Reply With Quote
Old 3rd May 2007, 01:55 PM   (permalink)
Default

Anytime
__________________
Spency.

PIC Micro's - Your mind is the limit

PIC's and interfacing with other devices - a PIC Basic Guide @ digital-diy.net
gramo is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes


Similar Threads
Thread Thread Starter Forum Replies Latest
PICs and DAC/ADC and other basic questions ChemE Micro Controllers 9 28th April 2007 03:26 AM
Where to buy PICs in the UK?? 2camjohn Micro Controllers 1 7th March 2005 06:00 PM
PIC Programmer with 18F PICs Timmymna Micro Controllers 5 22nd October 2004 12:44 PM
I am interested in PiCs but dont know much about them cubdh23 Micro Controllers 2 10th July 2004 07:07 AM
Multi Tasking...Sort of 2camjohn Micro Controllers 5 9th April 2004 01:10 PM



All times are GMT. The time now is 02:33 AM.


Electronic Circuits  |  Electronics Wiki
Powered by vBulletin® Version 3.7.0
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.