Forum: Mikrocontroller und Digitale Elektronik Mal wieder Interrupts


von Lena R. (eny)


Lesenswert?

Diesmal PIC18F2523, MPLAB X, XC 8, PicKit 3, kein Bootloader.


1
/* 
2
 * File:   main.c
3
 * Author: Lena
4
 *
5
 * Created on 4. August 2013, 23:25
6
 */
7
// PIC18F2523 Configuration Bit Settings
8
9
#include <xc.h>
10
11
// CONFIG1H
12
#pragma config OSC = HS         // Oscillator Selection bits (HS oscillator)
13
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
14
#pragma config IESO = OFF       // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)
15
16
// CONFIG2L
17
#pragma config PWRT = OFF       // Power-up Timer Enable bit (PWRT disabled)
18
#pragma config BOREN = SBORDIS  // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
19
#pragma config BORV = 3         // Brown Out Reset Voltage bits (Minimum setting)
20
21
// CONFIG2H
22
#pragma config WDT = OFF        // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
23
#pragma config WDTPS = 32768    // Watchdog Timer Postscale Select bits (1:32768)
24
25
// CONFIG3H
26
#pragma config CCP2MX = PORTC   // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
27
#pragma config PBADEN = ON      // PORTB A/D Enable bit (PORTB<4:0> pins are configured as analog input channels on Reset)
28
#pragma config LPT1OSC = OFF    // Low-Power Timer1 Oscillator Enable bit (Timer1 configured for higher power operation)
29
#pragma config MCLRE = ON       // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)
30
31
// CONFIG4L
32
#pragma config STVREN = ON      // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
33
#pragma config LVP = ON         // Single-Supply ICSP Enable bit (Single-Supply ICSP enabled)
34
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))
35
36
// CONFIG5L
37
#pragma config CP0 = OFF        // Code Protection bit (Block 0 (000800-001FFFh) not code-protected)
38
#pragma config CP1 = OFF        // Code Protection bit (Block 1 (002000-003FFFh) not code-protected)
39
#pragma config CP2 = OFF        // Code Protection bit (Block 2 (004000-005FFFh) not code-protected)
40
#pragma config CP3 = OFF        // Code Protection bit (Block 3 (006000-007FFFh) not code-protected)
41
42
// CONFIG5H
43
#pragma config CPB = OFF        // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)
44
#pragma config CPD = OFF        // Data EEPROM Code Protection bit (Data EEPROM not code-protected)
45
46
// CONFIG6L
47
#pragma config WRT0 = OFF       // Write Protection bit (Block 0 (000800-001FFFh) not write-protected)
48
#pragma config WRT1 = OFF       // Write Protection bit (Block 1 (002000-003FFFh) not write-protected)
49
#pragma config WRT2 = OFF       // Write Protection bit (Block 2 (004000-005FFFh) not write-protected)
50
#pragma config WRT3 = OFF       // Write Protection bit (Block 3 (006000-007FFFh) not write-protected)
51
52
// CONFIG6H
53
#pragma config WRTC = OFF       // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
54
#pragma config WRTB = OFF       // Boot Block Write Protection bit (Boot block (000000-0007FFh) not write-protected)
55
#pragma config WRTD = OFF       // Data EEPROM Write Protection bit (Data EEPROM not write-protected)
56
57
// CONFIG7L
58
#pragma config EBTR0 = OFF      // Table Read Protection bit (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)
59
#pragma config EBTR1 = OFF      // Table Read Protection bit (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)
60
#pragma config EBTR2 = OFF      // Table Read Protection bit (Block 2 (004000-005FFFh) not protected from table reads executed in other blocks)
61
#pragma config EBTR3 = OFF      // Table Read Protection bit (Block 3 (006000-007FFFh) not protected from table reads executed in other blocks)
62
63
// CONFIG7H
64
#pragma config EBTRB = OFF      // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) not protected from table reads executed in other blocks)
65
66
67
68
69
#define LED LATAbits.LA4
70
#define LED2 LATCbits.LC0
71
72
int led_state = 0;
73
74
void delay( int ms );
75
76
//Zeitverzögerung
77
void delay( int ms ) {
78
    int i=0;
79
    //1 ms = 4000 Befehlstakte (16 MHz Quarz / 4)
80
    for( i=0; i<ms; i++ ) {
81
            _delay(4000);
82
    }
83
}
84
85
//void interrupt isr_high(void);
86
87
void interrupt isr_high(void) {
88
   if(led_state == 0)
89
    {
90
       LED = 1;
91
       led_state = 1;
92
    } else {
93
       LED = 0;
94
       led_state = 0;
95
    }
96
   INTCONbits.INT0F = 0;
97
   INTCON3bits.INT2F = 0;
98
}
99
100
101
void main(void) {
102
103
  
104
105
    //Port A
106
    LATA = 0x00;                //Pegel
107
    TRISA = 0x00;    //Alle Pins von Port A sind Ausgänge
108
//    ANSELA = 0x00;    //Alle Pins von Port A sind digitale I/O's
109
    //Port B
110
    LATB = 0x00;
111
    TRISB = 0xFF;    //Alle Pins von Port B sind Eingänge
112
//    ANSELB = 0x00;    //Alle Pins von Port A sind digitale I/O's
113
    //Port C
114
    LATC = 0x00;
115
    TRISC = 0xF0;    //RC0..RC3 = Ausgänge, RC4..RC7 = Eingänge
116
//    ANSELC = 0x30;    //nur RC4 und RC5 sind analoge Eingänge
117
118
    RCONbits.IPEN = 1;          //Interrupts können Prioritäten haben
119
    INTCONbits.GIE_GIEH = 1;     //Interrupts können hohe P. haben
120
    INTCONbits.GIEL = 1;
121
    INTCONbits.INT0IE = 1;
122
    INTCON3bits.INT2IE = 1;
123
    INTCON2bits.INTEDG0 = 1;    //Interrupt on rising edge
124
    INTCON2bits.INTEDG2 = 1;     //Interrupt on rising edge
125
    INTCON3bits.INT2IP = 1;
126
127
128
129
    while(1)
130
    {
131
        if(INTCON3bits.INT2F == 0) LED2 = 1;
132
        delay(20);
133
        LED2 = 0;
134
        delay(20);
135
    }
136
    
137
138
139
}

Irgendwie bekomm ich das nicht ans Laufen.
An Int0 und Int2 sind jeweils Funktionsgeneratoren angeschlossen, die 
ein Rechtecksignal liefern. Zum Testen einfach zwischen 1 und 50 Hz.

Es scheint, als ob er nicht in die ISR springt.
LED2 blinkt föhlich vor sich hin, LED macht garnix.

Meiner Meinung ist das Programm aber soweit richtig, oder hab ich 
irgendetwas vergessen?

von Julian B. (julinho)


Lesenswert?

Ich kenne mich mit Pics nicht aus, aber in der I-Routine  änderst du nur 
die Variable led_state, aber der eigentliche LED-Port wird nicht 
beschrieben,oder?

von Lena R. (eny)


Lesenswert?

oben:  #define LED LATAbits.LA4
in ISR: LED = 1;

Das wäre zu einfach gewesen ;)

von Michael S. (rbs_phoenix)


Lesenswert?

Geht es denn, wenn du LED und LED2 vertauscht? Wenn dann die LED an RA4 
blinkt und die andere nichts macht, kann man schonmal davon ausgehen, 
dass die Konfig der Pins richtig ist. Ggf musst du mal gucken, obs geht, 
wenn der Komparator ausgeschaltet ist, der an RA4 ist.

Zudem: Bei einigen PIC16ern (gerade ältere) ist RA4 ein 
Open-Drain-Output, d.h. man benötigte dort einen Pull-Up-Widerstand. Im 
Datenblatt vom PIC18F2523 konnte ich auf die schnelle dazu nichts 
finden, aber vielleicht ist das bei diesem PIC auch noch so.

von Lena R. (eny)


Lesenswert?

Wenn ich vertausche, gehts auch, dann blinkt die andere LED.

Die im Interrupt blinkt dann nicht.

Timer Interrupt funktioniert übrigens.
Nur wird kein Interrupt ausgelöst, auch bei fallender Flanke nicht.
Das Signal ist auch ok, 5V pp Rechteck.

Ich hab das Datenblatt jetzt 3 mal durch und finde kein Bit, was falsch 
gesetzt ist.

Von der Konfiguration her, ist auch nix was mit Interrupts 
zusammenhängt.

Glaube langsam, dass der PIC vielleicht defekt ist. Wobei das eigentlich 
unwarscheinlich ist.

Wenn ich die INTx Pins, als Ausgang belege, bekomm ich auch ein Signal.

von Michael S. (rbs_phoenix)


Lesenswert?

Lena R. schrieb:
> Das Signal ist auch ok, 5V pp Rechteck.

Ich hoffe 0V - 5V und nicht -2.5V - 2.5V, die -2.5V wird er nicht mögen.

Ich würde nochmal probieren:
1
void interrupt isr_high(void) {
2
   if(INCONbitsINT0F){
3
       INTCONbits.INT0F = 0;
4
       LED = 1;
5
   }
6
   LED2 = 1;
7
}

Dazu die while(1) in der Main leer machen. Wenn LED leuchtet, war er 
zumindest einmal dort. Ich schätze aber, dass die nicht leuchten wird.

Es kann auch sein, dass "interrupt" (alleine stehend) die low-priority 
isr-Bezeichnung ist. Also entweder die (hier überflüssige) Prioritäten 
ausschalten oder:
1
void interrupt high_priority HighPriorityISRCode(){}

von Lena R. (eny)


Lesenswert?

0V - 5V.

Leider bringt das alles keinen Erfolg.
1
void interrupt high_priority isr_high(void) {
2
   if(INTCON3bits.INT2F){
3
       INTCON3bits.INT2F = 0;
4
       LED = 1;
5
   }
6
   LED2 = 1;
7
}

Gleiches für INTCONbits.INT0F.

Soweit ich das verstanden habe, muss man nur low_priority deklarieren.
Aber wie gesagt, auch dein Code bringt keine LED zum leuchten :(

Werd wohl nacher mal den INT1 PIN testen, aber dürfte ja eigentlich kein 
Unterschied machen.

von Peter D. (peda)


Lesenswert?

Füg dochmal nen isr_low Handler hinzu.

von Lena R. (eny)


Lesenswert?

Leider auch keine Besserung :(

von Peter D. (peda)


Lesenswert?

Ich kenn die PICs nicht, aber bei AVR, 8051 gibt es noch ne globale 
Interruptfreigabe.

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.