Wednesday, 24 July 2019
Main Menu
Home Home
Shop Shop
News News
Products Products
Application Notes Application Notes
Publications Publications
Links Links
Support Center Support Center
Downloads Downloads
Forum Forum
Resellers Resellers
Contact Us Contact Us
Updates Updates
MCS Wiki MCS Wiki
Online Help
BASCOM-8051 Help BASCOM-8051 Help
Contents in Cart
Show Cart
Your Cart is currently empty.
Search the Shop

Products Search

User Login


If you have problem after log in with disappeared login data, please press F5 in your browser

RSS News

AN #22 - Two examples about Multi Tasking Print
Multitasking with BASCOM-8051

The following two application notes are provided by David H Lawrence one of our US resellers. As you will find out at David is specialized in Industrial Embedded Processing.

The application note code and another example can be downloaded to

Download file #1
Download file #2


' (c) Copyright 2000 Rhombus Greenville SC
'Code can be used by others providing this header is included in the source.
'Getting started in Real-Time Control using BASCOM Part 1


'For those who have not yet applied themselves to real-time control using 8-bit
' MCU/MPUs, then these notes and segments of code may help you get started.
'Or if you normally avoid Interrupts, then this first part may change that by
' showing how Timer0 can be expanded into as many timers as you wish, and with
' very little code.

'I am experienced with the 51 at assembler level but new to the Bascom compiler.
' What surprises me the most is that despite the convenience of using a
' compiler, it does not appear to be restricting in any way - hence I hope to
' avoid the use of any assembler code.
'Whilst most of what will be described was written a good 15-25 years ago, I
' have checked and it does appear to fit in neatly with present day theory for
' simple real-time control and is classified as 'Co-operative Multi-tasking'.
' There is no forced switching of tasks as with a RTOS, and hence all CPU time
' is devoted to 'getting the job done' and no storage is needed to hold all the
' intermediate states of pre-empted tasks.


'All but the most simple machines require multiple tasks operating in parallel.
' Each task consist of a series of states(steps) with clearly defined logic that
' determines the transition from one state to the next.For example a tank drain
' valve is open, the low level float switch indicates empty but it is known that
' an additional 40 secs needs to be timed for a complete drain and to finally
' close the valve. In parallel a safety locking sequence must be performed on
' another part of the machine before a steam valve is opened.
'It is that sort of parallel control that is easily handled by PLCs where there
' is a continuous loop scanning all Inputs, then based on pre-defined logic so
' each task progresses from one stage(step) to the next and resulting in a new
' set of Outputs. With fast loops of Inputing, Processing and Outputing the
' tasks are effectively being controlled in parallel.
'When I/O is added that cannot be included in that main I/O loop, such as
' operator interfaces and host serial communication, then the software must use
' interrupts to take whatever time is needed from the main I/O loop to service
' the needs of those asynchronous events. It was at this stage of the PLC's
' history that the limitations of relay ladder logic became more than apparent.
' The PLC solutions to handle these new demands were far from elegant,whereas
' for MPU/MPCs the solutions are a natural and can be achieved very simply
' using the Bascom compiler.

'The methods to be described here have handled slow process control as mentioned
' above, and together with both serial & operator interfaces, They have also
' allowed an 11Mhz 8052 to precisely control a knitting machine's 100+ pneumatic
' outputs in perfect sync with needles flying by at 800 per second, and as the
' operator keyed in a new batch and the host collected production data.
'The sharing of CPU time is based on a priority ordered list of tasks and with
' all asyncronous or time critical events being interrupt driven. The main I/O
' tasks are prompted by timer set flags (only one in example) which can also
' serve to distribute CPU demands. Analog inputs can also benefit from using a
' timer rate related to the supply frequency. When each task is completed it
' returns execution to the top of the list.

'Interrupt routines are kept at an absolute minimum and any excessive processing
' needs are off-loaded to the main loop. This holds interrupt service latencies
' to a minimum and avoids the need for either hardware or software priority
' handling to satisfy critical timing issues.

'An example of off-loading interrupt servicing time would be to merely flag the
' timer event shown below, avoid all needs for stacking (it would not change the
' value of any registers, nor even the status flags), and carry out the updates
' in the main loop. For simplicity, the timer ISR below does its processing
' during the interrupt and that will normally be OK but for the most demanding
' applications.
'Timer0 ISR code is very small and should be self explicit. In order to show it
' working there is a main loop using those new timers as inputs, a little logic
' for reloading them, and their run status is output to a set of pins to allow
' scoping. For a steady trace the timers are running very fast at a resolution
' of 2mS. If using the Timer0 expansion code in your own applications then it is
' only a matter of defining a new constant for loading the timer.

'Using P3.5 as a scope trigger will show P3.2.3.4 effectively operating in
' parallel and from the same Timer0.

'Part 2 will add transparent keypad input to change the timer values whilst they
' are running & without affecting their operation until the Enter key finalises
' their new value and they snap to the new timing.


Dim Timers(4) As Byte , Tic_cnt0 As Byte , Isr_temp As Byte , Io_flag As Bit

Const 2ms = -1793  ' (2/1000)*(11059200/12)-50reload

Config Timer0 = Timer , Gate = Internal , Mode = 1 '16 bit,own code reloads
On Timer0 Timer_0_int
Enable Interrupts 'enable the use of interrupts
Enable Timer0

Priority Set Timer0 'highest priority
Counter0 = 2ms
Start Timer0

'----- MAIN LOOP

'Dumb code to show a set of timers (Timer0 expanded) each running with their own
' individual values, and controlling their own output(a port pin) and effectively
' in parallel.

'--Test for I/O prompt
If Io_flag = 1 Then Goto Io_control 'Dummy machine control

'--Test for waiting Host messages 'Nothing currently implemented
'If Msg_flag Then Goto Msg_rtn

'--Test for keypad activity
'If Key_flag Then GoTo Key_rtn



'The 3 stages of Read_Inputs/Process/Write_Outputs
'All inputs here are Timer values and hence readily available internally.
'The processing here is merely to watch for Timers(1) to count down to zero
' and then reset its associated P3.5. On the next pass (when Io_flag is found
' set in the Main_loop) we reload all 4 timers with their individual values &
' set their individual flags.
'All subsequent passes with Timer(1)<>0 has pins P3.2.3.4 updated to reflect
' when their counts have reached zero.
'That is not a separate Output stage as such, but if we had remote I/O then
' the equivalents of P3.2.. would be internal bits and once all processing
' was complete, we would output them as a distinct & separate operation as in
' a PLC.
= 0
If Timers(1) = 0 Then
If P3.5 = 1 Then 'Dont restart till 1 pass later
Reset P3.5
(1) = 20 : Set P3.5
(2) = 15 : Set P3.2
(3) = 10 : Set P3.3
(4) = 5 : Set P3.4
End If
If Timers(2) = 0 Then Reset P3.2 'Could avoid multiple resets
If Timers(3) = 0 Then Reset P3.3 ' but no real savings
If Timers(4) = 0 Then Reset P3.4
End If
Goto Main_loop

'We return at the highest priority level ignoring the tasks below this one
' but know that they will be reached on the next pass, now that the Io_flag
' is reset. *Except* if the interval set between scans is not realistic: eg
' if the Control routines take 50mS and the Io_flag is set every 40mS then

' all other functions will be blocked out. Timing the different functions in
' the Main_loop and allocating realistic intervals is not a difficult task.


'On-chip Timer0 over-flow interrupts steal insignificant slices of CPU time in
' order to update any number of independent timers. The timer values halt at zero
' thereby doubling as 'Done' flags. Where timing ranges cannot be covered by
' single byte values it may be more economical to group them with multiple
' Tic_cnts in preference to expanding all timers to use multiple bytes.

Counter0 = 2ms
Start Timer0
Set Io_flag
Inc Tic_cnt0
If Tic_cnt0 => 1 Then '1=2mS for easy scoping
= 0 '5/50 =10mS/100mS more typical
For Isr_temp = 1 To 4
If Timers(isr_temp) <> 0 Then Decr Timers(isr_temp)
'If Timers(0) <> 0 Then Decr Timers(0) 'Alternatively trade code size
'If Timers(1) <> 0 Then Decr Timers(1) ' for speed
'If Timers(2) <> 0 Then Decr Timers(2)
'If Timers(3) <> 0 Then Decr Timers(3)
End If