Forum: Mikrocontroller und Digitale Elektronik PIC32 CN Pins Triggern ständig Interrupt


von Simon (Gast)


Angehängte Dateien:

Lesenswert?

Ich habe eine Platine mit einem PIC32MX695F512 (Ethernet (Phyter), SPI 
Flash, RTCC).

Nachdem ich mit dem Board diese Probleme hatte,
beschloss ich eine neue Platine nur mit dem PIC32 einem 16MHz quarz und 
seinen Kondensatoren zu bestücken.

Angeschlossen ist ein ICD3.

Mein Problem:
Sobald ich den CN2 Pin auf GND lege, Triggert der Interrupt ständig.
Warum Triggert der Interrupt hier ständig und wieso sehe ich am
OUT0_IO (RB12/AN12/TCK) Ausgang ein Rechteckssignal von genau 1.440µS ?

1
void cn_init() {
2
3
    mCNOpen(CN_ON | CN_IDLE_CON,
4
         CN2_ENABLE, CN2_PULLUP_ENABLE);
5
6
    IPC6SET = 0x00140000; // Set priority level=5
7
    IPC6SET = 0x00030000; // Set Subpriority level=3
8
9
    IFS1CLR = 0x0001; // Clear the interrupt flag status bit
10
    IEC1SET = 0x0001; // Enable Change Notice interrupts
11
 }
12
13
14
void __ISR(_CHANGE_NOTICE_VECTOR, ipl5) ChangeNoticeHandler(void)
15
{
16
17
    OUT0_IO ^= 1;
18
    IFS1CLR = 0x0001;
19
20
}

Das angehangene Bild Zeigt den OUT0_IO (blau) und die Versorgungspannung 
3.3V (gelb, offset +2V)

von WehOhWeh (Gast)


Lesenswert?

Möglicherweise quittierst du das falsche Flag, und er landet immer wider 
in der ISR.

Ich würde mir auch mal die Configbitsettings anschauen. Vielleicht ist 
der Port irgendeiner Peripherie zugewisen.

Möglicherweise ist der CN-Pin auf level sensitiv.

Ist das mCNOpen() Harmony oder PLIB?
Ich würde das für diesen Fall selber schreiben, ist bei PIC32 nicht 
schwierig, auch nicht viel größer für den CN und man weiß, was es macht. 
Das sind wenige Zeilen.
Die Libs kann man ja für die komplizierten Sachen wie dieses blöde I2C 
nehmen, aber für so einfachen Kram wie CN lohnt sich das nicht, finde 
ich.

Tipp: Es gibt eine besser lesbare Schreibweise, als dieses 
Bitgepfriemel:

IFS0bits.CNIF = 0; //clear CN interruptflag

Man kann das Datenblatt einfach abtippen - inklusive 
Autovervollständigen. Enorm praktisch!

von Simon (Gast)


Lesenswert?

WehOhWeh schrieb:

> Ich würde mir auch mal die Configbitsettings anschauen. Vielleicht ist
> der Port irgendeiner Peripherie zugewisen.
Ich habe auch mal 3 andere CN pins verwendet, an jedem das selbe 
Problem.


> Möglicherweise ist der CN-Pin auf level sensitiv.

Wie und WO kann man das Einstellen?


>
> Ist das mCNOpen() Harmony oder PLIB?

PLIB, ich habe MPLABX und da ist es in der ports.h


>
> Tipp: Es gibt eine besser lesbare Schreibweise, als dieses
> Bitgepfriemel:
>
> IFS0bits.CNIF = 0; //clear CN interruptflag

habe ich gleich mal ersetzt



Danke dir für die Hilfe

von Stephan (Gast)


Lesenswert?

Hi,
hab die Register nicht im Kopf, sehe also nicht genau was du machst, 
aber hier mal der Code-Schnipsel von mir:
1
#define CN_CONFIG          (CN_ON | CN_IDLE_CON)   ///< Konfig der CN-Pins
2
#define CN_PINS            (CN11_ENABLE | CN8_ENABLE) ///< aktivierte CN-Pins
3
#define CN_PULLUPS         (              CN8_PULLUP_ENABLE)  ///< aktive Pullups
4
#define CN_INTERRUPT       (CHANGE_INT_ON | CHANGE_INT_PRI_2)  ///< Konfig des Interrupts 
5
6
7
   unsigned int newPortB;
8
   
9
   // Disables Change Notice interrupt, disables all
10
   // change notice inputs and pullups
11
   // clear change notice interrupt flag
12
   mCNClose();
13
   
14
   // STEP 4. enable change notice, enable discrete pins and weak pullups
15
   mCNOpen(CN_CONFIG, CN_PINS, CN_PULLUPS);
16
17
   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
18
   // STEP 5. read port(s) to clear mismatch on change notice pins
19
   newPortB = mPORTBRead(); // 
20
   
21
   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
22
   // STEP 6. clear change notice interrupt flag
23
   ConfigIntCN(CN_INTERRUPT);
24
   
25
   // Set priority levels
26
   INTSetVectorPriority(INT_CHANGE_NOTICE_VECTOR, INT_PRIORITY_LEVEL_2);
27
   INTSetVectorSubPriority(INT_CHANGE_NOTICE_VECTOR, INT_SUB_PRIORITY_LEVEL_0);
28
29
   // Interrupt an 
30
   INTEnableSystemMultiVectoredInt();
31
32
33
34
void __ISR(_CHANGE_NOTICE_VECTOR, ipl2) ChangeNotice_Handler(void)
35
{
36
   unsigned int newPortB;
37
38
   // clear the mismatch condition
39
   newPortB = mPORTBRead();
40
   
41
   // clear the interrupt flag
42
   mCNClearIntFlag();
43
44
   //************************************ PORT B ***************************************************
45
   // Auswertung
46
}

von Little B. (lil-b)


Lesenswert?

Stephan schrieb:
> void __ISR(_CHANGE_NOTICE_VECTOR, ipl2) ChangeNotice_Handler(void)
> {
>    unsigned int newPortB;
>
>    // clear the mismatch condition
>    newPortB = mPORTBRead();
>
>    // clear the interrupt flag
>    mCNClearIntFlag();
>
>    //************************************ PORT B
> ***************************************************
>    // Auswertung
> }

Ja, das lesen des Ports fehlt. Siehe hierzu Section 12 I/O Ports des 
Reference Manuals kapitel 12.3.3.1:

When a CN interrupt occurs, the user should read the PORTx register 
associated with the CN
pin(s). This will clear the mismatch condition and set up the CN logic 
to detect the next pin change.
The current PORTx value can be compared to the PORTx read value obtained 
at the last CN interrupt or during initialization, and used to determine 
which pin changed.The CN pins have a minimum
input pulse-width specification. Refer to the “Electrical 
Characteristics” chapter of the specific
device data sheet to learn more.

von Simon (Gast)


Lesenswert?

Oh man, ihr habt recht, damit geht es.

Scheinbar ist es nicht ok die Ports so zu lesen, man muss sie wohl 
komplett lesen.

new  = (PORTB & 0x003F) | (PORTG & 0x03C0) | (swap.Val & 0x3C00);

von Simon (Gast)


Lesenswert?

Eine Frage bleibt aber noch.

Wenn ich an PORTB mehrere Pins miteinander verbinde. z.B. RB0 RB1 RB2

Lesen tue ich die mit

x = PORTB;

Wieviele Interrupts entstehen?

von Stephan (Gast)


Lesenswert?

Dahinter ist nur eine einfache Logik, wenn sich einer ändert, dann wird 
der Wechsel erkannt und ein INT ausgelöst.
Sollten sich dann noch weitere ändern, bekommst du das nicht mit. Die 
Logik hat ja schon ausgelöst.
Nur durch das lesen der PORT Register und das Prüfen alle CNs auf 
Änderung, sagt dir was Sache ist.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.