Reputation: 1
Since one week I have the problem, that my PIC 16LF1829 does itself reset, when he's measuring the selected adc channel. I talked to several co-workers, but none could me help by that. I tried to change the adc-frequency, changed the voltage reference and the selected channel.
The Problem occurs, when the adc try to execute the adc-measure. Here are my code with german comment:
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.
}
Also here my 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.
}
It would be great, when someone could help me to understand the reason, why it didn't work.
Upvotes: 0
Views: 695
Reputation: 6145
PIE1 = 0b01000110;
You enabled ADC interrupts. With your current code, no matter what you wrote elsewhere, it won't work. Your code either crashed trying to jump to an inexistant handler, or is stuck forever in the interrupt.
Since you aren't using ADC interrupts, don't enable them ; the PIR1bits.ADIF
is independent, and will be set even with interrupts disabled (or you can poll ADCON0bits.GO_nDONE
for the same effect).
Upvotes: 1