2016-06-02 1 views
0

Depuis une semaine j'ai le problème, que mon PIC 16LF1829 se réinitialise lui-même, lorsqu'il mesure le canal adc sélectionné. J'ai parlé à plusieurs collègues, mais personne ne pouvait m'aider. J'ai essayé de changer la fréquence adc, changé la référence de tension et le canal sélectionné.PIC 16LF1829 se réinitialiser pendant la mesure adc

Le problème se produit lorsque l'adc essaie d'exécuter la mesure adc. Voici mon code avec un commentaire allemand:

int ADC_Messung(int Kanal){ 
int analog = 0; //AD-Wert auf 0 setzen. 
int analog_total[5]={0, 0, 0, 0, 0}; 

ADCON0bits.CHS=Kanal; 
ADCON0bits.ADON=1; 
PIR1bits.ADIF=0; 

delay(1); //Warten bis eingeschalten und ausgewählt. 

for(int adc_runde=0; adc_runde<5; adc_runde++) 
{ 
    analog = 0; //AD-Wert auf 0 setzen. 
    ADCON0bits.GO_nDONE = 1; //AD-Wandler aktivieren. 

    while(PIR1bits.ADIF == 0); //Warten auf AD-Flag, so wird angezeigt, dass die Messung abgeschlossen ist.*/ 

    analog = ADRESH << 8; //Messwert muss um 8 Stellen(nach links) geschoben werden, weil der Messwert in 2 8-Bit Register gespeichert wird. 
    analog_total[adc_runde] = (ADRESH << 8) | ADRESL; 
    ADCON0bits.GO_nDONE = 0; //AD-Wandler deaktivieren. 
    PIR1bits.ADIF=0; //AD-Flag auf 0 setzen für die nächsten Messung. 
} 

ADCON0bits.ADON=0; 
delay(1); //Warten, bis ADC ausgeschalten ist. 
int analog_return=0; 

for(int adc_summe=0; adc_summe<5; adc_summe++){ //Zur Bildung der Summe der Messungen. 
    analog_return=(analog_return+analog_total[adc_summe]); 
} 

return analog_return=(analog_return/5); //Mittelwert der ADC-Messungen bilden zur weiteren Verwendung. 
} 

également ici mon INIT:

void init(){ 
// #pragma config statements should precede project file includes. 
// Use project enums instead of #define for ON and OFF. 

// CONFIG1 
#pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin) 
#pragma config WDTE = OFF  // Watchdog Timer Enable (WDT disabled) 
#pragma config PWRTE = ON  // Power-up Timer Enable (PWRT enabled) 
#pragma config MCLRE = ON  // MCLR Pin Function Select (MCLR/VPP pin function is MCLR) 
#pragma config CP = OFF   // Flash Program Memory Code Protection (Program memory code protection is disabled) 
#pragma config CPD = OFF  // Data Memory Code Protection (Data memory code protection is disabled) 
#pragma config BOREN = ON  // Brown-out Reset Enable (Brown-out Reset enabled) 
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin) 
#pragma config IESO = ON  // Internal/External Switchover (Internal/External Switchover mode is enabled) 
#pragma config FCMEN = ON  // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled) 

// CONFIG2 
#pragma config WRT = OFF  // Flash Memory Self-Write Protection (Write protection off) 
#pragma config PLLEN = OFF  // PLL Enable (4x PLL disabled) -> Maximal 16 MHZ möglich, da Speisung nicht 100% zuverlässig. 
#pragma config STVREN = ON  // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset) 
#pragma config BORV = LO  // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.) 
#pragma config LVP = OFF  // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming) 

return; 

} 

void initdevice(){ 
OSCCON = 0b01111000;  //PLLEN ist deaktiviert, da der PIC mit den 16 MHz vom internen Oszillator betreibt wird. 

//WDTCON = 0b00?????1;  //@Todo Frequenz des Watchdog Timers muss noch festgelegt. Zudem muss er noch im Config1 freigeschalten werden. 

APFCON0 = 0b00000000;  //Keine Pinfunktionen gewechselt. 
APFCON1 = 0b00000000;  //Keine Pinfunktionen gewechselt. 

PORTA = 0b00000000;   //Jeder Pin wird zur Sicherheit deaktiviert. 
TRISA = 0b00001000;   //Master Clear (MCLRE) kann nur als Eingang definiert werden. 
LATA = 0b00000000;   //Zur Sicherheit wird auch der Latch deaktiviert. 
ANSELA = 0b00000000;  //Keine Analogeingänge festgelegt. 

PORTB = 0b00000000;   //Jeder Pin wird zur Sicherheit deaktiviert. 
TRISB = 0b01000000;   //RB6 ist Eingang für Jumper_VCC. Der Rest sind alles Ausgänge. 
LATB = 0b00000000;   //Zur Sicherheit wird auch der Latch deaktiviert. 
ANSELB = 0b00000000;  //Keine Analogeingänge festgelegt. 

PORTC = 0b00000000;   //Jeder Pin wird zur Sicherheit deaktiviert. 
TRISC = 0b01001111;   //@Todo Pinbelegung muss noch beschrieben werden. 
LATC = 0b00000000;   //Zur Sicherheit wird auch der Latch deaktiviert. 
ANSELC = 0b00001111;  //@Todo Pinbelegung muss noch beschrieben werden. 

ADCON0 = 0b00110000;  //Die AD-Wandler wird noch deaktiviert und das Status Bit wurde aus Vorsicht gelöscht. Als erster Analogeingang wird keiner festgelegt, da dieser sowieso vor der Messung festgelegt wird. 
ADCON1 = 0b11100011;  //Die Ausrichtung des ADC-Registers ist rechtsbündig, die Arbeitsfrequenz beträgt 250 kHZ (Vierundsechtzigstel von der Grundfrequenz und Referenzspannung kommt von der intern Referenzspannung auf 2,048 BDC. 
FVRCON = 0b11000010;  //Es wird die interne 2.048 VDC Referenzspannung für den ADC verwendet. 

INTCON = 0b11101000;  //Interrupts werden zur Benützung des Analog-Digital-Wandlers und für die Delay-Funktion benötigt. Extern werden keine Interrupts ausgelöst. Flag Bits werden zur Vorsicht gelöscht. 
PIE1 = 0b01000110;   //Gibt die nötigen Interrupts für den Analog-Digital-Converter, den Half-Bridge Mode und der Delay-Funktion frei. 
//PIE2 wird nicht benötigt. 
PIE3 = 0b00000010;   //Gibt den Timer4-Interrupt frei, um zu erkennen, wann der PWM fertig ist. 
//PIE4 wird nicht benötigt. 
PIR1 = 0b00000000;   //Alle Flags, welche verwendet werden, werden zur Sicherheit zurückgesetzt. 
//PIR2 - PIR4 werden nicht zurückgesetzt, da die PIE2 - PIE4 nicht benötigt werden und so keine Überprüfung der Flags stattfindet. 

//Warning PWM-Modul erst freigeben, wenn ein Durchlauf gemacht wurde, sonst könnte Kurzschluss von beiden PWM-Ausgängen auftreten !!! 
T4CON = 0b00000101;   //PWM-Timer wird noch ausgeschalten gelassen und mit einer Frequenz von 125 khz betrieben, sobald er eingeschaltet ist. 
CCP1CON = 0b10111100;  //PWM-Ausgang als alternativer Half-Bridge-Mode festgelegt, die Duty-Cycle-Bits werden zurückgesetzt und alle Ausgänge auf active-high gestellt. 
CCPTMRS = 0b11111101;  //PWM-Signal von PWM-Quelle 1 wird von Timer4 versorgt. Die anderen werden nicht benötigt. 
ECCP1AS = 0b00000000;  //Möglich Shut Down Flags werden gelöscht und Shtudown durch externe Einflüsse deaktiviert. 
PWM1CON = 0b10001000;  //Falls ein Shutdown eintritt, wird der PWM automatisch neu gestartet und die Dead-Time beträgt 2 us (4*8 Takte Mikrocontroller (32 Takte), da die Ausschaltzeit der FETs bei 16 ns und die der Transistoren bei ungefähr 1 us liegen und dies die tiefste Zeit ist. 
PSTR1CON = 0b00010011;  //PWM-Veränderungen werden in der nächsten Periode übernommen und Wellenform wird nach Polarität von CCPxM<1:0> übernommen. 
} 

Ce serait bien, quand quelqu'un pourrait me aider à comprendre la raison, pourquoi il ne fonctionne pas.

+0

La conduite d'un négatif d'entrée analogique au-delà d'une certaine limite provoquera la réinitialisation. Le signal d'entrée vers ADC a-t-il une tension négative? –

+0

Le bit 6 de 'PIE1 = 0b01000110 'n'est-il pas activé? Autoriser l'interruption ADC? Mais vous semblez interroger l'appareil. –

+0

De plus, les # pragma ne sont pas du code. N'essayez pas de les exécuter, cela ne fera rien. Mettez-les simplement dans leur propre dossier. – ElderBug

Répondre

1
PIE1 = 0b01000110; 

Vous avez activé les interruptions ADC. Avec votre code actuel, peu importe ce que vous avez écrit ailleurs, cela ne fonctionnera pas. Votre code s'est écrasé en essayant de sauter vers un gestionnaire inexistant, ou est resté bloqué pour toujours dans l'interruption.
Comme vous n'utilisez pas d'interruptions ADC, ne les activez pas; le PIR1bits.ADIF est indépendant et sera défini même si les interruptions sont désactivées (ou vous pouvez interroger ADCON0bits.GO_nDONE pour le même effet).

+0

Merci pour ce tipp. Maintenant, il peut commencer la mesure, mais le drapeau AD du 'PIR1bits.ADIF' ne se produira pas. – Zoozuu

+0

@Zoozuu Le fait qu'il ait planté avant presque certainement signifie que 'PIR1bits.ADIF' est réglé correctement. Et la documentation indique _ "Le bit ADIF est défini à la fin de chaque conversion, que l'interruption ADC soit activée ou non." _. Avez-vous changé quelque chose à côté de 'PIE1'? – ElderBug

+0

Vous ne devriez pas effacer le bit 'GO'. Cela se fait automatiquement après le chargement de 'ADRESH: ADRESL', et l'utilisateur efface seulement' GO' si le cycle de conversion doit être annulé. En même temps, le bit 'ADIF' est défini. "Remarque 1: Le bit ADIF est défini à la fin de chaque conversion, que l'interruption ADC soit activée ou non." Je vous suggère de lire en détail la section * de la feuille de données PDF *, il se peut que vous manquiez d'autres réglages. –