Created Sun, 15 Dec 2013 17:12:33 +0000 by Adonosonix
Sun, 15 Dec 2013 17:12:33 +0000
Hi,
I tried to set a timer interrupt, to do some work periodically, but I can't make it work. It hangs on the first time it fires.
Here is the code I use to setup the interrupt
//timer 3 set clock period 20ms
T3CON = 0x0060; // set prescalar 1:64
TMR3 = 0;
PR3 = 0x61A8;
IFS0CLR = 0x1000;// Clear the T3 interrupt flag
IEC0SET = 0x1000;// Enable T3 interrupt
IPC3CLR = 0x0000001F;
IPC3SET = (_T3_IPL_IPC << 2) | _T3_SPL_IPC;
T3CONSET = 0x8000;// Enable Timer3
Here is the interrupt handler
extern "C"
{
void __ISR(_TIMER_3_VECTOR,ipl3) pwmOn(void)
{
IFS0CLR = 0x00001000; // Clear Timer interrupt status flag
IEC0SET = 0x00001000; // Enable Timer interrupts
return;
}
}
I tried various combination of values to clear the interrupt… I can't make it work.
Using a serial print statement on the loop() function, I can see that the program hangs after the first call to the interrupt.
What's wrong?
Additional info: I am running a web server on the board.
Sun, 15 Dec 2013 17:56:31 +0000
IPC3SET = (_T3_IPL_IPC << 2) | _T3_SPL_IPC;
...
void __ISR(_TIMER_3_VECTOR,ipl3) pwmOn(void)
_T3_IPL_IPC is 4, not 3, so your ISR isn't being called as it's at IPL3 not 4.
Sun, 15 Dec 2013 18:42:50 +0000
Thank you so much for your reply. I have looked at the definitions, and I feel quite lost.
#define _T1_IPL_ISR ipl3
#define _T1_IPL_IPC 3
#define _T1_SPL_IPC 0
So, I should use _T1_IPL_xxxxx with ipl3 everywhere ?
Also, I would like to trigger every 15 seconds. I have read the documentation, but I do not understand how :
T3CON = 0x0060; // set prescalar 1:64
can relate to 1:60
and
T3CON = 0x8030;
makes 1:256
How does that work ?
Sun, 15 Dec 2013 18:56:20 +0000
Thank you so much for your reply. I have looked at the definitions, and I feel quite lost.
#define _T1_IPL_ISR ipl3
#define _T1_IPL_IPC 3
#define _T1_SPL_IPC 0
So, I should use _T1_IPL_xxxxx with ipl3 everywhere ?
No, for Timer 3 you should use _T3_IPL_xxx and ipl4 everywhere.
Also, I would like to trigger every 15 seconds. I have read the documentation, but I do not understand how :
T3CON = 0x0060; // set prescalar 1:64
can relate to 1:60 and
T3CON = 0x0070;
makes 1:256 How does that work ?
Have you read the Timers manual from the PIC32 FRM? [url]http://ww1.microchip.com/downloads/en/DeviceDoc/61105F.pdf[/url]
TxCON: bit 6-4: TCKPS<2:0>: Timer Input Clock Prescale Select bits 111 = 1:256 prescale value 110 = 1:64 prescale value 101 = 1:32 prescale value 100 = 1:16 prescale value 011 = 1:8 prescale value 010 = 1:4 prescale value 001 = 1:2 prescale value 000 = 1:1 prescale value
Bits 6 to 4, in binary, are 0000000000***0000 So that is between 00000000000000000 and 00000000001110000 Which, in hexadecimal is between 0x0000 and 0x0070 So the 0x60 is 0x0060, which is 0000000001100000 so bits 6-4 are 110, which in that table is 1:64 prescaler.
At 80MHz, with a 1:256 prescaler, the timer ticks at 312500 Hz. With a period of 0xFFFF that equates to 4.768 Hz, or ~0.2 seconds - the longest period you can "tick" with a single timer ISR.
You could tie two timers together into a single 32-bit timer, which would allow you to time for much longer periods, but TBH it's easiest just to tick for a regular shorter period and use a simple counter to further sub-divide it. Say tick at 10Hz, then count the number of 0.1 second interrupts till you reach your desired period.
Sun, 15 Dec 2013 19:28:59 +0000
Again thank you so much for your reply. Actually, the documentation I read was this one : http://www.mikroe.com/chapters/view/52/chapter-4-timers/
Counting the interrupts is a great idea. Thank you.
I did some tests before reading your answer, and I made it work with
T3CON = 0x0060;
TMR3 = 0;
PR3 = 0x61A8;
IFS0CLR = 0x1000;
IEC0SET = 0x1000;
IPC3CLR = 0x0000001F;
IPC3SET = (_T1_IPL_IPC << 2) | _T1_SPL_IPC;
T3CONSET = 0x8000;
void __ISR(_TIMER_3_VECTOR,ipl3) pwmOn(void)
{
Serial.print("I");
IFS0CLR = 0x00001000; // Clear Timer interrupt status flag
IEC0SET = 0x00001000; // Enable Timer interrupts
}
So, I am not using timer 3 ? Are any of the timers free to choose ? Or do I need to avoid some of them, because they have internal use or are use with the "defaults" frameworks?
Sun, 15 Dec 2013 20:10:32 +0000
You're using timer 3 but with timer 1's priority. It shouldn't cause a problem, but it's confusing to someone reading it.
If you want to use some other priority than priority 4 then you should really use a literal 3 instead of a symbol relating to another peripheral.
Timer 1 is used by the tone() command, and Timer 2 is used by PWM. All other timers are free to be used as you like.
Sun, 15 Dec 2013 21:10:02 +0000
Majenko. Thank you so much for your help. I have modified the code accordingly. Thanks again.