I don't understand how to program the timer and how to measure the time in seconds or miliseconds. So, what does the prescaler do and how do I read the timevalue. I assume you need TMR1H and TMR1L for that.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
A few basic facts:
- The timer counts CPU clock cycles
- The timer overflow interrupt event occurs when the timer goes from 255 to 0 (8 bit timers), or from 65535 to 0 (16 bit timers)
- The prescaler divides the number of CPU clock cycles the timer sees.
I've not tried it, but this code should be suitable for keeping track of time:
#chip 16F88, 8
#config osc = int
Dim TenthSeconds As Word
TenthSeconds = 0
'Clock pulse frequency is 8/4 = 2 MHz
'Divided by 4 by prescaler (PS1_1/4), timer incremented at frequency of 0.50 MHz
' = every 2 us
' If cleared, timer overflows after 65535 * 2 us = every 131.07 ms
InitTimer1 Osc, PS1_1/4
StartTimer 1
On Interrupt Timer1Overflow Call IncCounter
Do
'Main code
'Do something useful with TenthSeconds here
Loop
Sub IncCounter
' Timer will overflow after 131.07 ms
' We need it to overflow after 100.00, so the timer must have a value loaded into it
' Need to load TMR1H, TMR1L with value that they will have after 31.07 ms - then it will count to 131.07, taking 100.00 ms
' Value = 65535 * (31.07 / 131.07) = 15535
' High byte of this is 60, low byte is 175 (60 * 256 + 175 = 15535)
' So, we need to set TMR1H to 60 and TMR1L to 175.
' If you're not comfortable with high and low bytes, put 15535 into a word variable (say TempVar)
' Then, set TMR1L to TempVar, and TMR1H to TempVar_H - this makes the compiler split the number up
TMR1L = 0 'Need to do this according to the PIC datasheet
TMR1H = 60
TMR1L = 175
'Increment the counter
TenthSeconds += 1
end sub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I attempted to compile the above program and had a syntax error on line 14. I could not find "on interrupt" in the manual. I think I have the latest version of the program.
Is there a syntax error, updated manual? Or is Version: 0.9 10/2/2007 the latest version?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The on interrupt command will be found in GCBasic folder/?GCBasic(compiled html help file). For IE7 had to uncheck the always ask box in order for the html link to work.
Hughes example compiled fine in the latest Version GCBasic 0930, wouldn't hurt to load the 'update zip' either. If there is still a syntax problem, then post your code, so that it can be checked for errors.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The code is posted here, I pulled it and tried to compile it. So I must have an old copy of the compiler. I pulled from this site. gcbasic.sourceforge.com was not there for me all day though I could get to sourceforge.com. Will try there again.
I just unzipped the program in a directory and I wrote a batch file to call gcbasic with the /d: to point to the support files. I did not do a windows install or use and IDE. Did not see a reason for all that. Just want to convert a gcbasic file to asm.
Where can I get the latest code? All the update.zip links were down this morning, that is why I pulled it from here.
Also, is there a switch to throw the gcbasic lines in front of the macro expansion as a comment, then I can use mplabs or something like it to debug the code and see my gcbasic lines as a comment
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hey, thanks!
This is great info… I wonder why no one has replied to it.
I was looking for a way of having a program run for a couple of minutes and then making it go to sleep. This is very much what I was looking up, but had some strange results.
I implemented it using a 12F629 with a clock frequency of 4MHz and a prescaler value of 1/8.
I copied/pasted/modified your code as follows:
#chip 12F629,4
#config osc = int
Dim HalfSeconds As Word
HalfSeconds = 0
'Clock pulse frequency is 4/4 = 1 MHz
'Divided by 8 by prescaler (PS1_1/8), timer incremented at frequency of 0.125 MHz
' = every 8 us
' If cleared, timer overflows after 65535 * 8 us = every 524.28 ms
InitTimer1 Osc, PS1_1/8
StartTimer 1
On Interrupt Timer1Overflow Call IncCounter
Do
'Main code
'(blinks an LED)
if HalfSeconds < 120 goto nothingyet 'keep looping if less than a minute
asm sleep
nothingyet:
Loop
Sub IncCounter
' Timer will overflow after 524.28 ms
' We need it to overflow after 500.00 ms, so the timer must have a value loaded into it
' Need to load TMR1H, TMR1L with value that they will have after 24.28 ms - then it will count to 524.28, taking 500.00 ms
' Value = 65535 * (24.28 / 524.28) = 3035
' High byte of this is 11, low byte is 219 (11 * 256 + 219 = 3035)
' So, we need to set TMR1H to 11 and TMR1L to 219.
' If you're not comfortable with high and low bytes, put 3035 into a word variable (say TempVar)
' Then, set TMR1L to TempVar, and TMR1H to TempVar_H - this makes the compiler split the number up
TMR1L = 0 'Need to do this according to the PIC datasheet_ <-- I was not sure about this one but left it in anyway_
TMR1H = 11
TMR1L = 219
'Increment the counter
HalfSeconds = HalfSeconds + 1 ' the graphical gcbasic editor changed the original HalfSeconds += 1 to this form…
end sub
That is just the way I programmed into the 12F629, and it worked just fine; the LED blinked for about a minute and then the chip would go to sleep.
My problem is that when I measured the actual time it took for it to go to sleep it was just 51 seconds.
At first I thought it had something to do with the numbers I input into the H and L timers to compensate for the 24.28 ms difference in overflow. I tried changing the values but nothing noticeable came up… I even changed those values in TMR1H and TMR1L to zero and couldn't find any difference.
I'm not sure how this is supposed to work, but my guess is that those values should be input into the H and L values of the timer every time it overflows, and the way I see it in the program is that they are updated every time the subroutine is called… Anywho, I tried changing that but couldn't figure out how to tell it to update it only when overflowing.
I tried changing other things and the only way I could get the program to go to sleep after a minute was by changing the value HalfSeconds was compared to from 120 to 142 (!)
I would appreciate any help and comments on this and on what I might be doing wrong (or if there's any simpler way of doing it)..
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I don't understand how to program the timer and how to measure the time in seconds or miliseconds. So, what does the prescaler do and how do I read the timevalue. I assume you need TMR1H and TMR1L for that.
A few basic facts:
- The timer counts CPU clock cycles
- The timer overflow interrupt event occurs when the timer goes from 255 to 0 (8 bit timers), or from 65535 to 0 (16 bit timers)
- The prescaler divides the number of CPU clock cycles the timer sees.
I've not tried it, but this code should be suitable for keeping track of time:
#chip 16F88, 8
#config osc = int
Dim TenthSeconds As Word
TenthSeconds = 0
'Clock pulse frequency is 8/4 = 2 MHz
'Divided by 4 by prescaler (PS1_1/4), timer incremented at frequency of 0.50 MHz
' = every 2 us
' If cleared, timer overflows after 65535 * 2 us = every 131.07 ms
InitTimer1 Osc, PS1_1/4
StartTimer 1
On Interrupt Timer1Overflow Call IncCounter
Do
'Main code
'Do something useful with TenthSeconds here
Loop
Sub IncCounter
' Timer will overflow after 131.07 ms
' We need it to overflow after 100.00, so the timer must have a value loaded into it
' Need to load TMR1H, TMR1L with value that they will have after 31.07 ms - then it will count to 131.07, taking 100.00 ms
' Value = 65535 * (31.07 / 131.07) = 15535
' High byte of this is 60, low byte is 175 (60 * 256 + 175 = 15535)
' So, we need to set TMR1H to 60 and TMR1L to 175.
' If you're not comfortable with high and low bytes, put 15535 into a word variable (say TempVar)
' Then, set TMR1L to TempVar, and TMR1H to TempVar_H - this makes the compiler split the number up
TMR1L = 0 'Need to do this according to the PIC datasheet
TMR1H = 60
TMR1L = 175
'Increment the counter
TenthSeconds += 1
end sub
I attempted to compile the above program and had a syntax error on line 14. I could not find "on interrupt" in the manual. I think I have the latest version of the program.
Is there a syntax error, updated manual? Or is Version: 0.9 10/2/2007 the latest version?
The on interrupt command will be found in GCBasic folder/?GCBasic(compiled html help file). For IE7 had to uncheck the always ask box in order for the html link to work.
Hughes example compiled fine in the latest Version GCBasic 0930, wouldn't hurt to load the 'update zip' either. If there is still a syntax problem, then post your code, so that it can be checked for errors.
The code is posted here, I pulled it and tried to compile it. So I must have an old copy of the compiler. I pulled from this site. gcbasic.sourceforge.com was not there for me all day though I could get to sourceforge.com. Will try there again.
I just unzipped the program in a directory and I wrote a batch file to call gcbasic with the /d: to point to the support files. I did not do a windows install or use and IDE. Did not see a reason for all that. Just want to convert a gcbasic file to asm.
Where can I get the latest code? All the update.zip links were down this morning, that is why I pulled it from here.
Also, is there a switch to throw the gcbasic lines in front of the macro expansion as a comment, then I can use mplabs or something like it to debug the code and see my gcbasic lines as a comment
What do the hi and low bytes do? How do they work?
Hey, thanks!
This is great info… I wonder why no one has replied to it.
I was looking for a way of having a program run for a couple of minutes and then making it go to sleep. This is very much what I was looking up, but had some strange results.
I implemented it using a 12F629 with a clock frequency of 4MHz and a prescaler value of 1/8.
I copied/pasted/modified your code as follows:
#chip 12F629,4
#config osc = int
Dim HalfSeconds As Word
HalfSeconds = 0
'Clock pulse frequency is 4/4 = 1 MHz
'Divided by 8 by prescaler (PS1_1/8), timer incremented at frequency of 0.125 MHz
' = every 8 us
' If cleared, timer overflows after 65535 * 8 us = every 524.28 ms
InitTimer1 Osc, PS1_1/8
StartTimer 1
On Interrupt Timer1Overflow Call IncCounter
Do
'Main code
'(blinks an LED)
if HalfSeconds < 120 goto nothingyet 'keep looping if less than a minute
asm sleep
nothingyet:
Loop
Sub IncCounter
' Timer will overflow after 524.28 ms
' We need it to overflow after 500.00 ms, so the timer must have a value loaded into it
' Need to load TMR1H, TMR1L with value that they will have after 24.28 ms - then it will count to 524.28, taking 500.00 ms
' Value = 65535 * (24.28 / 524.28) = 3035
' High byte of this is 11, low byte is 219 (11 * 256 + 219 = 3035)
' So, we need to set TMR1H to 11 and TMR1L to 219.
' If you're not comfortable with high and low bytes, put 3035 into a word variable (say TempVar)
' Then, set TMR1L to TempVar, and TMR1H to TempVar_H - this makes the compiler split the number up
TMR1L = 0 'Need to do this according to the PIC datasheet_ <-- I was not sure about this one but left it in anyway_
TMR1H = 11
TMR1L = 219
'Increment the counter
HalfSeconds = HalfSeconds + 1 ' the graphical gcbasic editor changed the original HalfSeconds += 1 to this form…
end sub
That is just the way I programmed into the 12F629, and it worked just fine; the LED blinked for about a minute and then the chip would go to sleep.
My problem is that when I measured the actual time it took for it to go to sleep it was just 51 seconds.
At first I thought it had something to do with the numbers I input into the H and L timers to compensate for the 24.28 ms difference in overflow. I tried changing the values but nothing noticeable came up… I even changed those values in TMR1H and TMR1L to zero and couldn't find any difference.
I'm not sure how this is supposed to work, but my guess is that those values should be input into the H and L values of the timer every time it overflows, and the way I see it in the program is that they are updated every time the subroutine is called… Anywho, I tried changing that but couldn't figure out how to tell it to update it only when overflowing.
I tried changing other things and the only way I could get the program to go to sleep after a minute was by changing the value HalfSeconds was compared to from 120 to 142 (!)
I would appreciate any help and comments on this and on what I might be doing wrong (or if there's any simpler way of doing it)..