View previous topic :: View next topic |
Author |
Message |
goussepi
Joined: 11 Jan 2006 Posts: 6
|
help with timer1 pic18f452 |
Posted: Wed Jan 11, 2006 2:47 pm |
|
|
There is my problem, the isr is run every time TMR1L reaches 255, is this normal ? i'd like it to be run only when it reaches 65535.
Code: |
#include<18f452.h>
#use delay (clock = 20000000)
int32 z;
#int_timer1
void tmr1_isr()
{
z=0;
}
void main()
{
setup_timer_1(T1_INTERNAL);
enable_interrupts(GLOBAL);
enable_interrupts(int_timer1);
while(1)
{
}
}
|
|
|
|
MikeValencia
Joined: 04 Aug 2004 Posts: 238 Location: Chicago
|
|
Posted: Wed Jan 11, 2006 6:00 pm |
|
|
TMR1 is a 16-bit timer; thus it will overflow and run the ISR when
TMR1H:TMR1L transitions from 0xFFFF ---> 0x0000
As you can see, TMR1L will be 0xFF (255).
It will not interrupt in the following transition, e.g.
0x00FF --> 0x0100. |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1634 Location: Perth, Australia
|
|
Posted: Wed Jan 11, 2006 7:25 pm |
|
|
You did not set up a divisor. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
goussepi
Joined: 11 Jan 2006 Posts: 6
|
|
Posted: Thu Jan 12, 2006 1:46 am |
|
|
I know this sound weird but it's exactly what it does , the transition is 0x00ff->0x0000, i tried to force the register TMR1H to 0xFF and the result is 0xffff->0xff00, i tried to set a divisor, no changes. It happens on two different computer with two different version of mplab and CCS, there is either something missing in the code, or it's from the 18f452.h file.
Code: |
////////////////////////////////////////////////////////////////// Timer 1
// Timer 1 Functions: SETUP_TIMER_1, GET_TIMER1, SET_TIMER1
// Constants used for SETUP_TIMER_1() are:
// (or (via |) together constants from each group)
#define T1_DISABLED 0
#define T1_INTERNAL 0x85
#define T1_EXTERNAL 0x87
#define T1_EXTERNAL_SYNC 0x83
#define T1_CLK_OUT 8
#define T1_DIV_BY_1 0
#define T1_DIV_BY_2 0x10
#define T1_DIV_BY_4 0x20
#define T1_DIV_BY_8 0x30
|
|
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1634 Location: Perth, Australia
|
|
Posted: Thu Jan 12, 2006 2:29 am |
|
|
goussepi wrote: | I know this sound weird but it's exactly what it does , the transition is 0x00ff->0x0000, i tried to force the register TMR1H to 0xFF and the result is 0xffff->0xff00, i tried to set a divisor, no changes. It happens on two different computer with two different version of mplab and CCS, there is either something missing in the code, or it's from the 18f452.h file.
|
Sound to me like you are chasing your tail. Your cannot safely modify T1 in your mainline without disabling timer interrupts. Forcing T1 high is the opposite of what you wanted to acheive - you needed it forced low if anything.
In the code you listed you do not initialise T1 so the first interrupt can occur at any time. Similarly you did not clear any stale timer 1 over flow flag so the first interrupt can occur immediately. How are you determining that the timer is only counting so far? There is nothing in your code to indicate how you are doing this.
Here is a step by step "pureist" way of initializing a timer.
Code: |
disable_interrupts(INT_TIMER1);
setup_timer_1(T1_DIV_BY_1 | T1_INTERNAL);
set_timer1(0);
clear_interrupt(INT_TIMER1);
enable_interrupts(INT_TIMER1);
|
A simpler method:
Code: | setup_timer_1(T1_DIV_BY_1 | T1_INTERNAL);
set_timer1(0);
clear_interrupt(INT_TIMER1);
enable_interrupts(INT_TIMER1); |
_________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
goussepi
Joined: 11 Jan 2006 Posts: 6
|
|
Posted: Thu Jan 12, 2006 3:55 am |
|
|
Even with this safer code i still have the problem.
Code: |
#include<18f452.h>
#use delay (clock = 20000000)
int32 z;
#int_timer1
void tmr1_isr()
{
z=0;
}
void main()
{
disable_interrupts(INT_TIMER1);
setup_timer_1(T1_DIV_BY_1 | T1_INTERNAL);
set_timer1(0);
clear_interrupt(INT_TIMER1);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
while(1)
{
}
}
|
The isr is run for TMR1=0x00ff, i'm using the simulator with the "step into" button, i'm looking at the TMR1, TMR1L and TMR1H register and TMR1H never get incremented. Could i have wrongly configured mplab ? |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1634 Location: Perth, Australia
|
|
Posted: Thu Jan 12, 2006 3:59 am |
|
|
In that case, if TMRL is incrementing the problem is in MPLAB. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
goussepi
Joined: 11 Jan 2006 Posts: 6
|
|
Posted: Thu Jan 12, 2006 4:10 am |
|
|
Ok thanks, i'm going to work on this. |
|
|
MikeValencia
Joined: 04 Aug 2004 Posts: 238 Location: Chicago
|
|
Posted: Thu Jan 12, 2006 7:47 am |
|
|
If you want to see what really happens (assuming MPLAB itself has a bug), then you should toggle a pin in your TMR1 ISR, and look at it on an oscilloscope.
I can almost guarantee you that your interrupts are happening at a frequency of:
(4 * 1 * 65536) / 20000000 = .013 sec = 13 ms
Code: |
#include<18f452.h>
#use delay (clock = 20000000)
int32 z;
#int_timer1
void tmr1_isr()
{
*** TOGGLE AN I/O PIN HERE ***
}
void main()
{
disable_interrupts(INT_TIMER1);
setup_timer_1(T1_DIV_BY_1 | T1_INTERNAL);
set_timer1(0);
clear_interrupt(INT_TIMER1);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
while(1)
{
}
}
|
Now if you were using TMR0, it is configurable as an 8-bit or 16-bit timer, but with TMR1, you cannot configure that to 8-bit.
So verify it on the scope. |
|
|
goussepi
Joined: 11 Jan 2006 Posts: 6
|
|
Posted: Thu Jan 12, 2006 1:18 pm |
|
|
I won't have access to labs until tomorrow and this must be an mplab bug , no 16bit register are simulated right. I have also checked the TxCON registers, they'r all fine. |
|
|
Guest Guest
|
Re: help with timer1 pic18f452 |
Posted: Thu Jan 12, 2006 4:30 pm |
|
|
You have fallen into the same trap that I did with MPLAB timers.
The data sheet for 18Fxxx parts explains that TMR1H is NOT readable or writable.
What you can read (write) is a buffer which is updated when you read (write) TMR1L.
The action you are describing is an artifact of 16 bit timers in MPLAB.
You get the same action with machine code or any 'C' compiler.
In machine code set up interrupts using TMR1 as a timer, watch windows for TMR1L TMR1H, and a stopwatch.
You will find that interrupts occur only after TMR1L counts through 0-255 for 256 loops.
If you want to read TMR1H you will have to add reads of TMR1L to your code.
It seems that you have to trust that the timer is running without being able to observe TMR1H!
NB The same considerations apply to most other 16 bit timers, and 8/16 bit timers in 16 bit mode. |
|
|
Guest Guest
|
Re: help with timer1 pic18f452 |
Posted: Fri Jan 13, 2006 4:06 am |
|
|
Timer1 problem continued.
Microchip intend the action you describe.
MPLAB SIM is a simulator. It emulates the action of the silicon.
When you read TMR1H you are actually reading its buffer and not the real TMR1H.
MPLAB SIM copies this action.
You do not say which version of MPLAB you are using. There was a Timer0 bug in MPLAB 6.xx
Microchip does not support legacy versions of MPLAB, you must upgrade to 7.xx
The MPLAB 6.xx Timer0 bug has been resolved. |
|
|
goussepi
Joined: 11 Jan 2006 Posts: 6
|
|
Posted: Fri Jan 13, 2006 5:14 am |
|
|
I'am using mplab 7.30b.
Sorry i don't understand this :
Quote: |
If you want to read TMR1H you will have to add reads of TMR1L to your code.
|
Ok so what the view/"special function register" is displaying is a buffer. That's interesting, thanks for the information. |
|
|
Guest Guest
|
Re: help with timer1 pic18f452 |
Posted: Fri Jan 13, 2006 4:56 pm |
|
|
That's right, MPLAB SIM shows the contents of TMR1H's buffer.
Therefore, to transfer the contents of the real TMR1H to the TMR1H buffer, you have to perform reads of TMR1L.
I find that sort of thing easier to do in machine rather than code than 'C'.
( I try to keep things simple and sometimes 'C' gets in the way. )
If you are more comfortable with 'C' then use it.
To check this I tried it, again today, with Timers 0 and 1 in code.
The results agree with the above. |
|
|
bsodmike
Joined: 05 Aug 2006 Posts: 52
|
|
Posted: Tue Sep 26, 2006 12:31 pm |
|
|
Quote: | I can almost guarantee you that your interrupts are happening at a frequency of:
(4 * 1 * 65536) / 20000000 = .013 sec = 13 ms |
If that's causing anyone any headaches,
(1/(Fosc/4)) * 2^16 = (4/Fosc) * 2^16 = ~13msec |
|
|
|