|
|
View previous topic :: View next topic |
Author |
Message |
Jean FOUGERON
Joined: 30 Nov 2012 Posts: 110 Location: France
|
#INT_EXT behaviour |
Posted: Wed Jul 27, 2016 4:04 am |
|
|
Does anybody knows the details of #INT_EXT ?
I use it in my project.
I need to monitor a 4/20mA loop.
The signal applied to my PIC18F2550 is like series of squares 2 times a second
Each serie is a number of up levels during 10ms, and spaced 14ms (I mean 10ms up, the 4ms down ...) apart from the first one (to identify) which is 5ms long, is 10ms, and the last one which is 15ms.
When a problem occurs on the sets that it is monitoring, one (or many) top (10 or 15ms) disappears.
So, I have a bar of 2 colors leds and I light in green or red each led whether the corresponding top is present or not.
To detect the top I use #INT_EXT
Code: | #INT_EXT high
void Boucle()
{
L_Compteur_Flanc=L_Compteur;
if (!B_Flanc) B_Flanc=TRUE;
} |
and in main I have
Code: | void main()
{
initialisation();
while(TRUE)
{
restart_wdt(); // resetter le watch dog !
if (B_Flanc) Flanc_Pulse();
...
if(SFLS.Changed) Action();
}
} |
I also have a clock which allows me to measure the length and delay between tops.
Code: | /******************************************************************************
appelé tous les 200µs ??
*******************************************************************************/
#INT_TIMER3 high
void Counter()
{
set_timer3(L_Period);
L_Compteur++; //doit donc battre PERIODXXX
} |
The procedure Flanc_Pulse compares the value of L_Compteur with the different delays (5, 10, 14 and 15 ms) taking in account the possible dispersion (+/- 1,2 ms) and can adjust the clock period (value of L_Period) a little bit to correct variations (eg temperature of the monitored sets).
When Flanc_Pulse has detected a correct slope (L_2_H or H_2_L) it inverses the detecting slope of the #INT_EXT (when it detects a L_2_H slope 14ms after the previous one, it considers it as OK and switches to H_2_L expecting a descending signal in 10 or 15ms).
It, globally works well but ...
I observe that there are faulty calls of #INT_EXT, I mean that the interrupt goes without "seeing" any voltage variation of the current loop signal on PIN_RB0 where it is applied.
Of course it falses the treatment and I lose green led or red one.
I added a 100nF capacitor on the PIN_RB0 but nothing. The signal seems OK is 5V hight and without noise. Supply is 5VDC
In Microchip datasheet, I understand a logical 0 is detected below 0,8V and a logical 1 is >2V. There is never noise of this amplitude, so I guess something happens inside the PIC but what ?
I have tried and observe any correlation with any event, but noticed nothing.
Has anybody already seen similar behaviour and understood what happened and made correction ? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Wed Jul 27, 2016 5:07 am |
|
|
Get rid of using the high priority bit.
You are talking about signals at mSec timings, which imply these certainly do not need to be using high priorities. However key thing is that INT_EXT, does not have an interrupt priority bit at all. So what the compiler does if you try to set this, is 'anybodies guess'... :(
INT_EXT, is always high priority if priorities are enabled.
So try with this not enabled.
However are you sure you would see the sort of noise timings that could be involved?. |
|
|
Jean FOUGERON
Joined: 30 Nov 2012 Posts: 110 Location: France
|
|
Posted: Thu Jul 28, 2016 8:50 am |
|
|
Thanks for your answer
Ttelmah wrote: | Get rid of using the high priority bit.
...
So try with this not enabled.
|
OK, I remove it, and Warning 225 "cms.c" Line 754(1,1): Interrupt level changed EXT: NORMAL=>HIGH.
I introduce a spy SLR where SLR is connected to my oscilloscope and B_Rising is high when L_TO_H and low when H_TO_L.
B_Rising is fixed in the procedure Flanc_Pulse() which is called in the main so it is fixed with a delay regarding the reality.
Code: | void main()
{
initialisation();
while(TRUE)
{
restart_wdt(); // resetter le watch dog !
Boolean B=input(PIN_B0);
if(B_Rising) SLR(B); else SLR(!B);
if (B_Count) Comptage();
if (B_Flanc) Flanc_Pulse();
if(B_Check) Check_Alarm(); // Vérifier s'il y a une alarme à afficher
if(B_UART_OK) GetData(); // charger le query ModBus
if(SFLS.Changed) Action();
}
} |
In this case I can see the delay of approx 200 to 220µs and sometimes, erratically, more.
I think it is the delay between the event on the PIN_B0 and when Flanc_Pulse treat it.
But this delay is not present on each slope.
On the other hand, when I generate the spy SLR in the INT_EXT, there is nothing.
Code: | #INT_EXT
void Boucle()
{
Boolean B=input(PIN_B0);
if(B_Rising) SLR(!B); else SLR(B);
L_Compteur_Flanc=L_Compteur;
if (!B_Flanc) B_Flanc=TRUE;
} |
Which proves that the B_Rising is correct. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Thu Jul 28, 2016 10:51 am |
|
|
You need to get rid of high on everything. INT_EXT is always high if priorities are used. Unless you have some very specific need, the only reason is to allow an interrupt handler to interrupt other interrupt handlers. This then brings the responsibility of coping with having a handler potentially interrupted. Is your code written to handle this?. If not, don't use this. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|