Consejos de codificación c18/error de llaves/ayuda de declaración de función

Casi NO tengo experiencia en codificación, así que disculpe el estilo crudo y los comentarios detallados. Estoy tratando de tomar muestras de 4 sensores (1 cada 15 minutos). Pensé que sería más eficiente tener las funciones delayy data_writecomo funciones separadas para llamar, pero eso no está funcionando muy bien. Constantemente obtengo el siguiente error:

Error [1302] declaraciones de función de estilo antiguo no admitidas

al final de la data_writefunción, no importa dónde o cómo coloque las llaves (anidado, en la misma línea, eliminar, etc.), delayla función no da el error ya sea antes o después de la data_writefunción.

Por favor, siéntase libre de recomendarme un diseño mejor. Además, realmente no tengo ningún conocimiento de la memoria de datos, por lo que esta rutina probablemente sea una mierda, lo sé. Sin embargo, extrañamente no me da ningún error, así que no miraré a ese caballo regalado en la boca todavía.

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

    #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; }

Respuestas (3)

Todas las otras respuestas tienen buenos puntos y señalan otros problemas, pero la razón específica por la que recibe el error old style function declarations not supportedes porque a la declaración de su data_writefunción le faltan los tipos. Necesita ser cambiado de

void data_write (data_adr, result)

a

void data_write (int data_adr, int result)
Tengo otra pregunta sobre una parte específica de este código, la función data_write en realidad (con ensamblaje). Supongo que debería hacerla como una nueva pregunta en lugar de seguir volviendo a publicar bloques de código similares.

Primero, deshazte del retorno en la función principal. ¿A dónde vas a devolver los datos? No hay sistema operativo y el retorno no tiene sentido, por lo que podría ser fuente de algunos problemas.

¿Cómo exactamente vas a generar los datos? Parece que está tratando de escribir en la memoria de datos, pero ¿qué va a hacer después de eso, quitar el chip y leer físicamente la EEPROM usando un programador?

A continuación, sí, necesita while (1) para seguir recorriendo correctamente la función. Puede obtener algún tipo de bucle incluso sin tiempo. Si no recuerdo mal, el flash PIC18 está lleno de NOP de forma predeterminada. Seguirá ejecutando instrucciones hasta que se alcance el final del espacio de direcciones, después de lo cual debería (nuevamente, si no recuerdo mal) dar la vuelta y volver a la primera instrucción. No debe confiar en esta función y, en su lugar, debe envolver los contenidos de main con while (1) o equivalente.

A continuación, los errores en sí: Bueno, el manual del compilador establece que no está relacionado con las llaves en absoluto. Está relacionado con el estilo de declaración de funciones. En realidad, debe escribir el tipo de variable y el nombre al declarar una función. Lo que ha creado son variables con el mismo nombre que las variables globales. Cuando su código está en función, no utilizará variables globales. En su lugar, utilizará variables locales con ese nombre que enmascararán las variables globales.

También estás llamando mal a las funciones. ¡Necesita enumerar los argumentos cuando llama a las funciones!

A continuación, en el prototipo C18, main debe ser void main (vacío), lo que va bien con la regla de no retorno que mencioné antes.

También parece llamar nombres de registro incorrectamente. Intente leer en el manual del usuario cómo C18 llama a cada registro en el PIC y cómo direccionar cada bit individual de un registro. Por ejemplo, lo usaría INTCON1bits.GIEpara acceder al bit de activación de interrupción general en el registro de control de interrupción uno.

Otra cosa que he notado es que usas int para el contador de bucles. No hagas eso si puedes evitarlo. Intente usar caracteres tanto como sea posible, ya que son el tipo de datos nativo de la MCU. Ints tardará más en procesarse y dará como resultado bucles más lentos de lo esperado.

También mencionó funciones y eficiencia. Tenga en cuenta que C18 no puede realizar funciones en línea, por lo que si alguna vez tiene la necesidad de llamar a una función de manera eficiente, tendrá que reemplazarla con una macro.

AndrejaKo, Gracias por la respuesta. Pensé que dado que la función principal necesitaba pasar "resultado" a la función data_write, tenía que declararlo de esa manera. Si omito el retorno, ¿la función data_write seguirá teniendo acceso a la variable "resultado"? Se supone que los datos se registran simplemente. Mi plan era recuperar a través de ICSP o similar. Esa parte no es muy importante para mí. Como el error del compilador se detiene en la llave de cierre y especifica que es un problema de formato K&R, pensé eso. Creo que entiendo el problema de las variables globales. Voy a cambiar el nombre.
lo siento por mi formato aquí, también. Yo tampoco estoy acostumbrado.
Además, el formato para abordar esos bits es directamente de mi libro de texto (microcontroladores Huang -Pic). Veo su punto y lo he hecho antes con bits de puerto, así que también puedo cambiar eso, no hay problema. Solo estaba tratando de ser hábil y llamar a funciones en lugar de cortar/pegar el mismo código dentro de main. Gracias por el aporte. :-D
@Mark Bueno, para mí, parece que necesita aprender un poco de C antes de intentar programar microcontroladores en C. Eche un vistazo a este tutorial, por ejemplo. Básicamente, el retorno se usa para proporcionar resultados de una función a la función que la llamó.
Gracias AdrejaKo. Aprecio tu paciencia. De hecho, estoy tomando la clase ahora, pero el instructor no da muchos ejemplos y parece asumir que todos somos programadores. Sin embargo, se supone que este curso no requiere experiencia en programación. Lo siento por las preguntas básicas.

Como señala Andreja, no está utilizando correctamente la declaración de devolución.
Además, ahora que se ha editado el mensaje de error real, deja en claro que el error relacionado con usted data_writese debe a que no declaró los tipos de argumento como dice Jim en su respuesta. Puede ver ejemplos de cómo deben declararse en el código a continuación.

La returndeclaración se usa para devolver un resultado a la persona que llama, de cierto tipo dictado por la definición de la función.

Por ejemplo, esta función devuelve un int:

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

Para usar lo anterior, haces algo como:

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

Pero esta función no acepta ningún argumento ni devuelve nada (tenga en cuenta el voidtipo de retorno/argumento):

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

Hay muchos usos para una función sin retorno/argumentos, por ejemplo, configurar un periférico, inicializar la memoria, etc.

Otra forma de recuperar información de una función es usar un puntero pasado como argumento:

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

Para usar lo anterior, pasamos la dirección de la variable de resultado como tercer argumento (el &operador):

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

Entonces, con suerte, puede ver que no sirve de nada tener una returndeclaración para una función declarada como void, (a menos que desee regresar temprano como parte de alguna lógica de decisión, similar a las declaraciones continuey break, que no tiene en sus funciones anteriores) Si desea devolver algo, declare el tipo al comienzo de la definición de la función. Como sugiere Andreja, haría un poco de lectura sobre las funciones básicas de C y los punteros.

Gracias Oli, eso es muy útil. Tienes razón, estaba confundido acerca de la principal. Tenía la intención de poner algo como int main () pensando que el retorno pasaría el "resultado" fuera de main, a la función de "escritura de datos". Tengo mucho que aprender.