Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

26/05/2009 #1


Problemas "implicit conversion of pointer to int"
Hola a todos, soy nuevo en el foro y antes de todo os envio un saludo.

Estoy realizando un proyecto en mikroC en un PIC 18F4550. Este proyecto es para realizar fotografias de alta velocidad mediante el disparo de un flash y obturador de la cámara. Necesito implmentar un menu en un LCD para poder seleccionar las ditintas opciones. He encontrado un ejemplo de implementación de mení, in embargo me aparecen warnings de "implicit conversion of pointer to int" y finalmente no me compila el programa.

Hace 15 años cuando terminé la universidad dominaba la programación en C si embargo ahora ya lo tengo muy oxidado Creo que hay un problema en el código a la hora de iniciallizar las estrcuturas con punteros nulos, pero no se que hacer para solucionarlo.

Adjunto el código y mas abajo las lineas en donde me aparecen los warnings. A ver si alguien me pudiera echar una mano porque estoy completamente parado.

Codigo completo:

Código:
struct menuStruct;
void mainScreen();
void item2Handle();

//Font for the arrows
const unsigned short Arrows5x6[] = {
        0x30, 0x3C, 0x3F, 0x3C, 0x30,
        0x03, 0x0F, 0x3F, 0x0F, 0x03
        };

//Menu item structure
typedef struct menuItem
               {
                char *itemName;                 //Name of this item
                void (*handler)(void);          //Pointer to function, null if not used
                struct menuStruct *subMenu;     //Pointer to sub menu, null if not used
               } menuItem;

//Menu structure
typedef struct menuStruct
               {
                char *menuName;                 //Name of menu
                unsigned short numberItems;     //Number of menu items
                menuItem *items;                //Pointer to array of items
               } menuStruct;

//Demo menu. Menus are declared in reverse order,
menuItem subItem1ItemList[] = {{"Sub Sub Item 1", 0, 0}, {"Sub Sub Item 2", 0, 0}};

menuStruct subItem1Menu = {"Sub Item 1 Sub Menu", 2, &subItem1ItemList};

menuItem item1ItemList[] = {{"Sub sub menu 1", 0, &subItem1Menu}, {"Sub Item 2", 0, 0}};

menuStruct item1Menu = {"Item 1 Sub Menu", 2, &item1ItemList};

menuItem mainMenuItemList[] = {{"Sub Menu 1", 0, &item1Menu},{"Demo function", &item2Handle, 0},{"Sub sub menu 1", 0, &subItem1Menu},{"Item 4", 0, 0},{"Item 5", 0, 0},
                               {"Item 6", 0, 0},{"Item 7", 0, 0},{"Item 8", 0, 0},{"Item 9", 0, 0},{"Item 10", 0, 0}};

menuStruct mainMenu = {"Main Menu", 10, &mainMenuItemList};

//Demo item handle function
void item2Handle()
{
 GLCD_Fill(0x00);
 GLCD_Write_Text("Press RA4", 0, 0, 1);

 while(!Button(&PORTA, 4, 5, 1))
 {
 }
 return;
}

//Draws the actual menu
void drawMenu(menuStruct *menuToShow, short selectedIndex)
{
 unsigned short i;

 GLCD_Fill(0x00);
 GLCD_Set_Font(FontSystem5x8,5,8,32);
 GLCD_Write_Text(menuToShow->menuName, 0, 0, 1);

 for(i=0;i < (menuToShow->numberItems > 6 ? 6 : menuToShow->numberItems) ;i++)
 {
  if (i > 5 + (selectedIndex > 5 ? selectedIndex - 5 : 0))
  {
   break;
  }
  else if (selectedIndex < 6)
  {
   GLCD_Write_Text(menuToShow->items[i]->itemName, 5, i+1, (selectedIndex == i) ? 0 : 1);
  }
  else
  {
   GLCD_Write_Text(menuToShow->items[i+(selectedIndex-5)]->itemName, 5, i+1, (selectedIndex == i+(selectedIndex-5)) ? 0 : 1);
  }
 }

 Glcd_H_Line(0,127,7,1);
 Glcd_H_Line(0,127,55,1);
 GLCD_Set_Font(Arrows5x6,5,6,30);
 GLCD_Write_Char(30, 5, 7, 1);
 GLCD_Write_Char(31, 25, 7, 1);
 GLCD_Set_Font(FontSystem5x8,5,8,32);
 GLCD_Write_Text("Select", 45, 7, 1);
 GLCD_Write_Text("Back", 101, 7, 1);
 return;
}

//Main menu function
void openMenu(menuStruct *menuToShow)
{
 short selectedIndex = 0;               //Current selected item

 delay_ms(50);
 drawMenu(menuToShow, selectedIndex);

   do {
     if (Button(&PORTA, 0, 5, 1))
     {
        selectedIndex--;
        if (selectedIndex < 0)
        {
           selectedIndex = menuToShow->numberItems - 1;
        }
        drawMenu(menuToShow, selectedIndex);
     }
     else if (Button(&PORTA, 1, 5, 1))
     {
        selectedIndex++;
        if (selectedIndex > (menuToShow->numberItems) - 1)
        {
           selectedIndex = 0;
        }
        drawMenu(menuToShow, selectedIndex);
     }
     else if (Button(&PORTA, 2, 5, 1))
     {
         if (menuToShow->items[selectedIndex]->handler != 0)
         {
          menuToShow->items[selectedIndex]->handler();
         }
         else if (menuToShow->items[selectedIndex]->subMenu != 0)
         {
          openMenu(menuToShow->items[selectedIndex]->subMenu);
         }
         drawMenu(menuToShow, selectedIndex);
     }
     else if (Button(&PORTA, 3, 5, 1))
     {
          return;
     }

     delay_ms(30);
  } while (1);

 return;
}

void mainScreen()
{
 GLCD_Fill(0x00);
 GLCD_Set_Font(FontSystem5x8,5,8,32);
 GLCD_Write_Text("Menu", 0, 7, 1);
 return;
}

void main()
{
  ADPCFG = 0xFFFF;

  Glcd_Init_LV_24_33();
  mainScreen();

  //--- main loop
  do
  {
    if (Button(&PORTA, 0, 1, 1))
    {
     openMenu(&mainMenu);
     mainScreen();
    }
    Delay_ms(50);
  } while (1);
}//~!
Lineas donde aparece el error:

Código:
menuItem subItem1ItemList[] = {{"Sub Sub Item 1", 0, 0}, {"Sub Sub Item 2", 0, 0}};
menuItem item1ItemList[] = {{"Sub sub menu 1", 0, &subItem1Menu}, {"Sub Item 2", 0, 0}};
menuItem mainMenuItemList[] = {{"Sub Menu 1", 0, &item1Menu},{"Demo function", &item2Handle, 0},{"Sub sub menu 1", 0, &subItem1Menu},{"Item 4", 0, 0},{"Item 5", 0, 0},{"Item 6", 0, 0},{"Item 7", 0, 0},{"Item 8", 0, 0},{"Item 9", 0, 0},{"Item 10", 0, 0}};
Gracias anticipadas,

Jose
26/05/2009 #2

Avatar de Ardogan

No uso el mikroC, pero el tipo de error sugiere que tenés que hacer una conversión de los números 0 a un puntero.
Con el C18 se hace si mal no recuerdo con (void*)0.
Asi que fijate si cambiando los 0 por (void*)0 se van esos warnings. Ojo, solo en los parámetros que sean punteros.

Saludos
27/05/2009 #3


Hola Ardogan, creo que es algo que probé pero que no me funcionó, de todas formas hoy cuando llegue a casa volveré a realizar la prueba. Creo haber leido también que igual es un problema de inicialización de variables, cuando hay asignaciones en donde entran punteros a funciones, en tiempo de compilación y que se debería hacer la inicialización dentro de la función main, sin embargo lo probe ayer y no me funcionó dicha opción. Hoy probaré lo que tu me comentas.

Muchas gracias,

Jose

Ardogan dijo:
No uso el mikroC, pero el tipo de error sugiere que tenés que hacer una conversión de los números 0 a un puntero.
Con el C18 se hace si mal no recuerdo con (void*)0.
Asi que fijate si cambiando los 0 por (void*)0 se van esos warnings. Ojo, solo en los parámetros que sean punteros.

Saludos
27/05/2009 #4

Avatar de Dr. Zoidberg

Si el compilador es ANSI, en vez de (void *)0 deberías poder usar NULL, que es el valor específico para un puntero que no apunta a nada.

Saludos!
27/05/2009 #5


Hola, pues ninguna de las opciones funciona, ni la opción de (void*)0 ni la opción de NULL, de hecho el NULL parece no estar definido en este compilador...

Asi que sigo desconcertado con este problema y no consigo ningun tipo de solución, he puesto un post en el forum de mikroelectronika, en la sección de mickroC y de momento ninguna respuesta....

ezavalla dijo:
Si el compilador es ANSI, en vez de (void *)0 deberías poder usar NULL, que es el valor específico para un puntero que no apunta a nada.

Saludos!
27/05/2009 #6

Avatar de Ardogan

A ver con esto:

declará una función que no haga nada:

void nada(void){

}

y cambiar los 0's por &nada.
No sé si eso te afectara en el resto del programa (si hay algún if para chequear si el puntero es nulo, pero en ese caso en vez de preguntar == 0 se puede preguntar ==&nada).
27/05/2009 #7


Hola Ardogan, uhmmm, puede ser una buena solución la que me indicas, la pruebo nada más llegar a casa y te digo algo.

Un millón de gracias,

Jose

Ardogan dijo:
A ver con esto:

declará una función que no haga nada:

void nada(void){

}

y cambiar los 0's por &nada.
No sé si eso te afectara en el resto del programa (si hay algún if para chequear si el puntero es nulo, pero en ese caso en vez de preguntar == 0 se puede preguntar ==&nada).
27/05/2009 #8


Hola, he podido solucionar el problema con esa definición de funcion vacia, pero ahora me dan errores de "Recursion or cross-calling of", así que entiendo que estas rutinas de implementación de menus no están bien implemetadas para mikroC, así que voy a tener que currarme yo desde 0 la implementación de una rutina de menú, el problema es que al tener oxidado el C me va a costar horrores.

Gracias a todos por la ayuda.
27/05/2009 #9

Avatar de Ardogan

Sé que lo de función vacía no es lo ideal, pero es para salir del paso un ratito y poder llegar a algo que funcione para luego pulirlo de acuerdo al tiempo/esfuerzo que uno quiera/pueda invertir.

Eso de "Recursion or cross-calling of", tal vez en el compilador de C anterior se permiten más llamadas recursivas que en mikroC.... a ver...

En el manual habla de que hay que usar un pragma al declarar la función, si es que esta va a ser llamada indirectamente (es decir, usando punteros):

http://www.mikroe.com/pdf/mikroc/mikroc_manual.pdf
página 39

Vamos josemabcn, no se me eche para atrás; seguramente habrá que corregir muchas cosas pero siempre va a ser mejor que implementarlo de 0.

A no ser que el tamaño del código haga que no entre en el pic, o se utilicen más variables (ram) de las que puede manejar un pic, o que la velocidad de ejecución del pic se quede corta. Ahí sí puede ser más fácil empezar de 0 que reestructurar, pero si no es el caso y solo hay que ver algunos detalles de compilación no habría que desecharlo tan rápido.

Bueno, suerte con el camino que elijas, no olvides de comentar como te fue y como resolviste el problema.

Saludos
02/06/2009 #10


Al final me he decidido por implementar yo mismo el menú, ya que se trata de un menú muy sencillo con pocas funciones, por tanto ha resultado muy fácil.

El problema que me encuentro ahora es el siguiente... Tengo el menú implmentado y cuando selecciono la opción tengo que llamar a la función que implementa dicha opción, en dicha función presento en el LCD un valor de retardo en milisegundo que quiero que sea editable, es decir, mediante pulsadores quiero poder subir y bajar dicho valor, por tanto la rutina está chequeando constantemente la pulsación de dichas teclas. El problema es que quiero implementar una interrupción de manera que cuando ésta se active salte a la función de atención a la interrupción, ha de ser una función en tiempo real, en ella quiero abrir el obturador de la cámara y de acuerdo con el retardo que se encuentre activo de la función principal anterior posteriormente activar el flash, luego cerrar el obturador. Me interesa que al activarse la interrupción se muestre una indicación en el LCD durante un instante, pero no puedo utilizar una función de escritura en el LCD dentro de la función de atención a la interrupción, ya que el compilador da error de reentrada (al utilizarla tambien dentro de main()). Si, me direis que esas cosas no se deben hacer en una función de atención a interrupción, que debería activar un flag y luego chequear este en la función principal, pero claro, en dicha función estoy chequeando los pulsadores, por lo que puede pasar que cuando chequee el flag activado por la func. de atención a la interrupción el retardo sea demasiado grande y ya no sea en tiempo real....

Puf, que complicado esto de los PICS..., ¿alguna idea?.


Jose

Ardogan dijo:
Sé que lo de función vacía no es lo ideal, pero es para salir del paso un ratito y poder llegar a algo que funcione para luego pulirlo de acuerdo al tiempo/esfuerzo que uno quiera/pueda invertir.

Bueno, suerte con el camino que elijas, no olvides de comentar como te fue y como resolviste el problema.

Saludos
03/06/2009 #11

Avatar de Ardogan

A ver... vamos a poner un poco más en claro las tareas a realizar:

Rutina de interrupción:

1) Abrir obturador
2) Esperar retardo (configurable por el usuario)
3) Activar flash
4) Cerrar obturador

Lazo de programa:

1) Verificar pulsación tecla
2) Si tecla = arriba -> incrementar retardo
si tecla = abajo -> decrementar retardo
3) Presentar valor de retardo en LCD

Entonces la cuestión es:

pero no puedo utilizar una función de escritura en el LCD dentro de la función de atención a la interrupción, ya que el compilador da error de reentrada (al utilizarla tambien dentro de main()).
Fijate en "Function reentrancy en la página 115 de http://www.mikroe.com/pdf/mikroc/mikroc_manual.pdf (pagina 123 del pdf). Ahí dice que la condición para poder llamarla desde main o desde una rutina de interrupción es que no tenga parámetros ni variables locales.

Si, me direis que esas cosas no se deben hacer en una función de atención a interrupción, que debería activar un flag y luego chequear este en la función principal
De acuerdo con eso....

, pero claro, en dicha función estoy chequeando los pulsadores, por lo que puede pasar que cuando chequee el flag activado por la func. de atención a la interrupción el retardo sea demasiado grande y ya no sea en tiempo real....
Es demasiado grande el retardo para mostrar la indicación en el LCD?. No creo que pase de algunos milisegundos o me equivoco?.
Por ahí el problema es que si mostrás lo del LCD y haces una espera por software se te queda el programa en espera sin chequear las teclas. Digamos, no es solo el retardo en presentar los datos en el LCD sino que tiene que estar la indicación presente un tiempo relativamente grande (3..5 segundos) para que el usuario lo vea.
¿Es ese el problema no?

Bueno, ahi vas a tener que usar temporizadores para implementar el tiempo de presentación en el LCD, pero antes de eso aclarame si interpreté bien tu problema.

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

Otra cuestión, para los moderadores, estos dos últimos mensajes se salen del tema original.
Sería conveniente moverlo a algún post que hable de LCD + teclado. Yo sugiero:

http://www.forosdeelectronica.com/about33177.html

o

http://www.forosdeelectronica.com/about24163.html
Respuesta
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.