![]() |
![]() |
![]() |
|
|
|||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
|
|
Thread Tools | Display Modes |
|
|
(permalink) |
|
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
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 |
|
|
|
|
|
|
(permalink) |
|
I understand you are using Swordfish as your compiler...but what program are you using to simulate you circuit??
Thx |
|
|
|
|
|
|
(permalink) |
|
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 |
|
|
|
|
|
|
(permalink) |
|
Thx, and how is that Swordfish compiler working for you?? Do you like it so far??
|
|
|
|
|
|
|
(permalink) |
|
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. |
|
|
|
|
|
|
(permalink) |
|
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 |
|
|
|
|
|
|
(permalink) |
|
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
__________________
Spency. PIC Micro's - Your mind is the limit PIC's and interfacing with other devices - a PIC Basic Guide @ digital-diy.net |
|
|
|
|
|
|
(permalink) |
|
Oh, you've got to be kidding?
Isn't there a way to look at the intermediate assembly code like I do with C18? |
|
|
|
|
|
|
(permalink) |
|
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 |
|
|
|
|
|
|
(permalink) |
|
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 |
|
|
|
|
|
|
(permalink) |
|
Anytime
__________________
Spency. PIC Micro's - Your mind is the limit PIC's and interfacing with other devices - a PIC Basic Guide @ digital-diy.net |
|
|
|
|
| Bookmarks |
| Thread Tools | |
| Display Modes | |
|
|
|
|
||||
| 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 |