Forum: Mikrocontroller und Digitale Elektronik Fehler mit 2 ADC-Eingang


von Jin L. (jinli)


Lesenswert?

Hallo Leute,

für ein Projekt schreibe ich gerade ein Programm für mein µC, das 
folgende machen soll:

Durch ein Metalloxid Sensor wird einige Gasgruppe detektiert und ein 
Spannungswert an dem µC weitergeleitet, durch ADC umgewandelt und dann 
werden die Werte wird von Matlab aufgenommen und als Graph 
eingezeichnet.

Weil der Sensor sehr temperaturabhängig ist, habe ich noch ein 
Thermistor in meine Schaltung eingebaut um die Abweichungen durch 
Temperatur zu dämpfen. Soll heißen, der Ausgang an Thermistor lese ich 
auch ab und wandle sie um und je nach dem wie groß diese Wert ist, wird 
eine Korrektur in µC programm durchgeführt.

Problem : Da ich ein PIC18f45k20 benutze und nur ein ADC habe, muss ich 
quasi zw. 2 Kanäle umschalte und die beide Werte abwechselnd einlese. Da 
muss ich doch nur die Werte von der SFR ADCON0 dementsprechend verändern 
oder?
Was meint dann MPLab X dann mit

newfile.c:110: error: function does not take arguments
newfile.c:111: error: function does not take arguments
newfile.c:150: error: type redeclared
newfile.c:150: error: conflicting declarations for variable 
"ADC_Convert" (Sensor.h:21)

wenn in Zeile 110 und 111:
        ADC_Convert(1);
        ADC_Convert(0);
und 150 folgende steht:

unsigned char ADC_Convert(unsigned char channel)
{ // start an ADC conversion and return the 8 most-significant bits of 
the result

    if (channel == 0) {
        ADCON0 = 0b00000101;  // ADCON0 = 0b00000101 entspricht Kanal 
(RA1/AN1) (Kabel) Luftsensor
        ADCON0bits.GO_DONE = 1;             // start conversion
        while (ADCON0bits.GO_DONE == 1);    // wait for it to complete
        adc_high = ADRESH;
  adc_low  = ADRESL;
        return adc_high;                      // return high byte of 
result
    }
    else if ( channel ==1){

        ADCON0 = 0b00001001;  // ADCON0 = 0b00001001 entspricht Kanal 
(RA2/AN2) (Kabel) Temp sensor
        ADCON0bits.GO_DONE = 1;             // start conversion
        while (ADCON0bits.GO_DONE == 1);    // wait for it to complete
        temp_high = ADRESH;
  temp_low  = ADRESL;
        return temp_high;                      // return high byte of 
result
    }
}

Wär ungemei dankbar für jede Hilfe

JinLi

von Karl H. (kbuchegg)


Lesenswert?

Die beiden Fehlermeldungen
1
newfile.c:150: error: type redeclared
2
newfile.c:150: error: conflicting declarations for variable "ADC_Convert" (Sensor.h:21)

könnten zb daraus resultieren, dass du einen Prototyp für für die 
Funktion hast, der nicht mit der tatsächlichen Funktion übereinstimmt.
Auch ist es ein wenig seltsam, dass der Compiler der Ansicht ist, dass 
es eine Variable dieses Namens gibt. Und zwar in der Datei sensor.h

Nimm den Text "ADC_Convert" in deinem Editor in das Suchfeld und such 
mal alle Stellen auf, an denen dieser Text vorkommt und gleiche das mal 
konsistent ab. Du hast da irgendwo ein Mischmasch produziert.

Wenn du nicht weiter kommst, dann poste den kompletten Code.

: Bearbeitet durch User
von Jin L. (jinli)


Lesenswert?

Hallo Karl.

danke für die Hilfe.
Ich sehe gerade dass ich in mein header datei sensor.h den Prototype 
ADC_Convert habe. Aber was da steht bin ich leider überfragt, vlt kannst 
du mir wieder auf die sprünge helfen.

hier ist der header sensor.h

#ifndef PICKIT_H
#define PICKIT_H

/** D E C L A R A T I O N S *****************/

//typedef enum {FALSE, TRUE} BOOL;


/** D E F I N I T I O N S ********************/
#define Switch_Pin      PORTBbits.RB0
#define DetectsInARow   5

/** E X T E R N S *****************************/
// declare variables accessible by other files.

/** P R O T O T Y P E S ***********************/

void ADC_Init(void);
unsigned char ADC_Convert(void);

#endif

von Jin L. (jinli)


Lesenswert?

Mein gesamt Code:

/** C O N F I G U R A T I O N   B I T S ******************************/

#pragma config FOSC = INTIO67, FCMEN = OFF, IESO = OFF 
// CONFIG1H
#pragma config PWRT = OFF, BOREN = OFF, BORV = 30 
// CONFIG2L
#pragma config WDTEN = OFF, WDTPS = 32768 
// CONFIG2H
#pragma config MCLRE = OFF, LPT1OSC = OFF, PBADEN = ON, CCP2MX = PORTC 
// CONFIG3H
#pragma config STVREN = ON, LVP = OFF, XINST = OFF 
// CONFIG4L
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF 
// CONFIG5L
#pragma config CPB = OFF, CPD = OFF 
// CONFIG5H
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF 
// CONFIG6L
#pragma config WRTB = OFF, WRTC = OFF, WRTD = OFF 
// CONFIG6H
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF 
// CONFIG7L
#pragma config EBTRB = OFF 
// CONFIG7H

/** I N C L U D E S **************************************************/
#include "p18f45k20.h"
#include "usart.h"   //hader f? uart-communikation
#include "Sensor.h"  // header file
#include "math.h"  // haeder f? Mathematische berechnungen
#include "stdio.h" // hesder f?...
#include "../include/plib/delays.h"
#include "../include/stdlib.h"
#include <string.h>


/** V A R I A B L E S *************************************************/
unsigned char LED_Display;  // 8-bit variable
int adcwert = 0;

unsigned char channel;
unsigned char adc_high;
unsigned char adc_low;

unsigned char temp_high;
unsigned char temp_low;

unsigned char const T1 = 85;
unsigned char const T2 = 100;


/** D E C L A R A T I O N S *******************************************/

void main (void)
{

    LED_Display = 1;            // initialize

    // Init I/O
  TRISC=0x00;                       // Set all of PORTC as outputs. TX 
and RX must be set as outputs first for uart com.
        TRISD = 0b00000000;                    // PORTD bits 7:0 are all 
outputs (0)
  //TRISAbits.TRISA0 = 1;                 // input-Bit setzen: TRISA0 = 
1 (=> drehpoti ist input),

        TRISAbits.TRISA2 = 1;                   // Temp input-Bit
        TRISAbits.TRISA1 = 1;                   // Sensor input-Bit

  INTCON2bits.RBPU = 0;                   // enable PORTB internal 
pullups
  WPUBbits.WPUB0 = 1;      // enable pull up on RB0

    // ADCON1 is now set up in the InitADC() function.
         TRISBbits.TRISB0 = 1;       // PORTB bit 0 (connected to 
switch) is input (1)

    // Init ADC
        ADC_Init();

    //Uart-Einstellungen:
  OpenUSART( USART_TX_INT_OFF &
                    USART_RX_INT_OFF &
                    USART_ASYNCH_MODE &
                    USART_EIGHT_BIT &
                    USART_CONT_RX &
                    USART_BRGH_HIGH &
                    USART_ADDEN_ON, 25);  //Config_bits (1 MHz Osc, Baud 
rate 2400 )

    while (1)
    {
        ADC_Convert(1);
        ADC_Convert(0);
        if (temp_high > T1) {
            adc_high = adc_high+50;
        }

        putcUSART(adc_high);

    //    LED Ausgabe:
          //    LATD = AnzWert;                 // outputt ADC_Convert 
Wert von o bis 7 (siehe oben)
    LATD = adc_high;      // output ADC_Convert Value to PORTD LEDs 
(direckt bin?)

    Delay1KTCYx(50);                      // 100ms Delay (wert:25 = 
100ms delay)
    }

}



void ADC_Init(void)
{ // initialize the Analog-To-Digital converter.

  ANSEL = 0;  //turn off all other analog inputs
  ANSELH = 0;
   //ANSELbits.ANS0 = 1;    // turn on RA0/AN0 als analog input 
(Drehpoti)
        ANSELbits.ANS1 = 1;   // turn on RA1/AN1 als analog input 
(Sensor)
        ANSELbits.ANS2 = 1;   // turn on RA2/AN2 als analog input 
(Thermistor)
    // Sets bits VCFG1 and VCFG0 in ADCON1 so the ADC voltage reference 
is VSS to VDD

     ADCON1 = 0; // kein externe referenzspannung

      ADCON2 = 0b00111000;              // ADRESH und Low linksbuendig


}



unsigned char ADC_Convert (unsigned char channel)
{ // start an ADC conversion and return the 8 most-significant bits of 
the result

    if (channel == 0) {
        ADCON0 = 0b00000101;  // ADCON0 = 0b00000101 entspricht Kanal 
(RA1/AN1) (Kabel) Luftsensor
        ADCON0bits.GO_DONE = 1;             // start conversion
        while (ADCON0bits.GO_DONE == 1);    // wait for it to complete
        adc_high = ADRESH;
  adc_low  = ADRESL;
        return adc_high;                      // return high byte of 
result
    }
    else if ( channel ==1){

        ADCON0 = 0b00001001;  // ADCON0 = 0b00001001 entspricht Kanal 
(RA2/AN2) (Kabel) Temp sensor
        ADCON0bits.GO_DONE = 1;             // start conversion
        while (ADCON0bits.GO_DONE == 1);    // wait for it to complete
        temp_high = ADRESH;
  temp_low  = ADRESL;
        return temp_high;                      // return high byte of 
result
    }
}

von Karl H. (kbuchegg)


Lesenswert?

Jin Li schrieb:

> unsigned char ADC_Convert(void);

Da steht:
ADC_Convert ist eine Funktion, die keine Argumente nimmt (daher das 
void) und die einen Returnwert vom Typ unsigned char liefert.

Soweit so gut. Das ist das was da steht.

Und? Wie sieht die Funktion wirklich aus?
So
1
unsigned char ADC_Convert (unsigned char channel)
2
{
3
  ....
4
}

Das stimmt also schon mal nicht mit dem Protoypen überein. Die Funktion 
nimmt eben nicht 'keine Argumente' sonder sie nimmt 1 Argument, welches 
vom Typ unsigned char ist.

Ergo: Du hast im Protoypen den Compiler angelogen. Er hat sich drauf 
verlassen und hat seine Kentnisse, die du ihm mit dem Protoypen 
geliefert hast benutzt um den Aufruf hier
1
   ADC_Convert(1);
zu kontrollieren.
Der Prototyp hat ausgesagt: keine Argumente.
Aber der Aufruf hier will ein Argument mitgeben.
Das passt daher nicht zusammen. Daher die Fehlermeldung
1
newfile.c:110: error: function does not take arguments

Später dann während des Übersetzungsvorgangs ist der Compiler dann auf 
die tatsächliche Implementierung gestossen. Bis hier her hatte er nur 
den Protoypen. Und der Prototyp, wie wir schon wissen, sagte ja aus: 
keine Argumente.
Nur in der Funktionsdefinition sind plötzlich Argumente. Auch das passt 
wieder nicht zusammen. Daher die Fehlermeldung
1
newfile.c:150: error: type redeclared


Fazit: Lüg deinen Compiler nicht an. Wenn eine Funktion Argumente nimmt, 
dann kann der Protoyp nicht behaupten, da wären keine! Protoyp und 
tatsächliche Funktion müssen übereinstimmen!

In sensor.h
1
...
2
unsigned char ADC_Convert (unsigned char channel);
3
...

> Wär ungemei dankbar für jede Hilfe
Wie wärs mit einem C-Buch?

: Bearbeitet durch User
von Jin L. (jinli)


Lesenswert?

danke dir Karl, es klappt jetzt.

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.