Autor Tema: variable de usuario en XC8  (Leído 5656 veces)

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

Desconectado mak_paint

  • PIC12
  • **
  • Mensajes: 62
variable de usuario en XC8
« en: 24 de Noviembre de 2018, 12:17:39 »
saludos, en esta ocasión acudo al foro para realizar una pregunta, es lo siguiente: digamos que deseo crear una variable de tipo 8 bits sin signo (uint8_t ), y la llamó "FLAGS" mi deseo es q en partes del programa poder leer o escribir  de forma individual cada bit de esta variable, en el compilador MIKROC lo haría: FLAG.f0=1; y si deseo tomar un decisión podría ser: if (FLAG.f0==01){...} etc... pero en XC8 no se ni como declararla ni como usarla en BIT separados, cabe decir q necesito que estos "flags"  se encuentren en la misma variable pues hay una parte del codigo que uso una funcion SWITCH CASE y tomo decisiones dependiendo del contenido de esta variable... bueno estodo gracias de ante mano..

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:variable de usuario en XC8
« Respuesta #1 en: 24 de Noviembre de 2018, 13:50:07 »
Como vos los planteas, esta es la solucion que se me ocurre
Podes usar una union de un uint8_t y una structura de bitfields... algo asi:

Código: C
  1. union myuint8_t {
  2.     struct {
  3.         uint8_t F0: 1;
  4.         uint8_t F1: 1;
  5.         uint8_t F2: 1;
  6.         uint8_t F3: 1;
  7.         uint8_t F4: 1;
  8.         uint8_t F5: 1;
  9.         uint8_t F6: 1;
  10.         uint8_t F7: 1;
  11.     };
  12.     uint8_t valor;
  13. };

entonces lo inicializas

union myuint8_t FLAGS;

Código: C
  1. FLAGS.valor = 0x86;

Y acceder luego o cambiar los bits con:

Código: C
  1. FLAGS.F0 = 1;

Lo que si no tenes que confiarte que F0 va a ser el bit 0 siempre. Ya que el orden de los bitfields es dependiente del compilador.

--------------------

Por otro lado al querer acceder a un bit generalmente se usan las AND y OR

Código: C
  1. if ( FLAGS & ( 1 << x ) )
Donde x es el numero de bit que te interesa.
Si queres poner a 1 el bit 3 por ejemplo usas:

Código: C
  1. FLAGS | ( 1 << 3 )
Si queres poner a 0 el bit 7 por ejemplo usas:

Código: C
  1. FLAGS & ~( 1 << 7 )

MikroC te da esa facilidad que contas, pero la mayoria utiliza este que nombre al ultimo.

Desconectado mak_paint

  • PIC12
  • **
  • Mensajes: 62
Re:variable de usuario en XC8
« Respuesta #2 en: 24 de Noviembre de 2018, 14:20:57 »
muchas gracias por tu respuesta, definitivamente si en mikroc es mas fácil pero el compilador mikroc no se si le pasa a otros me a provocado muchos errores aveces hago una parte nueva del código lo compilo lo grabo al pic y el pic enloquece se cuelga me bugs etc, luego sin modifica ese trozo de código( pues me canso de revisarlo y se q esta bien) sigo unas cuantas lineas mas y compilo grabó y se van todos los problemas, llegue a pense q algun sector de la memoria del pic se habia dañado pero probe con varios y pasaba lo mismo...

Desconectado mak_paint

  • PIC12
  • **
  • Mensajes: 62
Re:variable de usuario en XC8
« Respuesta #3 en: 24 de Noviembre de 2018, 14:32:01 »
no consigo que funcione..
« Última modificación: 24 de Noviembre de 2018, 16:53:29 por mak_paint »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:variable de usuario en XC8
« Respuesta #4 en: 24 de Noviembre de 2018, 17:12:44 »
Pone el codigo que estas tratando de usar... Me refiero a un ejemplo mínimo donde lo uses.

Desconectado mak_paint

  • PIC12
  • **
  • Mensajes: 62
Re:variable de usuario en XC8
« Respuesta #5 en: 24 de Noviembre de 2018, 18:48:55 »
ok seria algo asi...
///////////////////////////////////////
void main() {
  do{
    if (RA0==0) {
      FLAG.F0=1;
      ADC1();      //aca tona una muetra en un canal analogo 0
      RESUL1= ADRESL
    }

    else if (RA1==0){
      FLAG.F1=1;
      ADC2();     //aca tona una muetra en un canal analogo 1
      RESUL2= ADRESL
    }

    else if (RA2==0){
      FLAG.F2=1;
      ADC3();    //aca tona una muetra en un canal analogo2
      RESUL3= ADRESL
    }
   
    if (PIR2bits.TMR3IF==1){
      TIME=0;
    }

  }while (TIME==1);

  DECIDE();
}


/////////////////////////////
void DECIDE(){
  swich(FLAG){
       
       case 1: FORMAT(RESUL1); PRINT(TOTAL); LED1=1;FLAG=0;break;

       case 2: FORMAT(RESUL2); PRINT(TOTAL); LED=0;FLAG=0; break;

       case 4: FORMAT(RESUL3); PRINT(TOTAL); LED2=1;FLAG=0;break;
     
       case 3: LED1=1;LED2=1;FLAG=0; berak;
   
       case 6:....ETC..

       case 7:...ETC...

       defaul : IMPEDANCIA();FLAG=0; break;

  }
}

en realidad el código no es asi hice un pequeño concepto para que se entienda lo que necesito es poder manipular los bits individualmente de FLAG pues en la función DECIDE hago uso del "swiche case" para decidir otras cosas.













« Última modificación: 24 de Noviembre de 2018, 19:24:42 por mak_paint »

Desconectado mak_paint

  • PIC12
  • **
  • Mensajes: 62
Re:variable de usuario en XC8
« Respuesta #6 en: 24 de Noviembre de 2018, 19:12:55 »
lo escribi tal cual como me lo pusiste al principio la estructura de bitfields y el compilador me arroja estos errores:

proyecto.c:86:1: error: unknown type name 'FLAGS'
FLAGS.valor;
^
proyecto.c:86:6: error: expected identifier or '('
FLAGS.valor;
     ^
proyecto.c:607:11: error: use of undeclared identifier 'FLAGS'
          FLAGS.F0=1;

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:variable de usuario en XC8
« Respuesta #7 en: 24 de Noviembre de 2018, 19:55:32 »
Tu programa no tiene un loop infinito... asi como me lo mostras.. No comprendo el porque usas usar un switch..case... Pero en fin.. hice este codigo y funciona:


Código: C
  1. union mytipo_t {
  2.     uint8_t val;
  3.     struct {
  4.         uint8_t F0:1;
  5.         uint8_t F1:1;
  6.         uint8_t F2:1;
  7.         uint8_t F3:1;
  8.         uint8_t F4:1;
  9.         uint8_t F5:1;
  10.         uint8_t F6:1;
  11.         uint8_t F7:1;
  12.     };
  13. };
  14.  
  15. union mytipo_t flags;
  16.  
  17. void main(void){
  18.  
  19.     flags.val = 0;
  20.     flags.F0 = 1; // Aca lo hace valer 0x01
  21.     flags.F2 = 1; // Aca lo hace valer 0x05
  22.          
  23.     while(1){
  24.  
  25.     }
  26.  
  27. }

Desconectado mak_paint

  • PIC12
  • **
  • Mensajes: 62
Re:variable de usuario en XC8
« Respuesta #8 en: 24 de Noviembre de 2018, 22:05:57 »
sigue sin funcionar......
proyecto.c:498:3: error: statement requires expression of integer type ('union mytipo_t' invalid)
  switch(FLAGS){
« Última modificación: 24 de Noviembre de 2018, 22:26:20 por mak_paint »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:variable de usuario en XC8
« Respuesta #9 en: 25 de Noviembre de 2018, 09:33:23 »
Que raro... yo lo puedo compilar sin ningun problema al codigo que te pase, el problema es en TU codigo, ya que lo veo declarado como FLAGS en mayusculas.

Recorda que para acceder a los 8 bits necesitas usar flags.val, por ejemplo aca:


  swich(FLAG){

deberia ser:

  swich(FLAGS.val){

Nuevamente, si queres que sea FLAGS solo ahi, luego podes acceder bit a bit como la segunda solucion que te mostre.

Desconectado mak_paint

  • PIC12
  • **
  • Mensajes: 62
Re:variable de usuario en XC8
« Respuesta #10 en: 25 de Noviembre de 2018, 10:47:38 »
Que raro... yo lo puedo compilar sin ningun problema al codigo que te pase, el problema es en TU codigo, ya que lo veo declarado como FLAGS en mayusculas.

Recorda que para acceder a los 8 bits necesitas usar flags.val, por ejemplo aca:


  swich(FLAG){

deberia ser:

  swich(FLAGS.val){

Nuevamente, si queres que sea FLAGS solo ahi, luego podes acceder bit a bit como la segunda solucion que te mostre.



Ok voy a probar, se me ocurrió también como solo yo escribo los bits  en 4 lineas y en swich leo la variable entera, que tal si en donde escribo los bit lo hago en asm,... otra cosa antes preguntaste por q uso el switch... case... bueno de esta variable FLAG van a cambiar 4 bits  durante el programa pueden estar en 1 varios de ellos en distintas combinaciones por lo tanto puedo tener la variable con valores desde 0 a 15 en decimal... entonces en la función DECIDE debo ejecutar  instrucciones dependiendo de valor de FLAG la solución mas elegante que se me ocurre es el uso de switch, imagina que use 15"if" y "else if" seria horrible ademas de la confusión ya que en ciertos casos se ejecuta la misma instrucción con dos valores distintos en  FLAG osea asi:
//////codigo real//////
....case 5:
    case 13:
              if (TOG){
               TOG=~TOG;
               H_LED=1;MEDIA(1);FORMAT(TOTAL);PRINT(TOTAL);
               break;
             }
             else {
               TOG=~TOG;
               IMPED();FLAG_CON=0;T3CONbits.TMR3ON=1;
               break;
             }
..... 

como ves para case 5 y 13 , voy a las mismas instrucciones, eso pasa  en unos cuantos casos mas, y en otros no.. ahora volviendo a los bits de FLAG solo manipulo estos bits en 4 líneas durante todo el codigo del resto leo la variable entra, asi q te parece mi idea de usar asm en estos pequeños casos y ahorrarnos el "union".... lo q no se como introducir una linea de asm en xc8 en buscado en la red y al parecer es problemático, por que xc8 es tan poco amigable...   


« Última modificación: 25 de Noviembre de 2018, 10:51:17 por mak_paint »

Desconectado mak_paint

  • PIC12
  • **
  • Mensajes: 62
Re:variable de usuario en XC8
« Respuesta #11 en: 25 de Noviembre de 2018, 13:21:12 »
y los problemas no acaban ahora que genere la funcion de interrupcion tambien me saltan errores:


#define FLG_VF  INTCONbits.INT0IF   
#define FLG_TC  INTCON3bits.INT1IF 

//////////////////////////////
void interrupt boton(){
__delay_ms(300);
  if (FLG_VF==1){
    V_Hz = ~V_Hz;
  }
  else if (FLG_TC==1){
   SELC_TC = ~SELC_TC;
  }
  FLG_VF=0;
  FLG_TC=0;
}
//////////////////////////
y los errores que saltan son:
proyecto.c:74:6: error: variable has incomplete type 'void'
void interrupt boton(){
     ^
proyecto.c:74:15: error: expected ';' after top level declarator
void interrupt boton(){
              ^
              ;
2 errors generated.
(908) exit status = 1
nbproject/Makefile-default.mk:106: recipe for target 'build/default/production/proyecto.p1' failed


////////////////////////

uso un 18F1320 en la configuración deshabilite las prioridades en la interrupción....

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:variable de usuario en XC8
« Respuesta #12 en: 25 de Noviembre de 2018, 15:04:54 »
Discúlpame pero sigo viendo cosas que NO deberías hacer...

Citar
void interrupt boton(){
__delay_ms(300);

Un DELAY en una interrupción, es algo que JAMAS deberías hacer

El/Los siguiente error es de algo que no es esa parte del código.. al menos yo no veo error ahí. O algo mal escrito.

Citar
entonces en la función DECIDE debo ejecutar  instrucciones dependiendo de valor de FLAG la solución mas elegante que se me ocurre es el uso de switch, imagina que use 15"if" y "else if" seria horrible ademas de la confusión ya que en ciertos casos se ejecuta la misma instrucción con dos valores distintos en  FLAG osea asi:

No conozco que estas haciendo ni el funcionamiento del programa. Tal ves sea cierto que no hay otra forma. No lo puedo saber a ciencia cierta, pero lo que me habias presentado:

Código: C
  1. case 1: FORMAT(RESUL1); PRINT(TOTAL); LED1=1;FLAG=0;break;
  2.  
  3.        case 2: FORMAT(RESUL2); PRINT(TOTAL); LED=0;FLAG=0; break;
  4.  
  5.        case 4: FORMAT(RESUL3); PRINT(TOTAL); LED2=1;FLAG=0;break;
  6.      
  7.        case 3: LED1=1;LED2=1;FLAG=0; berak;

Era como que si se podia hacer 1 if por cada bit de flag.

Desconectado mak_paint

  • PIC12
  • **
  • Mensajes: 62
Re:variable de usuario en XC8
« Respuesta #13 en: 25 de Noviembre de 2018, 15:22:30 »
gracias por tanta ayuda... bueno el delay de la interrupción la quite y el error sigue y es en la función de interrupción pues si la quito del código pues compila bien..
///////////////////////////
void interrupt boton(){
  if (FLG_VF==1){
    V_Hz = ~V_Hz;
  }
  else if (FLG_TC==1){
   SELC_TC = ~SELC_TC;
  }
  FLG_VF=0;
  FLG_TC=0;
//
}
///////////////////////////////

y el error es como se lee en el mensaje que emite MPLAB en la interrupción, pero como tu dices alli no hay error:

///////////////////////////////////
proyecto.c:117:6: error: variable has incomplete type 'void'
void interrupt boton(){
     ^
proyecto.c:117:15: error: expected ';' after top level declarator
void interrupt boton(){
              ^
              ;
2 errors generated.



 

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:variable de usuario en XC8
« Respuesta #14 en: 25 de Noviembre de 2018, 16:53:29 »
Para que veas que la parte del codigo NO esta mal... y que puede ser algo que tenes definido mal, por ejemplo una variable, etc... Compile el siguiente codigo:

Código: C
  1. #include <xc.h>
  2. #include <stdint.h>
  3. #define _XTAL_FREQ 4000000
  4.  
  5.  
  6. union mytipo_t {
  7.     uint8_t val;
  8.     struct {
  9.         uint8_t F0:1;
  10.         uint8_t F1:1;
  11.         uint8_t F2:1;
  12.         uint8_t F3:1;
  13.         uint8_t F4:1;
  14.         uint8_t F5:1;
  15.         uint8_t F6:1;
  16.         uint8_t F7:1;
  17.     };
  18. };
  19.  
  20. union mytipo_t flags;
  21. uint8_t V_Hz,SELC_TC;
  22.  
  23. void interrupt boton(){
  24.   if (INTCONbits.T0IF==1){
  25.     V_Hz = ~V_Hz;
  26.   }
  27.   else if (INTCONbits.TMR0IF==1){
  28.    SELC_TC = ~SELC_TC;
  29.   }
  30.   INTCONbits.T0IF=0;
  31.   INTCONbits.TMR0IF=0;
  32. //
  33. }
  34.  
  35. void main(void){
  36.  
  37.     flags.val = 0;
  38.     flags.F0 = 1;
  39.     flags.F2 = 1;
  40.          
  41.     while(1){
  42.  
  43.     }
  44.  
  45. }

Cambie unicamente los FLG_VF y TC por cualquier flag, la primera que encontre. tambien defini a V_Hz y SELC_TC como enteros, ya que no se que son.
Y el resultado fue el siguiente:

Código: [Seleccionar]
CLEAN SUCCESSFUL (total time: 62ms)
make -f nbproject/Makefile-default.mk SUBPROJECTS= .build-conf
make[1]: Entering directory 'F:/CCS/MPLABx/XC8.X'
make  -f nbproject/Makefile-default.mk dist/default/production/XC8.X.production.hex
make[2]: Entering directory 'F:/CCS/MPLABx/XC8.X'
"C:\Program Files (x86)\Microchip\xc8\v1.43\bin\xc8.exe" --pass1  --chip=18F1320 -Q -G  --double=24 --float=24 --emi=wordwrite --opt=+asm,+asmfile,-speed,+space,-debug,-local --addrqual=ignore --mode=free -P -N255 -I"../testLibrary.X" --warn=-3 --asmlist -DXPRJ_default=default  --summary=default,-psect,-class,+mem,-hex,-file --output=default,-inhx032 --runtime=default,+clear,+init,-keep,-no_startup,-download,+config,+clib,-plib   --output=-mcof,+elf:multilocs --stack=compiled:auto:auto:auto "--errformat=%f:%l: error: (%n) %s" "--warnformat=%f:%l: warning: (%n) %s" "--msgformat=%f:%l: advisory: (%n) %s"    -obuild/default/production/main.p1  main.c
main.c:32: warning: (373) implicit signed to unsigned conversion
main.c:35: warning: (373) implicit signed to unsigned conversion
"C:\Program Files (x86)\Microchip\xc8\v1.43\bin\xc8.exe"  --chip=18F1320 -G -mdist/default/production/XC8.X.production.map  --double=24 --float=24 --emi=wordwrite --opt=+asm,+asmfile,-speed,+space,-debug,-local --addrqual=ignore --mode=free -P -N255 -I"../testLibrary.X" --warn=-3 --asmlist -DXPRJ_default=default  --summary=default,-psect,-class,+mem,-hex,-file --output=default,-inhx032 --runtime=default,+clear,+init,-keep,-no_startup,-download,+config,+clib,-plib --output=-mcof,+elf:multilocs --stack=compiled:auto:auto:auto "--errformat=%f:%l: error: (%n) %s" "--warnformat=%f:%l: warning: (%n) %s" "--msgformat=%f:%l: advisory: (%n) %s"      --memorysummary dist/default/production/memoryfile.xml -odist/default/production/XC8.X.production.elf  build/default/production/main.p1     
Microchip MPLAB XC8 C Compiler (Free Mode) V1.43
Build date: Jul 24 2017
Part Support Version: 1.43
Copyright (C) 2017 Microchip Technology Inc.
License type: Node Configuration

:: advisory: (1233) Employing 18F1320 errata work-arounds:
:: advisory: (1234)  * GOTO instruction at reset vector must be preceded by NOP
:: advisory: (1234)  * DAW instruction may improperly clear CARRY bit
:: warning: (1273) Omniscient Code Generation not available in Free mode
:: warning: (1311) missing configuration setting for config word 0x300001; using default
:: warning: (1311) missing configuration setting for config word 0x300002; using default
:: warning: (1311) missing configuration setting for config word 0x300003; using default
:: warning: (1311) missing configuration setting for config word 0x300005; using default
:: warning: (1311) missing configuration setting for config word 0x300006; using default
:: warning: (1311) missing configuration setting for config word 0x300008; using default
:: warning: (1311) missing configuration setting for config word 0x300009; using default
:: warning: (1311) missing configuration setting for config word 0x30000A; using default
:: warning: (1311) missing configuration setting for config word 0x30000B; using default
:: warning: (1311) missing configuration setting for config word 0x30000C; using default
:: warning: (1311) missing configuration setting for config word 0x30000D; using default

Memory Summary:
    Program space        used    CAh (   202) of  2000h bytes   (  2.5%)
    Data space           used    16h (    22) of   100h bytes   (  8.6%)
    Configuration bits   used     7h (     7) of     7h words   (100.0%)
    EEPROM space         used     0h (     0) of   100h bytes   (  0.0%)
    ID Location space    used     8h (     8) of     8h bytes   (100.0%)
    Data stack space     used     0h (     0) of    80h bytes   (  0.0%)


You have compiled in FREE mode.
Using Omniscient Code Generation that is available in PRO mode,
you could have produced up to 60% smaller and 400% faster code.
See http://www.microchip.com/MPLABXCcompilers for more information.

make[2]: Leaving directory 'F:/CCS/MPLABx/XC8.X'
make[1]: Leaving directory 'F:/CCS/MPLABx/XC8.X'

BUILD SUCCESSFUL (total time: 1s)
Loading code from F:/CCS/MPLABx/XC8.X/dist/default/production/XC8.X.production.hex...
Loading completed

El cual no me dio ningun error. Y usando el PIC18F1320.