Forum: Mikrocontroller und Digitale Elektronik Interrupt A/D-Wandler


von Chris (Gast)


Lesenswert?

leider auch keine wirklich richtigen Tipps geben können, und jetzt 
versuch ich hier mein Glück. Ich benutze MPLabX und den XC8 Compiler. 
Das einlesen des Analogwertes des Potis in der Polling-Schleife 
funktioniert, jetzt würde ich es gerne in eine ISR packen und ab hier 
funktioniert dann nichts mehr.. bitte um Hilfe
mein Code:
1
#include "p18cxxx.h"
2
#include "xc.h"
3
#include "config.h"
4
5
#define BTN_IGNORE_FACTOR 10
6
#define _XTAL_FREQ 1000000
7
8
volatile unsigned char ad_msb = 0, ad_lsb = 0;
9
10
void delay(int time);
11
void SetupOscillator(void);
12
void SetupPWM(void);
13
void SetupADC(void);
14
void interrupt low_priority Low_Priority_ISR(void);
15
16
void main(void) {
17
18
   unsigned char button = 0, ignorebutton = 0;
19
20
   ANSEL = 0x00;                             //Eingänge Digital
21
   ANSELH = 0x00;
22
   INTCONbits.GIEH = 1;             //Alle High-Priority Interrupts enabled
23
   INTCONbits.GIEL = 1;             //Alle Low-Priority Interrupts enabled
24
   RCONbits.IPEN = 1;               //Enable Priority levels on Interrupts
25
26
   SetupOscillator();                          //Frequenz 1MHz
27
   SetupADC();    //Analogsignal RA0 einlesen, Digital RB0 einlesen(Taster)
28
   SetupPWM();  
29
   while (1) {
30
       ADCON0bits.GO_DONE = 1;                    //A/D-Wandlung starten
31
       while(ADCON0bits.GO_DONE != 0);         //auf A/D-Wandlung warten
32
       ad_msb = ADRESH;                         //A/D-Ergebnis Bit 2 bis 10
33
       ad_lsb = ADRESL;                          //A/D-Ergebnis Bit 0 und 1
34
       if (PORTBbits.RB0 == 0 && ignorebutton == 0) { //Taster gedrückt? (=0, 1= not pressed)
35
            button = button ^ 1;       //Modus toggeln -> PWM/Laufschrift
36
            ignorebutton = BTN_IGNORE_FACTOR; //Taster für bestimmte Zeit ignorieren
37
        }
38
        if (ignorebutton > 0) ignorebutton--;    //Ignorierzeit verringern
39
        if (button == 0) {                //Modus checken
40
             PIE1bits.ADIE = 0;           //ADC-Interrupt disabled
41
             CCPR2L = ad_msb;
42
             CCPR1L = ad_msb;
43
             CCP2CONbits.DC2B = ad_lsb;    //Steigerung Duty Cycle auf 0,1%
44
             CCP1CONbits.DC1B = ad_lsb;
45
             //PIE1bits.ADIE = 1;          //ADC-Inerrupt enabled
46
             LATD = ad_msb;
47
        }  else{
48
            CCPR1L = CCPR1L - 1;           //PWM Duty Cycle an CCP1/RC2 verringern -> abklingen
49
            delay(25);                     //25ms warten
50
            if(CCPR1L == 0){
51
                button = 0;
52
            }
53
            
54
        }
55
56
    }
57
}
58
59
void delay(int time) {
60
   int counter = 0;
61
   for (counter = 0; counter<time; counter++)
62
        __delay_ms(1);
63
}
64
65
void SetupOscillator(){
66
    OSCCONbits.SCS = 0x3;       //Interner Oscillator
67
    OSCCONbits.OSTS = 0;        //Interner Oscillator
68
    OSCCONbits.IRCF0 = 1;
69
    OSCCONbits.IRCF1 = 1;
70
    OSCCONbits.IRCF2 = 0;       //Oscillatorfrequenz 1MHz
71
    OSCCONbits.IDLEN = 0;       //Sleep-Mode bei sleep
72
}
73
74
void SetupPWM(){
75
   TRISCbits.RC1 = 1;           //Port RC1/CCP2 PWM als Ausgang sperren
76
   TRISCbits.RC2 = 1;           //Port RC2/CCP1 PWM als Ausgang sperren
77
   T2CONbits.T2CKPS = 0x00;     //Timer 2 Eingang: Fosc 1MHz/4 = 250kHz
78
   PR2 = 249;                 //PWM-Periode: PR+1 * 1/250kHz = 1ms, f=1kHz
79
   CCP2CONbits.CCP2M = 0x0F;    //CCP2 auf PWM
80
   CCP1CONbits.CCP1M = 0x0C;    //CCP1 auf PWM
81
   CCP1CONbits.P1M = 0x00;      //CCP1 Single Mode
82
   PSTRCONbits.STRA = 1;        //P1A als Ausgang für CCP1
83
   TRISCbits.RC1 = 0;           //Port RC1/CCP2 PWM als Ausgang
84
   TRISCbits.RC2 = 0;           //Port RC2/CCP1 PWM als Ausgang
85
   T2CONbits.TMR2ON = 1;        //Timer 2 an
86
}
87
88
void SetupADC(){
89
   TRISAbits.RA0 = 1;            //Port RA0 Poti auf Eingang setzen
90
   TRISBbits.RB0 = 1;            //Port RB0 Taster auf Eingang setzen
91
92
   ANSELbits.ANS0 = 1;     //RA0 auf Analogeingang setzen (=1, 0 = digital)
93
   ADCON0bits.ADON = 1;          //A/D-Wandler aktivieren
94
   ADCON0bits.CHS = 0x00;        //AN0/RA0 als A/D-Converter Eingang
95
   ADCON1bits.VCFG1 = 0;  //Negative Voltage Reference (=Vss , 0 = AN2,RA2)
96
   ADCON1bits.VCFG0 = 0;  //Positive Voltage Reference (=Vdd , 0 = AN3,RA3)
97
   ADCON2bits.ADFM = 0;   //A/D-Wandler Conversion Result Format: Links beginnend
98
99
   //PIE1bits.ADIE = 1;            //ADC-Interrupt enabled
100
   IPR1bits.ADIP = 0;            //ADC-Interrupt Low-Priority
101
   PIR1bits.ADIF = 0;            //Interruptflag zurücksetzen
102
   ADCON0bits.GO_DONE = 1;       //A/D-Wandler starten
103
}
104
void low_priority interrupt Low_Priority_ISR(){
105
    if(PIR1bits.ADIF == 1 && ADCON0bits.GO_DONE == 0){
106
        ad_msb = ADRESH;
107
        ad_lsb = ADRESL;
108
        PIR1bits.ADIF = 0;
109
        ADCON0bits.GO_DONE = 1;
110
    }
111
    return;
112
}

: Bearbeitet durch User
von Chris (Gast)


Lesenswert?

Es wurden mir wohl die ersten Zeilen abgeschnitten.
Hallo zusammen, ich bin seit ca. 3 Wochen am uC programmieren. Ich 
benutze den pic18f45k20 mit dem Demoboard des PICkit3. Jetzt bin ich zu 
den Interrupts gekommen und habe auch hier schon meine ersten Probleme. 
Tante Google konnte leider auch nicht weiterhelfen und daher bin ich 
jetzt hier gelandet und hoffe auf eine Lösung  ;)

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.