Forum: Mikrocontroller und Digitale Elektronik PIC18Fxxx: Interrupt Flag wird scheinbar nicht geloescht


von Paul K. (paul-cgn)


Lesenswert?

Hi zusammen,

ich versuche gerade Interupt vom CaptureComparePWM Modul und auch dem 
Comparator in meinem Pic18f4550 zu behandeln.

Das erste Ausloesen jedes Interrupt klappt wunderbar, jedoch wird bei 
jedem weiteren ausgeloesten Interrupt auch der zuvor ausgeloeste 
Interrupt flag erneut als gesetzt betrachtet. Vermutlich ein ganz doofer 
Fehler von mir beim Versuch den Flag zu loeschen, ich komme aber nicht 
drauf.

ggf wichtiger Hinweis (?): ich bin derzeit nur im simulator von mplabx 
unterwegs, also teste ich nicht an physischer hardware, aber das sollte 
ja hoffentlich keinen unterschied machen. Compiler ist c18.

Beispiel fuer den Ablauf:
1.) ein Interrupt wird durch ansteigende Flanke an CCP1 ausgeloest, die 
interrupt routine sieht auch das das interrupt flag PIR1bits.CCP1IF 
gesetzt ist und fuehrt den entsprechenden code aus und verlaesst die 
isr.
2.) in loese mit einer ansteigenden Flank an CCP2 den interupt aus, nun 
wird der PIR1bits.CCP2IF als gesetzt erkannt und der code 
ausgefuehrt...aber er erkennt auch noch PIR1bits.CCP1IF als gesetzt 
obwohl ich diesen doch vorher geloescht habe.
3.) ich loese den comparator interrupt aus durch anlegen high pegel an 
RA0, der flag PIR2bits.CMIF ist gesetzt und der entsprechende code wird 
ausgefuehrt....nur geht er aber weiter und erkennt wohl wieder die 
beiden CCP interrupt flags als ebenfalls gesetzt und fuehrt auch diesen 
code wieder aus.

Mein Problem scheint also zu sein, dass ich den Interrupt flag nicht 
richtig loesche...ich weiss aber partout nicht was ich falsch mache.

bitte hilfe :-)

1
/*
2
 * File:   main.c
3
 * Author: pkerspe
4
 *
5
 * Created on 26. Juli 2012, 09:49
6
 */
7
#include <p18f4550.h>
8
#include <delays.h>
9
#include <timers.h>
10
#include <capture.h>
11
12
#include <string.h>
13
#include <stdio.h>
14
#include <stdlib.h>
15
16
#pragma config WDT = OFF
17
//#pragma config OSC = HS
18
//#pragma config OSCS = OFF
19
#pragma config PWRT = OFF
20
#pragma config BOR = OFF
21
#pragma config LVP = OFF
22
23
24
void main(void);
25
void setupIo(void);
26
void initComparator(void);
27
void InterruptHandlerHigh(void);
28
void initInterrupts(void);
29
void initCCP(void);
30
31
void setupIo(){
32
    TRISAbits.RA0 = 1; //set RA0 as input -> comparator C1 -input
33
    TRISAbits.RA1 = 1; //set RA1 as input -> comparator C2 -input
34
    TRISAbits.RA2 = 1; //set RA2 as input -> comparator C2 +input //not used in mode 110
35
    TRISAbits.RA3 = 1; //set RA3 as input -> comparator C1 +input //not used in mode 110
36
    TRISAbits.RA4 = 0; //set RA4 as output -> comparator C1 output
37
    TRISAbits.RA5 = 0; //set RA5 as output -> comparator C2 output
38
    TRISCbits.RC1 = 1; //set RC1 as input -> capture ccp1 trigger
39
    TRISCbits.RC2 = 1; //set RC2 as input -> capture ccp2 trigger
40
}
41
42
void initComparator(){
43
    //CMCON = COMPARATOR CONTROL REGISTER
44
    CMCONbits.C1OUT = 1;
45
    CMCONbits.C2OUT = 1;
46
    CMCONbits.C1INV = 1;
47
    CMCONbits.C2INV = 1;
48
    CMCONbits.CIS = 0; //Comparator Input Switch bit 0 = C1 VIN- connects to RA0/AN0 AND C2 VIN- connects to RA1/AN1
49
    CMCONbits.CM2 = 1; //Comparator Mode bits CM2:CM0 -> 110 = 2 Comparators with internal ref voltage
50
    CMCONbits.CM1 = 1;
51
    CMCONbits.CM0 = 0;
52
53
    //init reference voltage
54
    CVRCONbits.CVREN = 1; //Comparator Voltage Reference Enable bit
55
    CVRCONbits.CVROE = 0; //Comparator VREF Output Enable bit (für multimeter ggf einschalten?)
56
      //1 = CVREF voltage level is also output on the RA2/AN2/VREF-/CVREF pin
57
    CVRCONbits.CVRR = 0; // Comparator VREF Range Selection bit
58
      //1 = 0 to 0.667 CVRSRC, with CVRSRC/24 step size (low range)
59
      //0 = 0.25 CVRSRC to 0.75 CVRSRC, with CVRSRC/32 step size (high range)
60
    CVRCONbits.CVRSS = 0; //Comparator VREF Source Selection bit
61
      // 1 = Comparator reference source, CVRSRC = (VREF+) ? (VREF-)
62
      // 0 = Comparator reference source, CVRSRC = VDD ? VSS
63
    CVRCONbits.CVR3 = 1;//CVR3:CVR0: Comparator VREF Value Selection bits (0 ? (CVR3:CVR0) ? 15)
64
    CVRCONbits.CVR2 = 0;//When CVRR = 1: CVREF = ((CVR3:CVR0)/24) * (CVRSRC)
65
    CVRCONbits.CVR1 = 0;//-> When CVRR = 0: CVREF = (CVRSRC/4) + ((CVR3:CVR0)/32) * (CVRSRC)
66
    CVRCONbits.CVR0 = 1;// 0b1001 => 1,25 + (9/32 * 5) = 2,65625V
67
}
68
69
void initInterrupts(){
70
    //enable interrupts for comparator
71
    RCONbits.IPEN = 1; //enable interrupt priority levels
72
    INTCONbits.GIE = 1; //enable interrupts in general
73
    INTCONbits.PEIE = 1; //external interrupts enabled
74
75
    PIR2bits.CMIF = 0; //reset CoMparatorInterruptFlag
76
    PIE2bits.CMIE = 1; //enable comparator interrupt
77
    IPR2bits.CMIP = 1; //set comparator interrupt to high priority
78
79
    //init interrupts for ccp1 and 2
80
    PIE1bits.CCP1IE = 1;
81
    PIE2bits.CCP2IE = 1;
82
}
83
84
void initCCP(){
85
    //ccp interrupts
86
    PIR1bits.CCP1IF = 0;
87
    PIR2bits.CCP2IF = 0;
88
89
    CCP1CON = 0b00000101; //Capture mode: every rising edge
90
    CCP2CON = 0b00000101; //Capture mode: every rising edge
91
92
    T3CONbits.TMR3CS = 0; //Timer3 increments on every internal instruction cycle
93
    T3CONbits.RD16 = 1; // enable 16 bit read for the timer3
94
    T3CONbits.T3CCP1 = 1; //set timer3 as timer for ccp1
95
    T3CONbits.T3CCP2 = 1; //set timer3 as timer for ccp2
96
    T3CONbits.TMR3ON = 1;
97
}
98
/*
99
 *
100
 */
101
void main() {
102
    setupIo();
103
    initComparator();
104
    initCCP();
105
    initInterrupts();
106
    while(1){
107
    }
108
}
109
110
111
//----------------------------------------------------------------------------
112
// High priority interrupt vector
113
#pragma code InterruptVectorHigh = 0x08
114
void InterruptVectorHigh (void) {
115
  _asm
116
    goto InterruptHandlerHigh //jump to interrupt routine
117
  _endasm
118
}
119
120
//----------------------------------------------------------------------------
121
// High priority interrupt routine
122
#pragma code
123
#pragma interrupt InterruptHandlerHigh
124
void InterruptHandlerHigh () {
125
  int test;
126
  if (PIR2bits.CMIF){
127
      PIE2bits.CMIE = 0;
128
      PIR2bits.CMIF = 0;    //clear interrupt flag
129
130
      if(CMCONbits.C1OUT){
131
          test = 1;
132
          CMCONbits.C1OUT = 0x00;
133
      }
134
      if(CMCONbits.C2OUT){
135
          test = 2;
136
          CMCONbits.C2OUT = 0x00;
137
      }
138
      PIE2bits.CMIE = 1;    // re-enable interrupt for comparator
139
    }
140
    if(PIR2bits.CCP2IF){
141
        PIR2bits.CCP2IF = 0b0;    //clear interrupt flag
142
        //PIE2bits.CCP2IE = 0;
143
        test = ReadCapture2();
144
        //PIE2bits.CCP2IE = 1;    // re-enable interrupt for capture ccp
145
    }
146
    if(PIR1bits.CCP1IF){
147
        //PIE1bits.CCP1IE = 0;
148
        WriteTimer3(0);
149
        PIR1bits.CCP1IF = 0;    //clear interrupt flag
150
        //add logic
151
        test = ReadCapture1();
152
        //PIE1bits.CCP1IE = 1;    // re-enable interrupt for capture ccp
153
    }
154
}

von Christian K. (Firma: Atelier Klippel) (mamalala)


Lesenswert?

Paul K. schrieb:
>         PIR2bits.CCP2IF = 0b0;    //clear interrupt flag

???

0b.... ist für eine Bitfolge gedacht. Kann gut sein das der 
Simulator/Compiler da Müll macht.

Grüße,

Chris

von Paul (Gast)


Lesenswert?

Danke für die Antwort Chris!
Wie man jedoch sieht habe ich auch "0" und "0x00" bei den anderen Flags 
versucht, leider klappt es bei keinem :-(

von pfennig (Gast)


Lesenswert?

Hallo,,
Du kannst das  register mit den interrupt flags auch direkt beschreiben,
Z.b.   PIR3 =0b00000000;

Ich gib in übrigen auch immer alle nullen an, auch wenn man es 
eigentlich nicht brauch,, aber grad bein initieren der register hilft es 
sehr bei der übersicht

von Paul K. (Gast)


Lesenswert?

Hallo Pfennig, danke für deine Antwort.
Es scheint nicht daran zu liegen wie ich den Wert übergebe, sondern wohl 
schlicht daran das der Simulator von mplabx nicht so ganz korrekt 
reagiert. Ich habe das ganze nun auf der echten Schaltung getestet und 
es scheint im Grunde zu funktionieren mit den Interrupts.

Gruß
Paul

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.