gramo
New Member
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
The result;
**broken link removed**
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
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;
**broken link removed**
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