View previous topic :: View next topic |
Author |
Message |
alvin.ma
Joined: 04 Sep 2009 Posts: 10
|
interrupt priority problem on 18F4550 |
Posted: Tue Oct 20, 2009 8:32 pm |
|
|
Hi all,
I am going to write a program with timer1 interrupt at highest priority, and use I2C and USB functions also.
I have set the priority as following:
#priority INT_TIMER1, INT_USB, INT_SSP
.......
#INT_TIMER1 HIGH
......
However, I discovered that the function of USB and I2C still affect the timer1 interrupt. Since I am using the timer1 interrupt to control the PWM, so the accuracy of the pulse is very important.
Can anyone help me on setting the interrupt? Or it's another problem?
Thanks. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Oct 20, 2009 10:18 pm |
|
|
Use the forum's search page to search for this:
Quote: |
USB interrupts disabled
x Search for all terms
|
There are several threads that might be related to your problem. |
|
|
alvin.ma
Joined: 04 Sep 2009 Posts: 10
|
|
Posted: Wed Oct 21, 2009 11:00 pm |
|
|
Hi
Thank you for reference.
I have read thought the threads, but I still cannot make clear about the USB interrupt.
However, I have narrowed the area of the problem that the timer1 interrupt is affected while the printf(usb_cdc_putc, "xxxxx %2x xxxx", input_image ); is accessed.
Since this problem may occur randomly and non-repeatedly, I cannot locate the problem where is it exactly. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Oct 22, 2009 12:34 pm |
|
|
It could be that the code in the #int_usb routine takes too long to execute
and sometimes it delays the interval between your Timer interrupts.
You could do some experiments. The #int_usb routine in this file
Quote: | c:\program files\picc\drivers\pic18_usb.c |
says that it can be converted to a non-interrupt (using polling) method.
(The instructions are given below).
If you did that, then presumably the Timer interrupt could occur during
the (polled) usb_isr() routine. That might fix your problem.
Code: |
/********************************************************
/* usb_handle_interrupt()
/*
/* Summary: Checks the interrupt, and acts upon event. Processing finished
/* tokens is the majority of this code, and is handled by usb.c
/*
/* NOTE: If you wish to change to a polling method (and not an interrupt
/* method), then you must call this function rapidly. If there is more
/* than 10ms latency the PC may think the USB device is stalled and
/* disable it.
/* To switch to a polling method, remove the #int_usb line above this
/* fuction. Also, goto usb_init() and remove the code that enables the
/* USB interrupt.
#int_usb NOCLEAR
void usb_isr()
{
int8 TRNAttempts;
clear_interrupt(INT_USB); |
|
|
|
alvin.ma
Joined: 04 Sep 2009 Posts: 10
|
|
Posted: Tue Nov 10, 2009 7:45 pm |
|
|
Hi,
I am facing another problem now. The MCU will hang while
communicating with PC through USB, and I have tried to create a
watchdog counter by using timer interrupt for preventing the dead
looping. However, it still hangs. I would like to ask that what sort of
problem may lead to MCU hang??
Thanks |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
Re: interrupt priority problem on 18F4550 |
Posted: Tue Nov 10, 2009 11:25 pm |
|
|
alvin.ma wrote: | Hi all,
I am going to write a program with timer1 interrupt at highest priority, and use I2C and USB functions also.
I have set the priority as following:
#priority INT_TIMER1, INT_USB, INT_SSP
.......
#INT_TIMER1 HIGH
......
However, I discovered that the function of USB and I2C still affect the timer1 interrupt. Since I am using the timer1 interrupt to control the PWM, so the accuracy of the pulse is very important.
Can anyone help me on setting the interrupt? Or it's another problem?
Thanks. |
The PIC18F supports high and low priority interrupts in hardware. Within the low priority interrupt handler you can set priority (very confusing) which basically means you can determine the order in which interrupt sources are check. In your case you have mixed both types.
What you actually want is:
Code: | #device HIGH_INTS = TRUE // enabled hardware high priority interrupts
..
#priority INT_USB, INT_SSP // specify the priority within the low priority interrupt handler
..
#INT_TIMER1 HIGH |
_________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
alvin.ma
Joined: 04 Sep 2009 Posts: 10
|
|
Posted: Fri Nov 13, 2009 12:13 pm |
|
|
Code: |
#include <18F4550.h>
#device HIGH_INTS=TRUE
#fuses HS, NOWDT, NOPROTECT, NOLVP, VREGEN, USBDIV, PLL5, CPUDIV1, NODEBUG
#use delay (clock=20000000)
#priority INT_TIMER3, INT_SSP, INT_USB
#include "usb_cdc.h"
#use i2c(master, sda=PIN_B0, scl=PIN_B1)
#INT_TIMER1 HIGH
void timer1_interrupt()
{
......... // driving servos
}
#INT_TIMER3
void timer3_interrupt()
{
set_timer3(15536);
......... // driving I2C periodically
}
void main()
{
........
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
enable_interrupts(INT_TIMER1);
setup_timer_3(T3_INTERNAL | T3_DIV_BY_1);
enable_interrupts(INT_TIMER3);
enable_interrupts(GLOBAL);
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(AN0);
set_adc_channel(0);
usb_init();
for (i=0;i<4;i++)
usb_cmd[i]=0x00;
while (TRUE) {
if (usb_enumerated()) {
if (usb_cdc_kbhit()) {
do {
usb_cmd_temp[i]=gethex1_usb();
i++;
}while ((i<28) && (usb_cmd_temp[i-1]!=0x0D));
................... // handling USB data
}
}
|
Hi,
I have tried to set the priority of the interrupts with reference of your suggestions, and the problems seems to be solved well. However, I found that the USB will hang sometimes while the MCU still running with timer interrupts. I have no idea about this problem. I am using 20MHz crystal. Is this problem relate to the communicating speed?
Please help. Thanks. |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Fri Nov 13, 2009 6:19 pm |
|
|
I thought you needed a 24MHz oscillator for USB operation _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
alvin.ma
Joined: 04 Sep 2009 Posts: 10
|
|
Posted: Fri Nov 13, 2009 10:20 pm |
|
|
asmallri wrote: | I thought you needed a 24MHz oscillator for USB operation |
Hi Andrew,
Can you tell me more about why should I need 24MHz oscillator for USB operation?
Thanks |
|
|
Ttelmah Guest
|
|
Posted: Sat Nov 14, 2009 3:51 pm |
|
|
You don't.
You only need 24MHz, for 'low speed' USB operation. For full speed operation, any of 4,8,12,16,20 & 24Mhz can be used for a crystal, and you can add 40 or 48MHz, is using an external clock source.
Best Wishes |
|
|
alvin.ma
Joined: 04 Sep 2009 Posts: 10
|
|
Posted: Sun Nov 15, 2009 10:30 am |
|
|
I got lost about the problem....
Is there any other problem in my program?
Please help~
thx |
|
|
alvin.ma
Joined: 04 Sep 2009 Posts: 10
|
|
Posted: Mon Nov 16, 2009 7:47 pm |
|
|
HI PCM programmer,
From my program, I wrote the USB function base on the example "ex_usb_serial.c". In its content, it just call the "usb_cdc.h",
is the USB function called by interrupt?
Thanks |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Nov 17, 2009 3:25 pm |
|
|
Here's another thing you can try.
Test the Timer1 interrupt flag inside your #int_usb routine.
If it's set, clear it, and then do your user code. The "user code"
is the same code that you do in the #int_timer1 routine. In other
words, keep the normal #int_timer1 routine, but add the ability
to also handle the Timer1 interrupt inside the #int_usb interrupt
routine.
Here is the framework of what I described above:
Code: |
#int_usb
void usb_isr()
{
if(interrupt_active(INT_TIMER1))
{
clear_interrupt(INT_TIMER1);
// Do you Timer1 user code here.
}
// Do the normal usb interrupt code here.
}
|
I don't guarantee that this will solve your problem, but you keep asking
for more help so I thought I would offer this.
Also, look at the routines called by the usb_isr() function.
Do any of them have a polling loop inside them ? If so, that could be
the source of your problem. I found this routine that is called by
usb_isr() and it has a polling loop in it:
Code: | void usb_isr_activity(void) |
Here's the polling loop. I don't how long it sits in this loop, while in the
usb_isr() interrupt routine. But, that could be the source of your
problem.
Code: |
while(UIR_ACTV)
{
//UIR_ACTV = 0;
UIR &= ~(1 << BIT_ACTV);
}
|
This routine is in this file:
Quote: | c:\program files\picc\drivers\pic18_usb.c |
You must solve this problem. I don't want to get out the hardware and
solve it for you. I am just offering possible tips. |
|
|
|