c18-Codierungsratschlag / Fehler in geschweiften Klammern / Hilfe zur Funktionsdeklaration

Ich habe fast KEINE Erfahrung im Programmieren, also entschuldigen Sie bitte den groben Stil und die ausführlichen Kommentare. Ich versuche, von 4 Sensoren abzutasten (1 alle 15 Minuten). Ich dachte, es wäre effizienter, die Funktionen delayund data_writeals separate Funktionen aufzurufen, aber das funktioniert einfach nicht sehr gut. Ich bekomme ständig folgenden Fehler:

Fehler [1302] Funktionsdeklarationen im alten Stil werden nicht unterstützt

am Ende der data_writeFunktion, egal wo oder wie ich die geschweiften Klammern (verschachtelt, gleiche Zeile, eliminieren usw.) setze, delaygibt die Funktion nicht den Fehler aus, ob sie vor oder nach der data_writeFunktion steht.

Bitte fühlen Sie sich frei, mir ein besseres Layout zu empfehlen. Außerdem habe ich wirklich kein Verständnis für den Datenspeicher, also ist diese Routine wahrscheinlich Mist, ich weiß. Seltsamerweise gibt es mir jedoch keine Fehler, also werde ich diesem geschenkten Gaul noch nicht ins Maul schauen.

====================================

    #include <stdio.h>
    #include <stdlib.h>
    #include <p18f452.h>
    #include <delays.h>
    #include <adc.h>

    int result;                         // used in ADC result handling
    int i;                              // used in delay loop/function
    int data_adr=0x64;                  // used in data_write function. initial=d100

    // assuming 4MHz oscillator => 8fosc.   Tinst= (4)*Tosc = (4)*(250ns) = 1us
    // all 4 sensors should read every minute so each will begin sequentially,
    // after 15sec delay from previous ADC conversion completes.

    void delay (void);                 // delay function prototype declaration
    void data_write (int, int);             // data-write function prototype declaration

    main()
    {
    // I think I need a while (1) loop here to repeat the loop forever???

    // sensor 1 configured to port AN0
        OpenADC(ADC_FOSC_8 & ADC_RIGHT_JUST & ADC_5ANA_0REF, ADC_CH0 & ADC_INT_OFF);
                            //configures ADC for port AN0 = sensor 1 input
            delay();                    // call the delay function
            ConvertADC();               // initiate conversion of sensor1 @ AN0
            while(BusyADC());           // waiting to complete conversion
            result=ReadADC();           // read the result of sensor1 @ AN0
            data_write();               // call data_write function
        CloseADC();


    // sensor 2 configured to port AN1
        OpenADC(ADC_FOSC_8 & ADC_RIGHT_JUST & ADC_5ANA_0REF, ADC_CH1 & ADC_INT_OFF);
                            //configures ADC for port AN1 = sensor 2 input
           delay();
           ConvertADC();
           while(BusyADC());
           result=ReadADC();
           data_write ();
        CloseADC();

    // sensor 3 configured to port AN2
        OpenADC(ADC_FOSC_8 & ADC_RIGHT_JUST & ADC_5ANA_0REF, ADC_CH2 & ADC_INT_OFF);
                            //configures ADC for port AN2 = sensor 3 input
           delay();
           ConvertADC();
           while(BusyADC());
           result=ReadADC();
           data_write ();
        CloseADC();

    // sensor 4 configured to port AN3
        OpenADC(ADC_FOSC_8 & ADC_RIGHT_JUST & ADC_5ANA_0REF, ADC_CH3 & ADC_INT_OFF);
                            //configures ADC for port AN3 = sensor 4 input
           delay();
           ConvertADC();
           while(BusyADC());
           result=ReadADC();
           data_write ();
        CloseADC();

        return (result);
    }

    // Delay function sequence
    void delay (void)
    {                                       // 15second delay routine
                                    // 15sec/Tinst= 15sec/1us
                                    // = 15*10^6 Tinst = 10K * 1500
                                    // Delay10KTCYx(1)= 0.01sec
                                    // = (10K)*(250)*(6)
        i=6;
        while(i>0) {
           Delay10KTCYx(250);      // 2.5sec delay
            i=i--;                  // run 6 times for total 15sec delay loop
        }
        return;
    }

    // data write sequence
    void data_write (data_adr, result) {
         _asm
         movlw  data_adr        // starting data memory address = data_adr
         movwf  EEADR,A
         movlw  result              // gets data stored in "result" variable
         movwf  EEDATA,A            // places data into data memory holder
         bcf    EECON1,EEPGD,A      // points to data memory
         bcf    EECON1,CFGS,A       // access data eeprom
         bsf    EECON1,WREN,A       // enable write to data EEPROM
         bcf    INTCON,IE,A         // disable interrupt
         movlw  0x55                // start flash erase sequence
         movwf  EECON2,A
         movlw  0xAA
         movwf  EECON2,A            // end flash erase sequence
         bsf    EECONN1,WR,A        // enable bit to start the write operation
         bsf    INTCON,GIE,A        // re-enable interrupt
         bcf    EECON1,WREN         // restores the write command to =disabled
         _endasm

         data_adr = data_adr+2;
         if (data_adr >= 0xC6)      // if address >= d'198
             data_adr = 0x64;       // resets starting point to d'100

        return; }

Antworten (3)

Alle anderen Antworten haben gute Punkte und weisen auf andere Probleme hin, aber der spezifische Grund, warum Sie den Fehler erhalten, old style function declarations not supportedist, dass Ihrer data_writeFunktionsdeklaration die Typen fehlen. Es muss geändert werden

void data_write (data_adr, result)

Zu

void data_write (int data_adr, int result)
Ich habe eine weitere Frage zu einem bestimmten Teil dieses Codes, nämlich der data_write-Funktion (mit Assembly). Ich nehme an, ich sollte es als neue Frage stellen, anstatt ähnliche Codeblöcke immer wieder neu zu posten?

Entfernen Sie zuerst die Rückkehr in der Hauptfunktion. Wohin werden Sie die Daten zurückgeben? Es gibt kein Betriebssystem und die Rückgabe ist bedeutungslos, daher könnte dies die Quelle einiger Probleme sein.

Wie genau willst du die Daten ausgeben? Sieht so aus, als würden Sie versuchen, in den Datenspeicher zu schreiben, aber was werden Sie danach tun, den Chip entfernen und das EEPROM mit einem Programmiergerät physisch lesen?

Als Nächstes brauchen Sie while (1), um die Funktion ordnungsgemäß zu durchlaufen. Sie können auch ohne while eine Art Schleife erhalten. Wenn ich mich richtig erinnere, ist der PIC18-Flash standardmäßig mit NOPs gefüllt. Es wird weiterhin Anweisungen ausführen, bis das Ende des Adressraums erreicht ist, wonach es (wiederum, wenn ich mich richtig erinnere) umbrechen und zur ersten Anweisung zurückkehren sollte. Sie sollten sich nicht auf diese Funktion verlassen und stattdessen den Inhalt von main mit while (1) oder etwas Äquivalentem umschließen.

Als nächstes die Fehler selbst: Nun, das Compiler-Handbuch gibt an, dass es überhaupt nichts mit geschweiften Klammern zu tun hat. Es hängt mit dem Stil der Funktionsdeklaration zusammen. Sie müssen tatsächlich den Typ der Variablen und den Namen schreiben, wenn Sie eine Funktion deklarieren. Was Sie erstellt haben, sind Variablen mit demselben Namen wie globale Variablen. Wenn Ihr Code in Funktion ist, verwendet er keine globalen Variablen. Stattdessen werden lokale Variablen mit diesem Namen verwendet, die globale Variablen maskieren.

Außerdem rufst du Funktionen schlecht auf. Sie müssen die Argumente tatsächlich auflisten, wenn Sie Funktionen aufrufen!

Als nächstes muss in C18 der Prototyp für main void main (void) sein, was gut zu der zuvor erwähnten No-Return-Regel passt.

Sie scheinen auch Registernamen falsch zu nennen. Versuchen Sie tatsächlich, im Benutzerhandbuch zu lesen, wie C18 jedes Register im PIC aufruft und wie jedes einzelne Bit eines Registers adressiert wird. Zum Beispiel würden Sie verwenden, INTCON1bits.GIEum auf das allgemeine Interrupt-Aktivierungsbit im Interrupt-Steuerregister Eins zuzugreifen.

Eine andere Sache, die mir aufgefallen ist, ist, dass Sie int für Schleifenzähler verwenden. Tun Sie das nicht, wenn Sie es vermeiden können. Versuchen Sie, so viel wie möglich Zeichen zu verwenden, da es sich um den nativen Datentyp der MCU handelt. Die Verarbeitung von Ints dauert länger und führt zu langsameren Schleifen als erwartet.

Sie haben auch Funktionen und Effizienz erwähnt. Denken Sie daran, dass C18 kein Inlining von Funktionen ausführen kann. Wenn Sie also jemals eine Funktion effizient aufrufen müssen, müssen Sie sie durch ein Makro ersetzen.

AndrejaKo, Danke für die Antwort. Ich dachte, da die Hauptfunktion "Ergebnis" an die data_write-Funktion übergeben musste, musste ich es so deklarieren. Wenn ich die Rückgabe weglasse, hat die data_write-Funktion immer noch Zugriff auf die "Ergebnis"-Variable? Die Daten sollen sozusagen einfach protokolliert werden. Mein Plan war, über ICSP oder ähnliches abzurufen. Dieser Teil ist nicht super wichtig für mich. Da der Compiler-Fehler an der schließenden geschweiften Klammer stoppt und angibt, dass es sich um ein K&R-Formatierungsproblem handelt, dachte ich das. Ich glaube, ich verstehe das Problem mit den globalen Variablen. Ich werde umbenennen.
Entschuldigung für meine Formatierung auch hier. Ich bin es auch nicht gewohnt.
Außerdem stammt das Format zum Adressieren dieser Bits direkt aus meinem Lehrbuch (Huang-Pic-Mikrocontroller). Ich verstehe Ihren Standpunkt und habe das zuvor mit Portbits getan, sodass ich das auch ändern kann, kein Problem. Ich habe nur versucht, geschickt zu sein und Funktionen aufzurufen, anstatt denselben Code in main auszuschneiden und einzufügen. Danke für die Eingabe. :-D
@Mark Nun, für mich sieht es so aus, als müssten Sie ein bisschen C lernen, bevor Sie versuchen, Mikrocontroller in C zu programmieren. Schauen Sie sich zum Beispiel dieses Tutorial an. Grundsätzlich wird return verwendet, um Ergebnisse einer Funktion an die Funktion zu liefern, die sie aufgerufen hat.
Danke AdrejaKo. Vielen Dank für Ihre Geduld. Ich nehme gerade an dem Kurs teil, aber der Dozent gibt nicht viele Beispiele und scheint anzunehmen, dass wir alle Programmierer sind. Dieser Kurs soll jedoch keine Programmiererfahrung voraussetzen. Es tut mir leid für die grundlegenden Fragen.

Wie Andreja betont, verwenden Sie die return-Anweisung nicht richtig.
Jetzt, da die eigentliche Fehlermeldung bearbeitet wurde, wird deutlich, dass der Fehler in Bezug auf Ihren Fehler data_writedarauf zurückzuführen ist, dass die Argumenttypen nicht deklariert wurden, wie Jim in seiner Antwort feststellt. Sie können Beispiele dafür sehen, wie sie im folgenden Code deklariert werden sollten.

Die returnAnweisung wird verwendet, um ein Ergebnis eines bestimmten, von der Funktionsdefinition vorgegebenen Typs an den Aufrufer zurückzugeben.

Diese Funktion gibt beispielsweise ein int zurück:

int add(int a, int b)
{
    int c;
    c = a + b;
    return c;
}

Um das Obige zu verwenden, tun Sie Folgendes:

int result;
result = add(5, 6); // result = 11

Aber diese Funktion akzeptiert keine Argumente und gibt nichts zurück (beachten Sie den voidRückgabe-/Argumenttyp):

void do_something(void)
{
    // do something here...
    //
}

Es gibt viele Verwendungsmöglichkeiten für eine Funktion ohne Rückgabe/Argumente - zum Beispiel das Einrichten eines Peripheriegeräts, das Initialisieren eines Speichers usw.

Eine andere Möglichkeit, Informationen von einer Funktion zurückzubekommen, besteht darin, einen als Argument übergebenen Zeiger zu verwenden:

void add(int a, int b, int* p_result)
{
    int temp;
    temp = a + b;
    *p_result = temp;
}

Um das Obige zu verwenden, übergeben wir die Adresse der Ergebnisvariablen als 3. Argument (den &Operator):

int result = 0;
int a = 6;
int b = 5;
add(a, b, &result); // result will equal 11 on function return

Sie können also hoffentlich sehen, dass es keinen Sinn macht, eine returnAnweisung für eine als deklarierte Funktion zu haben void(es sei denn, Sie möchten als Teil einer Entscheidungslogik früher zurückkehren - ähnlich wie bei continueund break-Anweisungen, die Sie in Ihren obigen Funktionen nicht haben) If Wenn Sie etwas zurückgeben möchten, deklarieren Sie den Typ am Anfang der Funktionsdefinition. Wie Andreja vorschlägt, würde ich etwas über die Grundlagen von C-Funktionen und -Zeigern lesen.

Danke Oli, das ist sehr hilfreich. Du hast Recht, ich war verwirrt über die wichtigsten. Ich wollte so etwas wie int main () setzen und dachte, die Rückgabe würde das "Ergebnis" aus main an die Funktion "data-write" übergeben. Ich habe viel zu lernen.