UART TOOL

Coding and general discussion relating to user created compiler modules

Moderators: David Barker, Jerry Messina

Widgetman
Posts: 136
Joined: Sun Dec 16, 2007 7:39 pm
Location: Florida

Thanks

Post by Widgetman » Mon Mar 14, 2011 11:51 am

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.

Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Mon Mar 14, 2011 2:35 pm

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.

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

Widgetman
Posts: 136
Joined: Sun Dec 16, 2007 7:39 pm
Location: Florida

Timer Example Attempt

Post by Widgetman » Mon Mar 14, 2011 5:21 pm

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

Jon Chandler
Registered User
Registered User
Posts: 185
Joined: Mon Mar 10, 2008 8:20 am
Location: Seattle, WA USA
Contact:

Post by Jon Chandler » Mon Mar 14, 2011 5:38 pm

You need to configure the port pins as outputs. The simple way is to add:

Output(Red_LED)
Output(Green_LED)

I believe if you set a condition (i.e., LOW(Red_LED) this is handled automatically but not so with the toggle command.
Jon

Check out the TAP-28 PIC Application board at http://www.clever4hire.com/throwawaypic/

Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Mon Mar 14, 2011 5:47 pm

In addition to what Jon's pointed out...

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" 
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.

rmteo
Posts: 237
Joined: Fri Feb 29, 2008 7:02 pm
Location: Colorado, USA

Post by rmteo » Mon Mar 14, 2011 5:54 pm

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.

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
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:

Code: Select all

task blink_Blue
  while true
    toggle LED_Blue
    OSDelay_ms(2500)
  end while
end 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.
Why use 8 bits when you can have 32?
ARM CORTEX Rules!!! :D :D :D

Widgetman
Posts: 136
Joined: Sun Dec 16, 2007 7:39 pm
Location: Florida

Post by Widgetman » Mon Mar 14, 2011 7:53 pm

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

User avatar
David Barker
Swordfish Developer
Posts: 1214
Joined: Tue Oct 03, 2006 7:01 pm
Location: Saltburn by the Sea, UK
Contact:

Post by David Barker » Mon Mar 14, 2011 8:11 pm

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...

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 

Widgetman
Posts: 136
Joined: Sun Dec 16, 2007 7:39 pm
Location: Florida

Suggestions

Post by Widgetman » Mon Mar 14, 2011 8:22 pm

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

Post Reply