Autor Tema: Barrido de displays!  (Leído 4890 veces)

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

Desconectado Enigma

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 609
    • www.toroscoleados.com
Barrido de displays!
« en: 08 de Enero de 2008, 02:47:20 »
Hola chicos, espero se encuentren muy bien... Bueno siguiendo con mi aprendizaje de C en Ccs, he hecho este programa, gracias a la colaboración de algunos foristas, y bueno, lo he revisado una y otra vez, y creo que la lógica está bien, pero sin embargo no funciona!!! y no se porque.. :? Y bueno quisiera saber si ustedes que saben y que me han ayudado tanto me pudieran corregir lo horrores que seguramente tengo ( aunque lo revise tres veces antes de pedirle ayuda a ustedes)... Pero estoy sin respuesta, acudo a ustedes en busca de orientación.... aquí está el programa adjunto!!!

Gracias y disculpen la molestia!!!!

Atte: Enigma... La llanerita de Guayana :g)
« Última modificación: 08 de Enero de 2008, 02:51:39 por Enigma »
No hay nada como cabalgar en la sabana y sentir la brisa con olor a mastranto, bosta y ganado. ¡¡O Fortuna, velut luna, status variabilis, semper crescis, aut decrescis, vita detestabili!! Que viva el coleo, la musica LLanera y la gótica!

Desconectado micro_cadaver

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2102
    • blog microembebidos
Re: Barrido de displays!
« Respuesta #1 en: 08 de Enero de 2008, 04:05:57 »
y que parte es la que falla?  :-)
a cosechar!!!... :P
pic32... ahi voy....
aguante el micro 16f84  !!!!

visita mi pagina: http://www.microembebidos.wordpress.com

Desconectado damago

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 320
Re: Barrido de displays!
« Respuesta #2 en: 08 de Enero de 2008, 11:14:39 »
Hola Enigma,

hay un pequeño error de concepto con las variables. Las variables 'resul' y 'cont' de la funcion 'main()' son locales (es decir, no se puede ver desde fuera de 'main()').
Al igual las variables 'resul' y 'cont' de la funcion 'mostrar()' son locales y solo se puede 'ver' dentro de la misma funcion.

La solucion para ver las variables que modificas en 'main()' dentro de la funcion 'mostrar()' es:
1) declarar 'resul' y 'cont' como variables globales (fuera del main()): para hacer esto simplemente colocalas asi:

#include <18f4550.h>
#fuses INTRC_IO,NOWDT,NOPROTECT,NOCPD,NOLVP,VREGEN,NOPBADEN
#use fast_io (A)
#use fast_io (B)
#use fast_io (C)
#use fast_io (D)
#use delay(clock=4000000)
//#DEFINE   Q1   PIN_A0                   // transistor 1
//#DEFINE   Q2   PIN_A1                   // transistor 2
//#DEFINE   Q3   PIN_A2                   // transistor 3
//#DEFINE   Q4   PIN_A3                   // transistor 4

// VARIABLES GLOBALES
int resul,i,cont; // Aqui son visibles desde cualquier parte del codigo (siempre que este en el mismo archivo)

//Declaracion de funciones
void mostrar(void);

void main(void)
{
//         int resul,i,cont; NO LAS DECLARES AQUI
         i=0;
         cont=1;
         port_b_pullups(TRUE);               // Activo las pullups

O

2) pasar las variables locales de 'main()' a 'mostrar()': para ellos deja todo como esta, pero declara 'mostrar()' de la siguiente manera:


void mostrar(int cont, int resul) // ahora son parametros de entrada a la funcion
                                              // de este modo valen lo que les asignas en main() que es desde donde llamas a mostrar()
{
// No las declares aqui
      //output_low(Q1);
      //output_low(Q2);
      //output_low(Q3);
      //output_low(Q4);

      if(cont==1)
         {


ademas en la funcion main() debes CAMBIAR -> "mostrar(); por mostrar(cont, resul);". Osea los 2 parametros de entrada a la funcion mostrar().

Elige una de las 2 opciones.

Simplemente es eso. En tu programa, aunque se llamen igual, las variables de main y mostrar (resul y cont) son totalmente diferentes. Inicialmente las variables de la funcion mostrar, que no estan inicializadas, valdran 0 (normalmente el compilador genera codigo en ensamblador que se ocupa de inicializar a 0 las variables no inicializadas. Esto es independiente y trasnparente para nosotros). Y con ese valor se quedan para siempre, ya que no se lo modificas. Por eso no hace nada.


Si te interesa, la diferencia fisicamente es:
- la variable global, ocupa una posicion de memoria ram fija de tu micro.
- la variable local ocupa una posicion de memoria que puede cambiar. Las variables locales se almacenan en la zona de la pila. Cada vez que llamas a mostrar con mostrar(cont, resul) se ponen en la pila los valores de estas 2 variables, y cuando sales de mostrar, desaparecen de la pila (no ocupan una posicion fija en la RAM). Es mas elegante esta opcion, ademas de poder controlar errores involuntarios de cambiar los valores de cont y resul desde otras funciones (por error), ya que no serian vistas desde ellas (si no son parametros de entrada). Con lo cual el compilador emitiria un error.

Un saludo. Dani.
« Última modificación: 08 de Enero de 2008, 11:24:24 por damago »

Desconectado damago

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 320
Re: Barrido de displays!
« Respuesta #3 en: 08 de Enero de 2008, 11:49:05 »
Hola Enigma, ahora que me he fijado un poco mas en el codigo, te comento:

- la opcion 1 te funcionara bien (variables globales, y eliminas las declaraciones locales en ambas funciones)
- la opcion 2 tiene una pega:

como te he comentado las variables locales desaparecen cuando se sale de la funcion, y tu quieres mantener el valor de 'cont' que lo modificas en esta funcion.

Soluciones:

2.1) Puedes pasar parametros por valor o por referencia. Pasar parametros por valor, es lo que hemos hecho en la opcion 2 anterior anterior. Simplementes le envias 2 valores como parametros de entrada a la funcion mostrar(). Pero aunque luego los modifiques en la funcion mostrar(), al salir de esta, los cambios no se reflejan en las variables de la funcion que la llama (main()).

La otra manera (paso por referencia), lo que pasas es la direccion de la variables, en lugar de su valor. De este modo, en la funcion mostrar(), no se crean 2 nuevas variables (ni en pila, ni en ningun sitio). Simplemente sabe la direccion donde esta posicionada en memoria, las variables 'cont', y 'resul' de la funcion main(). De este modo, cuando cambies el valor de 'cont' en mostrar(), lo que realmente estas haciendo es cambiar el valor de la misma posicion de memoria donde esta almacenada la variable 'cont' de la funcion main().

La funcion mostrar ahora se declararia del siguiente modo:

void mostrar(int *cont, int resul) // como parametro de entrada tendria las direcciones de cont y resul, no 'sus valores'
{

'cont' es un puntero (no contienen el valor de las variables, si no la direccion de estas)

Tb habria que sustituir donde aparece 'cont' por '(*cont)'.

Es decir:

void mostrar(int *cont, int resul) // como parametro de entrada tendria las direcciones de cont y resul, no 'sus valores'
{
      if( (*cont)==1)
         {
            output_a(0x01);
            //output_high(Q1);
            output_d(resul);
            delay_ms(5);
            (*cont)=2;
         }

      if( (*cont)==2)
         {
etc...

la variable resul, la pasamos por valor (no por referencia), ya que nose modifica dentro de la funcion mostrar(), ni se quiere que se conserve los cambios que se hiciesen en ella dentro de la funcion mostrar(), en caso de que se hicieran.


2.2) declara la variable 'cont' como global, y la 'resul' como local y la pasas como parametro por valor.

void mostrar (int resul)
{
etc..

2.3) En casos como este, en el que parece que la variable 'cont' solo la modificas y la utilizas dentro de la funcion mostrar() (en main no la utilizas para nada), puedes hacer lo siguiente:

void mostrar ()
{
static int cont =1;
etc...

declaras las variable local 'cont' como 'static'. A diferencia de las variables locales, cuando les añades 'static' evitas que su valor se pierda al salir de la funcion. De este modo, la primera vez que entres valdra '1' (el valor al que la hemos inicializado). La segunda vez, el ultimo que tenia antes de salir (osea cont=2). Y asi.

En este caso, sigue siendo una variable local, es decir, su valor no podria verse desde la funcion main(). 'cont' de la funcion main89 y la funcion mostrar() son variables totalmente diferentes, aunque tengan el mismo nombre (son 'locales').


Un saludo. Dani.
« Última modificación: 08 de Enero de 2008, 11:51:09 por damago »

Desconectado Enigma

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 609
    • www.toroscoleados.com
Re: Barrido de displays!
« Respuesta #4 en: 08 de Enero de 2008, 13:50:25 »
Hola, oye gracias damago por esa teoria, la verdad no la sabia.... y si tenias razón, cuando declaré las variables como globales pues los displyas prendieron, no como queria, pero ñpor lo menos prendieron!!!! esso es un inicio!!!! Muchas gracias!!!

Micro_cadaver en realidad si te soy sincera, ni yo misma sabia cual era la falla, ahorita fue que me la hicieron ver, parte del problema era la declaración de las variables!!!

jejeje gracias... voy a seguir metiendole mano al programa a ver si logro que funcione!!! Gracias por la ayuda!!! :-)

Atte: Enigma... La llanerita de Guayana :-)
No hay nada como cabalgar en la sabana y sentir la brisa con olor a mastranto, bosta y ganado. ¡¡O Fortuna, velut luna, status variabilis, semper crescis, aut decrescis, vita detestabili!! Que viva el coleo, la musica LLanera y la gótica!

Desconectado damago

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 320
Re: Barrido de displays!
« Respuesta #5 en: 13 de Enero de 2008, 10:24:46 »
Hola Enigma, aunque hayas decidido usar variables globales, quiero completar una cosilla que veo que falta en el punto 2.1)

te he comentado como se declara 'cont' como puntero en la funcion mostrar (int *cont) y como se usa dentro: (*cont) = 2;

pero no te habia comentado como se llama a la funcion 'mostrar' desde la funcion 'main'. Como ahora lo que pasas es una direccion, no un valor, la llamada seria asi:

blablabla...
mostrar(&cont, resul); // el operador '&' se pone delante para pasar la direccion de la variable cont, en lugar de su valor
blablabbla....

Un saludo. Dani.