UART TOOL
Moderators: David Barker, Jerry Messina
Thanks
Thanks a bunch Jerry. I will play with the software timer stuff and see if I can figure it out. Really all I need to do is run a counter in the background incremented off the timer, and compare it on timeout to a known value. If it matches then I can do something and start counting again. Waiting to process the packets after the DelayMS is finished won't work for me.
-
- Swordfish Developer
- Posts: 1473
- Joined: Fri Jan 30, 2009 6:27 pm
- Location: US
You can also setup a timer to free run and just use a polling method. This works best if you set the timer to work in 16-bit mode. TMR0 gives the longest duration since it has a 1:256 prescaler, but it also works with timers 1 and 3 (but they only have a 1:8 prescaler).
Using this method you can have a max timeout of up to 65536 counts, which can be quite a while depending on the clock rate and prescaler setting. For example, with a 40MHz clock TMR0 using a prescaler of 1:256 gives a count rate of 100ns * 256 = 25.6us. Since the 16-bit timer wraps every 65536 counts, the max delay is 65536 * 25.6us = 1.677 secs. This code snippet uses TMR0 and the timer macros shown below.
tmr16.bas
Using this method you can have a max timeout of up to 65536 counts, which can be quite a while depending on the clock rate and prescaler setting. For example, with a 40MHz clock TMR0 using a prescaler of 1:256 gives a count rate of 100ns * 256 = 25.6us. Since the 16-bit timer wraps every 65536 counts, the max delay is 65536 * 25.6us = 1.677 secs. This code snippet uses TMR0 and the timer macros shown below.
Code: Select all
include "tmr16.bas"
//
// read tick timer
//
function get_ticks() as word
read_tmr16(0, result)
end function
//
// main code
//
dim start_time, elap_time, timeout as word
dim exit_condition as boolean
// setup TMR0 for 16-bit internal counter, 1:256 prescaler, and turn it on
T0CON = %10000111
exit_condition = false
timeout = 10 // number of counts to wait
// record the start time
start_time = get_ticks()
repeat
// do some stuff
// you can use 'break' to exit the loop if you like
if (exit_condition = true) then
break
endif
elap_time = get_ticks() - start_time
until (elap_time > timeout)
tmr16.bas
Code: Select all
//
//-----------------------------------------------------------------
// read/write 16-bit timer macros
//-----------------------------------------------------------------
//
module timer16
// SF CheckParam() macro constants
public const
cpConst = $01,
cpVariable = $02,
cpArray = $04,
cpSize01 = $08,
cpSize08 = $10,
cpSize16 = $20,
cpSize32 = $40,
cpInteger = $0100,
cpReal = $0200,
cpString = $0400,
cpChar = $0800,
cpBoolean = $1000,
etError = 0,
etWarning = 1,
etMessage = 2,
etHint = 3
// write 16-bit timer specified by 'tmr' with the value 'wval'
public macro write_tmr16(tmr, wval)
if (tmr = 0) then
TMR0H = (wval >> 8)
TMR0L = byte(wval)
elseif (tmr = 1) then
TMR1H = (wval >> 8)
TMR1L = byte(wval)
elseif (tmr = 3) then
TMR3H = (wval >> 8)
TMR3L = byte(wval)
else
CheckParam(etError, "unsupported TMR select")
endif
end macro
// reads 16-bit timer specified by 'tmr', stores it in 'wresult'
public macro read_tmr16(tmr, wresult)
if (tmr = 0) then
wresult.byte0 = TMR0L
wresult.byte1 = TMR0H
elseif (tmr = 1) then
wresult.byte0 = TMR1L
wresult.byte1 = TMR1H
elseif (tmr = 3) then
wresult.byte0 = TMR3L
wresult.byte1 = TMR3H
else
CheckParam(etError, "unsupported TMR select")
endif
end macro
end module
Timer Example Attempt
Hi,
I threw a simple test together after reading the examples everyone posted and what I could find elsewhere. Below is a simple program that is suppose to toggle the RED LED every second, and the GREEN LED every 5 Seconds. Any idea why I see no LEDS toggle ?
Thanks
Device = 18F25J10 // Setup the device/clock information
Clock = 8
Config FOSC = HSPLL
Config FOSC2 = ON
Config CP0 = OFF // Turn Code Protect On And Off
Include "ISRTimer.bas"
Include "utils.bas"
Const Timer1 = 0
Dim RED_LED As PORTC.2
Dim GREEN_LED As PORTC.1
Dim PreScaler As Word
Dim SecCount As Word
Dim DelayTime As Word
#option TIMER_PRIORITY = ipLow
#option TIMER_AUTO_RELOAD = true
Event LEDFlash()
Toggle(RED_LED)
SecCount = SecCount + 1000
End Event
Timer.Initialize(Timer1)
Timer.Items(Timer1).Interval = 1000 ' Approx 1Second
Timer.Items(Timer1).OnTimer = @LEDFlash // timer1 event handler
Timer.Start
SecCount = 0
'PreScaler = 0
DelayTime = 5000 ' Time To Compare Too
While true
Timer.Items(Timer1).Enabled = True // Enable Timer1 event
If SecCount = DelayTime Then
Toggle(GREEN_LED)
SecCount = 0
End If
Wend
I threw a simple test together after reading the examples everyone posted and what I could find elsewhere. Below is a simple program that is suppose to toggle the RED LED every second, and the GREEN LED every 5 Seconds. Any idea why I see no LEDS toggle ?
Thanks
Device = 18F25J10 // Setup the device/clock information
Clock = 8
Config FOSC = HSPLL
Config FOSC2 = ON
Config CP0 = OFF // Turn Code Protect On And Off
Include "ISRTimer.bas"
Include "utils.bas"
Const Timer1 = 0
Dim RED_LED As PORTC.2
Dim GREEN_LED As PORTC.1
Dim PreScaler As Word
Dim SecCount As Word
Dim DelayTime As Word
#option TIMER_PRIORITY = ipLow
#option TIMER_AUTO_RELOAD = true
Event LEDFlash()
Toggle(RED_LED)
SecCount = SecCount + 1000
End Event
Timer.Initialize(Timer1)
Timer.Items(Timer1).Interval = 1000 ' Approx 1Second
Timer.Items(Timer1).OnTimer = @LEDFlash // timer1 event handler
Timer.Start
SecCount = 0
'PreScaler = 0
DelayTime = 5000 ' Time To Compare Too
While true
Timer.Items(Timer1).Enabled = True // Enable Timer1 event
If SecCount = DelayTime Then
Toggle(GREEN_LED)
SecCount = 0
End If
Wend
-
- Registered User
- Posts: 185
- Joined: Mon Mar 10, 2008 8:20 am
- Location: Seattle, WA USA
- Contact:
-
- Swordfish Developer
- Posts: 1473
- Joined: Fri Jan 30, 2009 6:27 pm
- Location: US
In addition to what Jon's pointed out...
You have to have any '#option' statements BEFORE the module is included, so change it to
The parameter for Timer.Initialize() is the total number of timers you want... in this case it should be 'Timer.Initialize(1)' instead of 'Timer.Initialize(Timer1)', which is telling it you want 0 timers. You can leave the parameter out and it will default to creating 4 timers, or set '#option TIMER_AVAILABLE'
Move the line 'SecCount = 0' to before Timer.Start() so it is cleared before the timers start running.
You have to have any '#option' statements BEFORE the module is included, so change it to
Code: Select all
#option TIMER_PRIORITY = ipLow
#option TIMER_AUTO_RELOAD = true
Include "ISRTimer.bas"
Include "utils.bas"
Move the line 'SecCount = 0' to before Timer.Start() so it is cleared before the timers start running.
You are starting to get into the realm of what is known as multi-tasking. You have two tasks - one to toggle the Red LED every second and the other to toggle the Green LED every 5 seconds. As you have found it can get quite tricky to do it right. It is easy to get a single task going. However adding tasks is difficult. The best way to do this is to use an RTOS (real-time operating system). Using an RTOS, each task runs independently of others. Here is a pseudo-code example of how your program would be if using an RTOS.
If you want to add another task - say toggle a Blue LED every 2.5 seconds - then all you would need to do is create another task:
In fact, the number of tasks that can run concurrently is limited by RAM in the MCU and can run into thousands. There are several free RTOS available. Unfortunately I do not know of any that is available for BASIC - all of them written for C.
Code: Select all
include "RTOS"
task blink_Red
while true
toggle LED_Red
OSDelay_ms(1000)
end while
end task
task blink_Green
while true
toggle LED_Green
OSDelay_ms(5000)
end while
end task
main:
create_Task(blink_Red)
create_Task(blink_Green)
while true
RTOS(run_scheduler)
end while
end
Code: Select all
task blink_Blue
while true
toggle LED_Blue
OSDelay_ms(2500)
end while
end task
Why use 8 bits when you can have 32?
ARM CORTEX Rules!!!
ARM CORTEX Rules!!!
Hi Guys,
Thanks a bunch for the help. I made a few tweaks but still no LED toggle. I changed the code to turn on the red LED on the first timer interrupt and also to tuen on the green in 5 interruputs and hold them in this state. I still do not see LED's turn on. Any ideas ? This should not be this hard. I hope it is just me being naive.
Thanks
Device = 18F25J10 // Setup the device/clock information
Clock = 8
Config FOSC = HSPLL
Config FOSC2 = ON
Config CP0 = OFF // Turn Code Protect On And Off
#option TIMER_PRIORITY = ipLow
#option TIMER_AUTO_RELOAD = true
Include "ISRTimer.bas"
Include "utils.bas"
Const Timer1 = 0
Dim RED_LED As PORTC.2
Dim GREEN_LED As PORTC.1
Dim PreScaler As Word
Dim SecCount As Word
Dim DelayTime As Word
Event LEDFlash()
Low(RED_LED)
SecCount = SecCount + 1000
End Event
SecCount = 0
DelayTime = 5000 ' Time To Compare Too
Timer.Initialize(Timer1)
Timer.Items(Timer1).Interval = 1000 ' Approx 1Second
Timer.Items(Timer1).OnTimer = @LEDFlash // timer1 event handler
Timer.Start
While true
Timer.Items(Timer1).Enabled = True // Enable Timer1 event
If SecCount = DelayTime Then
Low(GREEN_LED)
SecCount = 0
End If
Wend
Thanks a bunch for the help. I made a few tweaks but still no LED toggle. I changed the code to turn on the red LED on the first timer interrupt and also to tuen on the green in 5 interruputs and hold them in this state. I still do not see LED's turn on. Any ideas ? This should not be this hard. I hope it is just me being naive.
Thanks
Device = 18F25J10 // Setup the device/clock information
Clock = 8
Config FOSC = HSPLL
Config FOSC2 = ON
Config CP0 = OFF // Turn Code Protect On And Off
#option TIMER_PRIORITY = ipLow
#option TIMER_AUTO_RELOAD = true
Include "ISRTimer.bas"
Include "utils.bas"
Const Timer1 = 0
Dim RED_LED As PORTC.2
Dim GREEN_LED As PORTC.1
Dim PreScaler As Word
Dim SecCount As Word
Dim DelayTime As Word
Event LEDFlash()
Low(RED_LED)
SecCount = SecCount + 1000
End Event
SecCount = 0
DelayTime = 5000 ' Time To Compare Too
Timer.Initialize(Timer1)
Timer.Items(Timer1).Interval = 1000 ' Approx 1Second
Timer.Items(Timer1).OnTimer = @LEDFlash // timer1 event handler
Timer.Start
While true
Timer.Items(Timer1).Enabled = True // Enable Timer1 event
If SecCount = DelayTime Then
Low(GREEN_LED)
SecCount = 0
End If
Wend
- David Barker
- Swordfish Developer
- Posts: 1214
- Joined: Tue Oct 03, 2006 7:01 pm
- Location: Saltburn by the Sea, UK
- Contact:
I can see a few mistakes in your code. For example, you have 'low(RED_LED)' in the handler but have not set to OUTPUT as already suggested. You are also initialising the Timer module with 0 timers!
This works on my 452 development board...
This works on my 452 development board...
Code: Select all
Device = 18F452
Clock = 20
#option TIMER_PRIORITY = ipLow
#option TIMER_AUTO_RELOAD = true
Include "ISRTimer.bas"
Const Timer1 = 0
Dim RED_LED As PORTD.0
Event LEDFlash()
Toggle(RED_LED)
End Event
' entry point...
low(RED_LED)
Timer.Initialize
Timer.Items(Timer1).Interval = 1000
Timer.Items(Timer1).OnTimer = LEDFlash
Timer.Items(Timer1).Enabled = True
Timer.Start
// main loop
While true
Wend
Suggestions
Hi Dave,
Thanks for the input. I copied your code and modified it for my part and oscillator, and all I get now is a RED LED on all the time. This is a step in the right direction, but I was wondering if your LED toggles. I guess I am going to have to take baby steps till I can narrow down what is really going on. As far as the suggestions I did try to follow them as close as possible. I was not sure what Jon meant by the OUTPUT statement. There was no reference to it in any examples I could find as to how to do this.
Thanks
Device = 18F25J10
Clock = 8
#option TIMER_PRIORITY = ipLow
#option TIMER_AUTO_RELOAD = true
Include "ISRTimer.bas"
Const Timer1 = 0
Dim RED_LED As PORTC.2
Event LEDFlash()
Toggle(RED_LED)
End Event
' entry point...
low(RED_LED)
Timer.Initialize
Timer.Items(Timer1).Interval = 1000
Timer.Items(Timer1).OnTimer = LEDFlash
Timer.Items(Timer1).Enabled = True
Timer.Start
// main loop
While true
Wend
Thanks for the input. I copied your code and modified it for my part and oscillator, and all I get now is a RED LED on all the time. This is a step in the right direction, but I was wondering if your LED toggles. I guess I am going to have to take baby steps till I can narrow down what is really going on. As far as the suggestions I did try to follow them as close as possible. I was not sure what Jon meant by the OUTPUT statement. There was no reference to it in any examples I could find as to how to do this.
Thanks
Device = 18F25J10
Clock = 8
#option TIMER_PRIORITY = ipLow
#option TIMER_AUTO_RELOAD = true
Include "ISRTimer.bas"
Const Timer1 = 0
Dim RED_LED As PORTC.2
Event LEDFlash()
Toggle(RED_LED)
End Event
' entry point...
low(RED_LED)
Timer.Initialize
Timer.Items(Timer1).Interval = 1000
Timer.Items(Timer1).OnTimer = LEDFlash
Timer.Items(Timer1).Enabled = True
Timer.Start
// main loop
While true
Wend