Autor Tema: error cuando declaro una variable tipo typedef en un .h  (Leído 2806 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado vra

  • PIC10
  • *
  • Mensajes: 27
error cuando declaro una variable tipo typedef en un .h
« en: 23 de Enero de 2020, 21:01:51 »
Hola a todos, espero hayan tenido excelente día. Tengo un error conceptual aquí y no encuentro un documento en el cual se explique de forma concisa qué puedo poner en los archivos de cabecera.

tengo un archivo "globales.h" donde creo las definiciones de mis varibles globales como sigue y gracias a las explicaciones de @KILLERJC:

Código: [Seleccionar]
#ifndef XC_GLOBALES_H
#define XC_GLOBALES_H

#include <xc.h> 

/*              Variables globales a usar en el sistema.                      */

typedef union                           /* Variable tipo estructura para      */
{                                       /* marcar eventos de interrupciones en*/
    unsigned int banderas;              /* marcar eventos de interrupciones en*/
    struct                              /* las interrupciones.                */
    {                                   
        unsigned int restantes:15;
        unsigned int tecla:1;           /* Bandera para indicar el uso de la
                                         * interrupción por notificación de
                                         * cambio en un pin.                  */
    } BANDERASBits;
} SENALES;

#endif /* XC_GLOBALES_H */

entonces supuse que podía declarar la variable en otro archivo de cabecera como sigue:

Código: [Seleccionar]
SENALES senales;                    /* Implementación de los banderas de      */
                                    /* control para las interrupciones        */

void Inicia_Interr(void);           /* Prototipo de función para configurar e
                                     * iniciar las fuentes de interrupción.   */

/* Prototipos de función para manejar las fuentes de interrupción */

void __attribute__((interrupt(no_auto_psv))) _T1Interrupt(void);/* Prototipo de
                                             * función para manejar la
                                             * interrupción del timer 1.      */

void __attribute__((interrupt(no_auto_psv))) _T2Interrupt(void);/* Prototipo de
                                             * función para manejar la
                                             * interrupción del timer 2.      */

void __attribute__((interrupt(no_auto_psv))) _CNInterrupt(void);/* Prototipo de
                                             * función para manejar la
                                             * interrupción por notificación
                                             * de cambio en los pines
                                             * seleccionados.                 */

pero tan pronto compilo el programa entonces me da error de múltiples definiciones de "senales" la cual está en una de las primeras líneas del segundo trozo de código, el error es el siguiente:

Código: [Seleccionar]
build/default/production/main.o(.nbss+0x0):C:\Users\valery\MPLABXProjects\Menu_LCD.X\main.c: multiple definition of `senales'
build/default/production/interrup.o(.nbss+0x0):C:\Users\valery\MPLABXProjects\Menu_LCD.X\interrup.c: first defined here
c:\program files (x86)\microchip\xc16\v1.33\bin\bin\..\bin/coff-ld.exe: Link terminated due to previous error(s).
make[2]: *** [dist/default/production/Menu_LCD.X.production.hex] Error 255
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2

BUILD FAILED (exit value 2, total time: 14s)

pero tan pronto quito esa declaración de ahí el error desaparece, asumí entonces que ese tipo de declaraciones no las puedo incluir en un archivo de cabecera pero la gran pregunta es...por qué?, he estado buscando info sobre lo válido o no válido en un archivo de cabecera y no encuentro nada.

Podrían sacarme de esta duda y además indicarme un buen documento donde ver lo que puedo incluir en un archivo de cabecera?

Gracias de antemano por la ayuda brindada.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:error cuando declaro una variable tipo typedef en un .h
« Respuesta #1 en: 23 de Enero de 2020, 22:52:15 »
¿Podrias pasar el proyecto? Me refiero a un minimo ejemplo. Porque veo que lo repetido es senales en minuscula, y no el typedef que es SENALES mayuscula.

Desconectado vra

  • PIC10
  • *
  • Mensajes: 27
Re:error cuando declaro una variable tipo typedef en un .h
« Respuesta #2 en: 24 de Enero de 2020, 06:46:42 »
¿Podrias pasar el proyecto? Me refiero a un minimo ejemplo. Porque veo que lo repetido es senales en minuscula, y no el typedef que es SENALES mayuscula.

De momento solo la estoy usando en los archivos adjuntados pero estoy confundido, estoy suponiendo que al escribir la línea
Código: [Seleccionar]
SENALES senales estoy haciendo declarando una variable llamada senales del tipo SENALES, estoy equivocado?.

NOTA: la declaración que me da error es si la declaro en interrup.h, en cambio si la declaro en interrup.c no da error; es por eso que supongo que es un problema con las declaraciones en los archivos de cabecera.
« Última modificación: 24 de Enero de 2020, 06:50:02 por vra »

Desconectado ALFREDOSKY

  • PIC16
  • ***
  • Mensajes: 118
Re:error cuando declaro una variable tipo typedef en un .h
« Respuesta #3 en: 24 de Enero de 2020, 14:00:39 »
Hola vra, me parece que el log de error dice que, senales, se definió primero en:

C:\Users\valery\MPLABXProjects\Menu_LCD.X\interrup.c

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:error cuando declaro una variable tipo typedef en un .h
« Respuesta #4 en: 24 de Enero de 2020, 14:43:48 »
Defini la variable en 1 solo archivo .c como:

Código: C
  1. SENALES senales

Y en el archivo .h usa esta linea:

Código: C
  1. extern SENALES senales

Desconectado vra

  • PIC10
  • *
  • Mensajes: 27
Re:error cuando declaro una variable tipo typedef en un .h
« Respuesta #5 en: 24 de Enero de 2020, 19:17:27 »
@ALFREDOSKY y @KILLERJC.

Si, no se por cuál razón daba ese error si no tenía declarada senales en la función interrup.c, en cualquier caso cambié las definiciones como sigue:

la declaración "SENALES senales" la cambié a interrup.c y ya no da error, además le quité el nombre a la estructura para no usar tantos nombres al llamar a cualquier miembro de la union-estructura; ahora los archivos lucen como sigue:

el archivo "interrup.c" es el siguiente:

Código: [Seleccionar]
#include "interrup.h"
#include "globales.h"


SENALES senales;                        /* Declaración de la variable senales */
//senales.tecla = 0;                      /* para usarla en la interrupción que */
                                        /* sea necesaria.                     */

void Inicia_Interr(void)                /* Función para configurar e iniciar
                                         * las fuentes de interrupción.       */
{
    IEC0bits.T3IE = 1;                  /* Se habilita la interrupción        */
                                        /* para el timer de 32 bits, se       */
    IPC2bits.T3IP = 1;                  /* establece la prioridad de la       */
    IFS0bits.T3IF = 0;                  /* interrupción en 1 y se borra la    */
                                        /* la bandera del timer de 32         */
                                        /* bits.                              */
   
    IEC1bits.CNIE = 1;                  /* Se habilitan los pines CN62 a CN65 */
    IPC4bits.CNIP = 2;                  /* para detectar el cambio de estado, */
    IFS1bits.CNIF = 0;                  /* esto es, los Puerto E,4 a Puerto   */
    CNEN4 = 0xc000;                     /* E,7 para detectar la tecla         */
    CNEN5 = 0x0003;                     /* presionada. También se configuró la*/
                                        /* prioridad de la interrupción por   */
                                        /* notificación de cambio de estado en*/
                                        /* 2, un nivel más alta que la del    */
                                        /* temporizador.                      */
}

/*               Funciones para el manejo de interrupciones                   */

void __attribute__((interrupt(no_auto_psv))) _T1Interrupt(void)/* Función para*/
{                                       /* manejo de la interrupción del      */
                                        /* timer 1, para usarlo como ciclo de */
    IFS0bits.T1IF =0;                   /* trabajo del sistema.               */
}

void __attribute__((interrupt(no_auto_psv))) _T3Interrupt(void)/* Función para*/
{                                       /* manejo de la interrupción del      */
    T2CONbits.TON = 0;                  /* timer 32 para usarlo como          */
    IFS0bits.T3IF = 0;                  /* temporizador de 32 bits.           */
}

void __attribute__((interrupt(no_auto_psv))) _CNInterrupt(void)/* Función para*/
{                                       /* el manejo de la interrupción por   */
    //senales.tecla ^= senales.tecla;     /* cambio de estado en los terminales */
                                        /* habilitados para este tipo de      */
                                        /* interrupción. Cada vez que entra   */
    IFS1bits.CNIF = 0;                  /* conmuta la bandera de tecla        */
                                        /* presionada. La intención de esto es*/
                                        /* chequear si */
}

el archivo "interrup.h" es como sigue:

Código: [Seleccionar]
#ifndef INTERRUP_H
#define INTERRUP_H

#include <xc.h>
#include "globales.h"

/*            Definición de constantes a usar en las interrupciones.          */

void Inicia_Interr(void);           /* Prototipo de función para configurar e
                                     * iniciar las fuentes de interrupción.   */

/* Prototipos de función para manejar las fuentes de interrupción */

void __attribute__((interrupt(no_auto_psv))) _T1Interrupt(void);/* Prototipo de
                                             * función para manejar la
                                             * interrupción del timer 1.      */

void __attribute__((interrupt(no_auto_psv))) _T2Interrupt(void);/* Prototipo de
                                             * función para manejar la
                                             * interrupción del timer 2.      */

void __attribute__((interrupt(no_auto_psv))) _CNInterrupt(void);/* Prototipo de
                                             * función para manejar la
                                             * interrupción por notificación
                                             * de cambio en los pines
                                             * seleccionados.                 */
#endif /* INTERRUP_H */


sin embargo cuando intento inicializar el miembro de la unión estructura que me interesa de la siguiente manera: "senales.tecla = 0;" da el siguiente error:

Código: [Seleccionar]
interrup.c:6:8: error: expected '=', ',', ';', 'asm' or '__attribute__' before '.' token

y ese error se presenta justo en la línea que tiene la inicialización del miembro "senales.tecla", es por eso que tengo esa línea comentada aunque ya tengo declarada la variable compuesta una línea más arriba.

Por qué me da este error?, estoy aprendiendo y aunque estoy leyendo todo lo que consigo por ahí aún no comprendo qué estoy haciendo mal en este caso.

Desconectado ALFREDOSKY

  • PIC16
  • ***
  • Mensajes: 118
Re:error cuando declaro una variable tipo typedef en un .h
« Respuesta #6 en: 24 de Enero de 2020, 20:05:12 »
vra, creo que te has saltado un nivel  de la estructura final, 'tecla' esta un nivel mas adentro por decirlo de alguna manera, sería

senales.BANDERASBits.tecla = 1; si no me equivoco,

a BANDERASBits seria bueno le pongas un nombre, digamos bitsBandera para que accedas

senales.bitsBandera.tecla = 1;

otra manera de hacerlo para tener mas claridad es, prueba cambiando la definicion de tus estructuras de la siguiente manera:

en tu archivo globales.h

typedef struct _banderasbits{
    unsigned int restantes;
    unsigned int tecla;
}BANDERASBits;

typedef struct _senales{
    unsigned int banderas;
    BANDERASBits algunNombre;
}SENALES;

en tu .c

SENALES senales;

senales.banderas = 1;
senales.algunNombre.restantes = 0;
senales.algunNombre.tecla= 1;

espero esté en lo correcto y te pueda servir, saludos.

Desconectado vra

  • PIC10
  • *
  • Mensajes: 27
Re:error cuando declaro una variable tipo typedef en un .h
« Respuesta #7 en: 27 de Enero de 2020, 18:51:12 »
vra, creo que te has saltado un nivel  de la estructura final, 'tecla' esta un nivel mas adentro por decirlo de alguna manera, sería

senales.BANDERASBits.tecla = 1; si no me equivoco,

a BANDERASBits seria bueno le pongas un nombre, digamos bitsBandera para que accedas

senales.bitsBandera.tecla = 1;

otra manera de hacerlo para tener mas claridad es, prueba cambiando la definicion de tus estructuras de la siguiente manera:

en tu archivo globales.h

typedef struct _banderasbits{
    unsigned int restantes;
    unsigned int tecla;
}BANDERASBits;

typedef struct _senales{
    unsigned int banderas;
    BANDERASBits algunNombre;
}SENALES;

en tu .c

SENALES senales;

senales.banderas = 1;
senales.algunNombre.restantes = 0;
senales.algunNombre.tecla= 1;

espero esté en lo correcto y te pueda servir, saludos.

Gracias @ALFREDOSKY, la verdad le había quitado el nombre a la estructura para evitar llamar a los miembros de la union con nombres tan largos pero lo probaré y aviso


 

anything