TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Algec en 09 de Enero de 2006, 06:57:00

Título: Itoa y atoi en ccs
Publicado por: Algec en 09 de Enero de 2006, 06:57:00
no se porque pero no funciona como debiera la funciona atoi e itoa en CCS, a menos que sea un fallo mio, que es lo mas logico

Segun la ayuda de CCS deberia ser asi
#inlcude<stdlib.h>
 int32 x=1234;
char string[5];
itoa(x,10, string);

// string es ahora “1234”


Si se incluye esto exactamente asi en un programa no me lo compila.

Bien yo use la siguiente rutina asi

#include <stdlib.h>

char string[10];
int x= 1234;
int uni, dec,cen;

string=itoa(x,10); // esta linea me da error al compilar asi que la escribi asi
itoa(x,10,string); // asi la compila


uni = atoi(string[0]);
dec = atoi(string[1]);
cen = atoi(string[2]);

segun entiendo yo UNI deberia ser 3
dec deberia ser 2
y cen deberia ser 1

LA idea es para mandar estos caracteres a unos displays de 7 seg despues de la conversion a su codigo correspondiente, pero antes descomponer el entero o el float en sus digitos simples


¿me podeis ayudar? ¿en que me equivoco?
Título: RE: Itoa y atoi en ccs
Publicado por: pocher en 09 de Enero de 2006, 07:22:00
Que raro que no te funcione lo de arriba, ya que es el ejemplo que aparece en el compilador.

Yo creo que uni = atoi(string[0]) debebiera de dar el 1 y no el 3, etc para los demás.

Un saludo
Título: RE: Itoa y atoi en ccs
Publicado por: pocher en 09 de Enero de 2006, 07:32:00
Ahora que lo veo, tienes puesto:

int x= 1234;

Tendría que ser int16
Título: RE: Itoa y atoi en ccs
Publicado por: Algec en 09 de Enero de 2006, 07:33:00
SI es asi, pero es al escribir este ejemplo usaba int32
Pero por lo demas pasa lo que os indico
Título: RE: Itoa y atoi en ccs
Publicado por: pocher en 09 de Enero de 2006, 07:44:00
Acabo de compilar lo de arriba y sí funciona. ¿?
Título: RE: Itoa y atoi en ccs
Publicado por: pocher en 09 de Enero de 2006, 07:56:00
Realmente una vez tienes la cadena "1234" el paso a entero de cada caracter individual lo podrías quitar.

Tan solo tendrías que hacer:

for (n=0;n<4;n++)

{

if (cadena[n]=="0")   output_b 0x3F;    //El 0

etc

Un saludo

PD. También se podría hacer con sprintf
Título: RE: Itoa y atoi en ccs
Publicado por: Algec en 09 de Enero de 2006, 10:17:00
Sera mi compilador?
Probare otra version
Gracias ya te pego todo y el proteus si no funciona
Título: RE: Itoa y atoi en ccs
Publicado por: Algec en 09 de Enero de 2006, 10:19:00
Sera mi compilador?
Probare otra version
Gracias ya te pego todo y el proteus si no funciona
Título: RE: Itoa y atoi en ccs
Publicado por: El_Coach en 09 de Enero de 2006, 11:18:00
Hola, yo tengo la versión 3.221 y en la ayuda tan solo aparece atoi().

¿Que versiones utilizais?


1saludo RollEyes
Título: RE: Itoa y atoi en ccs
Publicado por: pocher en 09 de Enero de 2006, 11:25:00
La 3.241
Título: RE: Itoa y atoi en ccs
Publicado por: pocher en 09 de Enero de 2006, 12:32:00
Esto:

uni = atoi(string[0]);
dec = atoi(string[1]);
cen = atoi(string[2]);

no va a funcionar, ya que debes declarar cada elemento de la matriz en atoi como un puntero. Te lo digo por si lo sigues usando.
Título: RE: Itoa y atoi en ccs
Publicado por: Algec en 09 de Enero de 2006, 13:14:00
Comprendo, deberan ser punteros distintos, uno para cada digito. Es asi?
Tendria que declarar varios int, como
int unidades, decenas, centenas etc
Título: RE: Itoa y atoi en ccs
Publicado por: pocher en 09 de Enero de 2006, 13:25:00
Eso es. Pruebalo y si no te sale te digo como lo haría yo.
Título: RE: Itoa y atoi en ccs
Publicado por: El_Coach en 10 de Enero de 2006, 03:24:00
Ok, desconocía de la existencia de estas funciones.
Está bien tenerlas en cuenta.

Suerte Algec.


1saludoSonrisa
Título: RE: Itoa y atoi en ccs
Publicado por: Algec en 10 de Enero de 2006, 06:11:00
A ver, las conocia del C convencional, y pense usarlas para hacer lo que quiero.
LA idea es haxcer una funcion que sirva para excitar un display de 7 seg de los digitos que queramos, del tipo

Visualizar_display(float valor,char  numero de digitos)

el problema me surge al descomponer el float en los distintos digitos para visualizarlos

Esta funciona servira para el numero de digitos del display que usemos pasandole el parametro correspondiente.
ME gusta hacer funciones estandar, por lo que incluso se le puede pasar el parametro de si el display es de anodo comun o de catodo comun.
Tengo hecho toda la funcion y va bien con un display y un contador hasta de 8 digitos, pero asi es mas facil ya que solo visualizo el conteo que son enteros int32

el problema surge al pasarle un valor float y tenerlo que descomponer en sus respectivos enteros decenas etc + el punto decimal


a ver a quien se le ocurre la forma de convertir en char cada unidad, decena centena etc ya que uso la siguiente formula para visualizar


uso dos puertos, b y d.
el B saca el dato a visualizar con una conversion del tipo

char dato[10]={valor hex del cero, valor hex del 1.......};

por lo que lo envio a el puerto B con

output_b(dato[valor entero]);

y el puerto D hace el barrido de excitacion de el display correspondiente a ese dato y asi sucesivamente



el problema repito es al tener que pasar del float a valor entero del display correspondiente


seria un bucle asi

for(x=0; x<numero de digitos;x++){
output_b(dato[valor entero]);
output_d(seleccion de display en hex
Título: RE: Itoa y atoi en ccs
Publicado por: El_Coach en 10 de Enero de 2006, 06:42:00
Hola, para convertir en char un número te puede servir esto:

caracter = "0" + numero;

Esto suma tu número al valor correspondiente al cero en ASCII.
Entonces ahora carácter tiene el valor ASCII de tu número.

Espero que te sirva.


Un saludo Giño
Título: RE: Itoa y atoi en ccs
Publicado por: pocher en 10 de Enero de 2006, 11:25:00
Bien, supongamos que quieres representar el 134,45

- Primero multiplicalo por 100. Resultado 13445

- Pasa este número a cadena con itoa ó con sprintf

- Pasa cada caracter del número a entero, empleando punteros:

*cadena4=cadena[4];
*cadena3=cadena[3];
*cadena2=cadena[2];
*cadena1=cadena[1];
*cadena0=cadena[0];

uni=atoi(cadena4);
dec=atoi(cadena3);
cen=atoi(cadena2);
unim=atoi(cadena1);
decm=atoi(cadena0);

- Ahora mediante if averigua donde poner el punto decimal.

Esta es una de las formas en que puedes trocear el número. Se puede hacer de otras muchas formas como te comente en un mensaje anterior.

Espero te sirva.

Un saludo

Título: RE: Itoa y atoi en ccs
Publicado por: Algec en 10 de Enero de 2006, 11:31:00
Lo pruebo esta noche y ya te comento, si no pegare todo el fichero
Muchas gracias
Título: RE: Itoa y atoi en ccs
Publicado por: Algec en 11 de Enero de 2006, 06:19:00
TE envio por mail lo que tengo hecho, ya me comentas si no te importa, sigue sin funcionar
Título: RE: Itoa y atoi en ccs
Publicado por: Algec en 11 de Enero de 2006, 11:07:00
Gracias tio eres un genio, ya vi lo que estaba mal, tu ejemplo funciona de lujo.
Cuando este terminado lo publico con tu permiso por si sirve para algo
ME gusta hacer montajes que sirvan para multiples usos, ya tengo hechas algunas librerias para eso.
Saludos y gracias de nuevo
Título: RE: Itoa y atoi en ccs
Publicado por: Algec en 11 de Enero de 2006, 13:53:00
BIen continuo en el tema, he modificado algo la rutina para que sea mas "elegante" y eliminar variables y queda de la siguiente forma
//   Conexiones:
//         · RD0 -> Display 1º 7seg
//         · RD1 -> Display 2º 7seg
//         · RD2 -> Display 3º 7seg
//         · RD3 -> Display 4º 7seg
//         · RD4 -> Display 5º 7seg
//         · RD5 -> Display 6º 7seg
//         · RD6 -> Display 7º 7seg
//         · RD7 -> Display 8º 7seg
//         · RB0 -> a 7seg
//         · RB1 -> b 7seg
//         · RB2 -> c 7seg
//         · RB3 -> d 7seg
//         · RB4 -> e 7seg
//         · RB5 -> f 7seg
//         · RB6 -> g 7seg
///////////////////////////////////

#include <16f877a.h>
#include <stdlib.h>
#fuses XT,NOWDT,NOPROTECT
#use delay (clock=4000000)
#use fast_io(B)
#use fast_io(D)

visualizar_display(int32 x)
{
   char cadena[9];
   char cadena7[2]={0};
   char cadena6[2]={0};
   char cadena5[2]={0};
   char cadena4[2]={0};
   char cadena3[2]={0};
   char cadena2[2]={0};
   char cadena1[2]={0};
   char cadena0[2]={0};


    // tabla de salidas de excitacion de siete segmentos

   //   int tab7seg[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67};   //  7seg hex 0-9 catodo comun
   int tab7seg[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xf8,0x80,0x98};   //  7seg hex 0-9 anodo comun

     // para hacer el barrido de los 8 displays
     int muestra_digito[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};           //  Seleccion del display a visualizar

   // pasa el entero a cadena
 
   itoa(x,10,cadena);

   // Pasa cada cada caracter del número a entero, empleando punteros:

   *cadena7=cadena[7];
   *cadena6=cadena[6];
   *cadena5=cadena[5];
   *cadena4=cadena[4];
   *cadena3=cadena[3];
   *cadena2=cadena[2];
   *cadena1=cadena[1];
   *cadena0=cadena[0];

    // pone el caracter en la salida
    // activa el display correspondiente

    output_b(tab7seg[atoi(cadena0)]);               //...1erº 7seg
    output_d(muestra_digito[7]);
    delay_ms(1);

    //continua con cada digito

    output_b(tab7seg[atoi(cadena1)]);
    output_d(muestra_digito[6]);
    delay_ms(1);


    output_b(tab7seg[atoi(cadena2)]);
    output_d(muestra_digito[5]);
    delay_ms(1);


    output_b(tab7seg[atoi(cadena3)]);
    output_d(muestra_digito[4]);
    delay_ms(1);


    output_b(tab7seg[atoi(cadena4)]);
    output_d(muestra_digito[3]);
     delay_ms(1);

    output_b(tab7seg[atoi(cadena5)]);
    output_d(muestra_digito[2]);
    delay_ms(1);

    output_b(tab7seg[atoi(cadena6)]);
    output_d(muestra_digito[1]);
     delay_ms(1);

    output_b(tab7seg[atoi(cadena7)]);
    output_d(muestra_digito[0]);
    delay_ms(1);

   }


   main()
   {
   int32 y;
   set_tris_b(0x00);
   set_tris_d(0x00);
   do{
      visualizar_display(y);
      y++;
          }while(1);
   }
 Funciona bien con int32 salvo que empieza a contar por la izda sin tener en cuenta los ceros de la derecha, lo cual es un problema, ademas no consigo trasladar la rutina a funcionamiento con float que es como realmente deberia funcionar.
Si te molestas en mirarla veras que lo que te digo es asi, espero que no hayas borrado el motajito de proteus.
Se que doy la lata pero de veras que ando atascado con esto.
Título: RE: Itoa y atoi en ccs
Publicado por: pocher en 13 de Enero de 2006, 00:24:00
Ya lo tengo casi resuelto. Ayer por la tarde le estuve dando vueltas.

La verdad que al usar las funciones atoi e itoa y necesitar punteros para cada caracter individual se complica la cosa. Hay algo que no entiendo relativo al uso de punteros con atoi, pero para esto abriré un tema nuevo.

Lo dicho esta tarde te pego la solución.

Un saludo

Título: RE: Itoa y atoi en ccs
Publicado por: Algec en 13 de Enero de 2006, 02:37:00
Gracias por todo
Veras mi idea de hacer la funcion totalmente flexible es usarla en todos los sitios que necesite visualizar un float con displays.
Con lcd es simple pero los displays dan problemas en la posicion de los digitos y en el punto decimal. TRato de hacer una funcion estandar como la que tengo de teclado y de LCD, asi crear una libreria que usar para cada programa y limitarme a hacer el soft correspondiente, como para hacer un frecuencimetro contador, o lo que sea.
Se que te estoy dando trabajo, pero sigo estancado
De nuevo mi agradecimiento
Título: RE: Itoa y atoi en ccs
Publicado por: pocher en 13 de Enero de 2006, 13:38:00
Te pego lo que tengo. Representa de 1 a 8 dígitos pero sin usar decimales.

Cuando le mandas representar un solo dígito no se enciende, habrá que depurar ese error, las demás combinaciones de 2 a 8 dígitos van bien.

Como te comenté el hacerlo con estas funciones y tener que usar punteros me ha complicado la existencia. Hubiera sido más sencillo hacerlo con caracteres (sin atoi ni itoa) en lugar de con enteros.

Este es el código:

Codigo:

// Conexiones:
// · RD0 -> Display 1º 7seg
// · RD1 -> Display 2º 7seg
// · RD2 -> Display 3º 7seg
// · RD3 -> Display 4º 7seg
// · RD4 -> Display 5º 7seg
// · RD5 -> Display 6º 7seg
// · RD6 -> Display 7º 7seg
// · RD7 -> Display 8º 7seg
// · RB0 -> a 7seg
// · RB1 -> b 7seg
// · RB2 -> c 7seg
// · RB3 -> d 7seg
// · RB4 -> e 7seg
// · RB5 -> f 7seg
// · RB6 -> g 7seg
///////////////////////////////////

#include <16f877a.h>
#include <stdlib.h>
#fuses XT,NOWDT,NOPROTECT
#use delay (clock=4000000)
#use fast_io(B)
#use fast_io(D)


visualizar_display(int32 x)
{
   int n=5,a;
   char cadena[9];

   //char *pcadena;

   //char *psal=cadena;

   char cadena7[2]={0};
   char cadena6[2]={0};
   char cadena5[2]={0};
   char cadena4[2]={0};
   char cadena3[2]={0};
   char cadena2[2]={0};
   char cadena1[2]={0};
   char cadena0[2]={0};

// tabla de salidas de excitacion de siete segmentos

// int tab7seg[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67}; // 7seg hex 0-9 catodo comun
   int tab7seg[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xf8,0x80,0x98}; // 7seg hex 0-9 anodo comun

   // para hacer el barrido de los 8 displays
   int muestra_digito[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; // Seleccion del display a visualizar

   // pasa el entero a cadena

   itoa(x,10,cadena);
   //sprintf(cadena,"%lu",x);

   //pcadena=cadena;            //O también pcadena=&cadena[0];

   // Pasa cada cada caracter del número a entero, empleando punteros:

   *cadena7=cadena[7];
   *cadena6=cadena[6];
   *cadena5=cadena[5];
   *cadena4=cadena[4];
   *cadena3=cadena[3];
   *cadena2=cadena[2];
   *cadena1=cadena[1];
   *cadena0=cadena[0];

   // pone el caracter en la salida
   // activa el display correspondiente

   output_b(tab7seg[atoi(cadena0)]);
   output_d(muestra_digito[n-1]);
   delay_ms(1);
   if (n==1)
      return;

   output_b(tab7seg[atoi(cadena1)]);
   output_d(muestra_digito[n-2]);
   delay_ms(1);
   if (n==2)
      return;

   output_b(tab7seg[atoi(cadena2)]);
   output_d(muestra_digito[n-3]);
   delay_ms(1);
   if (n==3)
      return;
   
   output_b(tab7seg[atoi(cadena3)]);
   output_d(muestra_digito[n-4]);
   delay_ms(1);
   if (n==4)
      return;
   
   output_b(tab7seg[atoi(cadena4)]);
   output_d(muestra_digito[n-5]);
   delay_ms(1);
   if (n==5)
      return;

   output_b(tab7seg[atoi(cadena5)]);
   output_d(muestra_digito[n-6]);
   delay_ms(1);
   if (n==6)
      return;

   output_b(tab7seg[atoi(cadena6)]);      //Decenas
   output_d(muestra_digito[n-7]);
   delay_ms(1);
   if (n==7)
      return;

   output_b(tab7seg[atoi(cadena7)]);       //Unidades
   output_d(muestra_digito[n-8]);
   delay_ms(1);      
   if (n==8)
      return;
   

/*
for(a=1;a<=n;a++)
{
   //output_b(tab7seg[atoi(*pcadena)]);
   //output_b(tab7seg[atoi(psal)]);
   output_d(muestra_digito[n-a]);
   delay_ms(1);
}
*/

}


main()
{
int32 y=76543210;
set_tris_b(0x00);
set_tris_d(0x00);
do{
visualizar_display(y);
//y++;
}while(1);
}


Prueba y me comentas.
Título: RE: Itoa y atoi en ccs
Publicado por: Algec en 14 de Enero de 2006, 14:05:00
Ya funciona con 1 caracter nada mas, ademas de hacerle algun arreglillo mas:
Te pego el codigo.-
// Conexiones:
// · RD0 -> Display 1º 7seg
// · RD1 -> Display 2º 7seg
// · RD2 -> Display 3º 7seg
// · RD3 -> Display 4º 7seg
// · RD4 -> Display 5º 7seg
// · RD5 -> Display 6º 7seg
// · RD6 -> Display 7º 7seg
// · RD7 -> Display 8º 7seg
// · RB0 -> a 7seg
// · RB1 -> b 7seg
// · RB2 -> c 7seg
// · RB3 -> d 7seg
// · RB4 -> e 7seg
// · RB5 -> f 7seg
// · RB6 -> g 7seg
///////////////////////////////////

#include <16f877.h>
#include <stdlib.h>
#fuses XT,NOWDT,NOPROTECT
#use fast_io(B)
#use fast_io(D)
#use delay (clock=40000000)




visualizar_display(int32 x)
{
   int n=0;
   int tiempo =1;
   char cadena[11];
   char cadena8[2];
   char cadena7[2];
   char cadena6[2];
   char cadena5[2];
   char cadena4[2];
   char cadena3[2];
   char cadena2[2];
   char cadena1[2];
   char cadena0[2];

// tabla de salidas de excitacion de siete segmentos



// para hacer el barrido de los 8 displays
   int muestra_digito[9]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; // Seleccion del display a visualizar

// int tab7seg[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67}; // 7seg hex 0-9 catodo comun
   int tab7seg[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xf8,0x80,0x98}; // 7seg hex 0-9 anodo comun

   // pasa el entero a cadena

    itoa(x,10,cadena);
   n=strlen(cadena);

   // Pasa cada cada caracter del número a entero, empleando punteros:


   *cadena7=cadena[7]; // Unidades
   *cadena6=cadena[6]; // Decenas
   *cadena5=cadena[5]; // Centenas
   *cadena4=cadena[4]; //.....
   *cadena3=cadena[3];
   *cadena2=cadena[2];
   *cadena1=cadena[1];
   *cadena0=cadena[0];




   // pone el caracter en la salida
   // activa el display correspondiente



   output_b(tab7seg[atoi(cadena0)]);
   output_d(muestra_digito[n-1]);
   delay_ms(tiempo);
   if (n==0)
      return;

   output_b(tab7seg[atoi(cadena1)]);
   output_d(muestra_digito[n-2]);
   delay_ms(tiempo);
   if (n==1)
      return;

   output_b(tab7seg[atoi(cadena2)]);
   output_d(muestra_digito[n-3]);
   delay_ms(tiempo);
   if (n==2)
      return;

   output_b(tab7seg[atoi(cadena3)]);
   output_d(muestra_digito[n-4]);
   delay_ms(tiempo);
   if (n==3)
      return;

   output_b(tab7seg[atoi(cadena4)]);
   output_d(muestra_digito[n-5]);
   delay_ms(tiempo);
   if (n==4)
      return;
   output_b(tab7seg[atoi(cadena5)]);      // Centenas
   output_d(muestra_digito[n-6]);
   delay_ms(tiempo);
   if (n==5)
     return;

   output_b(tab7seg[atoi(cadena6)]);      //Decenas
   output_d(muestra_digito[n-7]);
   delay_ms(tiempo);
   if (n==6)
      return;

   output_b(tab7seg[atoi(cadena7)]); //Unidades, este se tiene que imprimir el primero para que no salga 7 al empezar ¿?
   output_d(muestra_digito[n-8]);
   delay_ms(tiempo);
   if (n==7)
      return;

  }
int32 y=0;

#int_RTCC
pulse()
{
      visualizar_display(y);
      visualizar_display(y);
      visualizar_display(y);
     
       set_rtcc(220);
}

main()
   {
   setup_counters(RTCC_INTERNAL, RTCC_DIV_256);
                enable_interrupts(INT_RTCC);
                enable_interrupts(GLOBAL);
                set_rtcc(220);
  set_tris_b(0x00);
  set_tris_d(0x00);

// ejemplo de funcionamiento
  delay_ms(100);
   y++;
  delay_ms(100);
   y++;
  delay_ms(100);
   y=y+2;
  delay_ms(100);
   y=y+2;
  delay_ms(100);
   y=y+23;
  do{
        y=y+33;
        delay_ms(100);
    }while(1);
  }


De todas formas veras que lo hice funcionar por interrupcion asi el display se refresca cada cierto tiempo independientemente del programa.

Otra cuestion es que la primera vez que se ejecuta la rutina dibuija un 7
¿¿¿¿¿??????? no tengo ni P I del porque
Tambien me dan problemas el tamaño de las cadenas y no encuentro la forma de eliminar las intermedias con redireccionamiento de punteros tipo &cadena o algo asi
No me gusta usar muchas variables

UNa cosa mas, el siguiente paso es FLOATS que es lo que realmente queria yo hacer, asi que seguire y si me ayudas te estare muy agradecido
Sigo en lo mismo, si necesitas tu algo no dudes en decirlo
Título: RE: Itoa y atoi en ccs
Publicado por: RedPic en 14 de Enero de 2006, 14:52:00
Amigo Algec:

Te ruego que justo delante de tu código coloques la directiva code (entre corchetes) y justo donde acabe coloques la directiva /code (entre corchetes) tal como hace el maestro Pocher.

Así tu código queda mucho mas bonito y, sobre todo, mucho mas legible para todos. Es un detalle que a todos nos han tenido que recordar y que es muy útil en este tipo de foros en los que estamos colocando constantemente código fuente de programas.

Gracias.

Título: RE: Itoa y atoi en ccs
Publicado por: Algec en 15 de Enero de 2006, 08:03:00
Perdonad por no haberlo incluido pero no sabia que era tan util, a partir de ahora lo tendre en cuenta.
LA rutina con float ya esta casi casi lista a falta de unos retoques, funciona muy bien, si puedo esta misma tarde la pego.
Estoy terminando de configurarla para displays de anodo comun y catodo comun.
Título: RE: Itoa y atoi en ccs
Publicado por: pocher en 15 de Enero de 2006, 10:20:00
En el anterior programa que envié y que decía que había un error al no representar el caso de un solo dígito, pués bien, estoy casi convencido que es culpa del PROTEUS. Le he puesto un VTERM al circuito y por el PORTB y PORTD salen los números que tienen que salir para representación de un solo dígito, pero el PROTEUS no lo dibuja en pantalla.

En fín este es el precio que hay que pagar con el PROTEUS, has de perder tiempo (en ocasiones demasiado) para saber si es culpa tuya o del programa (o del compilador). No siempre se puede disponer de circuitos reales...

Otra cosa que también me ha hecho perder tiempo es el parpadeo de los números. En un programa no parpadeaban y en el mismo programa (sin tocar nada) pero con más (o menos, no me acuerdo) líneas de comentarios los números parpadeaban. Dirás que no puede ser pero te aseguro que es cierto.

Me imagino que estas cosas que me han pasado a mí, también te habran sucedido.

Un saludo
Título: RE: Itoa y atoi en ccs
Publicado por: Algec en 15 de Enero de 2006, 13:21:00
Ya he resuelto casi todo, sale el digito y ademas funciona para floats con coma flotante.
VEras te pego el codigo con varios ejemplos.
Como dices el Proteus tiene esas cosas, pero se le perdonan.
Codigo:

Codigo:--------------------------------------------------------------------------------
// Conexiones:
// · RD0 -> Display 1º 7seg
// · RD1 -> Display 2º 7seg
// · RD2 -> Display 3º 7seg
// · RD3 -> Display 4º 7seg
// · RD4 -> Display 5º 7seg
// · RD5 -> Display 6º 7seg
// · RD6 -> Display 7º 7seg
// · RD7 -> Display 8º 7seg
// · RB0 -> a 7seg
// · RB1 -> b 7seg
// · RB2 -> c 7seg
// · RB3 -> d 7seg
// · RB4 -> e 7seg
// · RB5 -> f 7seg
// · RB6 -> g 7seg
// · RB7 -> Punto 7seg
///////////////////////////////////

#include <16f877.h>
#include <stdlib.h>
#include <math.h>


#fuses XT,NOWDT,NOPROTECT
#use fast_io(B)
#use fast_io(D)
#use delay (clock=1000000)




visualizar_display(float f, int numero_total_digitos, int numero_de_decimales)
{
   int32 x=0;
   float f1;
   int n=0;
   int c=0;
   int tiempo =10;
   char cadena[10];
   char cadena8[4];
   char cadena7[4];
   char cadena6[4];
   char cadena5[4];
   char cadena4[4];
   char cadena3[4];
   char cadena2[4];
   char cadena1[4];
   char cadena0[4];


// para hacer el barrido de los 8 displays
   int muestra_digito[9]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; // Selecciona el display a visualizar

// tabla de salidas de excitacion de siete segmentos
// Cambiar la tabla segun se vaya a usar uno u otro tipo de display
//(0,1,2,3,4,5,6,7,8,9,Punto,E.)

// int tab7seg[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67}; // 7seg hex 0-9 catodo comun
   int tab7seg[11]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xf8,0x80,0x98,0x7f}; // 7seg hex 0-9 anodo comun
   
   // en funcion del numero de decimales que queremos visualizar lo va a convertir
   // en entero y para no perder la parte decimal lo multiplica antes por el valor
   // correspondiente


   if(numero_de_decimales ==1)
      f1=f*10;
   if(numero_de_decimales ==2)
      f1=f*100;
   if(numero_de_decimales ==3)
      f1=f*1000;
   if(numero_de_decimales ==4)
      f1=f*10000;
   if(numero_de_decimales ==5)
      f1=f*100000;
   if(numero_de_decimales ==6)
      f1=f*1000000;
   if(numero_de_decimales ==7)
      f1=f*10000000;

   // redondea por arriba el float una vez multiplicado

   x=ceil(f1);

   // Si el tamaño del numero a visualizar excede de la longitud del display visualiza  E.


   // pasa el entero a cadena


    itoa(x,10,cadena);

   // calcula la longitud de la cadena

   n=strlen(cadena);

   // Pasa cada cada caracter del número a entero, empleando punteros:

   *cadena7=cadena[7]; // Unidades
   *cadena6=cadena[6]; // Decenas
   *cadena5=cadena[5]; // Centenas
   *cadena4=cadena[4]; //.....
   *cadena3=cadena[3];
   *cadena2=cadena[2];
   *cadena1=cadena[1];
   *cadena0=cadena[0];


   // si excede  el numero de digitos del visualizador dibuja una E. en este

   if(n>numero_total_digitos)
      {
      output_b(tab7seg[10]);        // Visualiza E. en el display si se produce saturacion y sale de la rutina
        output_d(muestra_digito[0]);
      delay_ms(tiempo);
      return;
      }


   // Si el valor es menor que 1, para que visualice el cero anterior y los posteriores a  la coma
   
  if(f<1)
      {
         // Visualiza 0. en el display en su lugar correspondiente
         output_b(tab7seg[0]);        
          output_d(muestra_digito[numero_de_decimales]);
         delay_ms(tiempo);

         // Visualiza tantos ceros como sean necesarios en el display en su
         // lugar correspondiente despues de la coma
       
         for(c=numero_total_digitos-n;c>n;c--)
            {
            output_b(tab7seg[0]);      
              output_d(muestra_digito[c-1]);
            delay_ms(tiempo);
            }
         }
   
   

   // coloca el punto decimal en su lugar

   output_b(0x7f);
   output_d(muestra_digito[numero_de_decimales]);
   delay_ms(tiempo);


   // las siguientes lineas ponen cada caracter en la salida
   // y activan el display correspondiente

   output_b(tab7seg[atoi(cadena0)]);
   output_d(muestra_digito[n-1]);
   delay_ms(tiempo);
   if (n==0)
      return;


   output_b(tab7seg[atoi(cadena1)]);
   output_d(muestra_digito[n-2]);
   delay_ms(tiempo);
   if (n==1)
      return;


   output_b(tab7seg[atoi(cadena2)]);
   output_d(muestra_digito[n-3]);
   delay_ms(tiempo);
   if (n==2)
      return;


    output_b(tab7seg[atoi(cadena3)]);
   output_d(muestra_digito[n-4]);
   delay_ms(tiempo);
   if (n==3)
      return;


   output_b(tab7seg[atoi(cadena4)]);
   output_d(muestra_digito[n-5]);
   delay_ms(tiempo);
   if (n==4)
      return;


   output_b(tab7seg[atoi(cadena5)]);      // Centenas
   output_d(muestra_digito[n-6]);
   delay_ms(tiempo);
   if (n==5)
     return;


   output_b(tab7seg[atoi(cadena6)]);      //Decenas
   output_d(muestra_digito[n-7]);
   delay_ms(tiempo);
   if (n==6)
      return;

   output_b(tab7seg[atoi(cadena7)]);      //Unidades
   output_d(muestra_digito[n-8]);
   delay_ms(tiempo);
   if (n==7)
      return;

  }

float y=0;

// rutina de interrupcion por desbordamiento

#int_RTCC

pulse()
{
      visualizar_display(y,6,3);
      set_rtcc(256);
}


// Programa Principal

main()
   {
   setup_counters(RTCC_INTERNAL, RTCC_DIV_8);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);
   set_rtcc(256);
   set_tris_b(0x00);
   set_tris_d(0x00);

   // necesario inicializar las salidas para que en el primer barrido no salgan caracteres raros

   output_b(0x00);
   output_d(0x00);

   // ejemplo de funcionamiento

  do{
    y=0;
    delay_ms(5000);
    y=14.023;  
    delay_ms(5000);
    y=104.23;  
    delay_ms(5000);
    y=104.3;  
    delay_ms(5000);

    for(y=0;y<10;y=y+0.005)
       delay_ms(100);
    for(y=0;y<50;y=y+1)
       delay_ms(100);
    for(y=0;y<500;y=y+10)
       delay_ms(100);
    for(y=0;y<9999;y=y+100)
       delay_ms(100);
   
    }while(1);
  }

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


Hay varias cosas que quiero consultarte que no comprendo porque pasan


Te enumero
1.- Si las cadenas que se usan para los punteros se cambian a menos caracteres de 5 da problemas ¿?
¿Ves alguna forma de trabajar sin estas cadenas intermedias? la verdad es me gustan poco, aunque funcione
2.- Al visualizar valor CERO me dibuja un cero de mas
3.- No van bien los tiempos de las interrupciones pero eso supongo que sera el Proteus


Por lo demas creo que trabaja bien, compruebalo como quieras

Ademas al compilar pasa algo raro, si aumento la tab7seg[11] a tab7seg [12] para incluir el punto decimal el compilador me da error de RAM cuando sin incluirlo tiene un 14% de uso ¿?

Si ves algun error mas dimelo, voy a hacer ahora la de catodo comun

Muchas gracias

Muchas gracias tio
Título: RE: Itoa y atoi en ccs
Publicado por: pocher en 17 de Enero de 2006, 11:19:00
Lo he estado provando, ahora que tengo un poco de tiempo y va bastante bien. Falta depurar un poco más, pero ya casi lo tienes.

- Los ceros a la derecha del punto decimal no aparecen. O es culpa del PROTEUS o del bucle for:

Codigo:

      for(c=numero_total_digitos-n;c>n;c--)
     {
           output_b(tab7seg[0]);      
              output_d(muestra_digito[c-1]);
               delay_ms(tiempo);
     }



Estos ceros aparecen un pequeño instante y luego se borran.

- tab7seg[12] a mí no me dá error.

- Los tiempos quiza no te salgan según quieres por la fosc=1Mhz que empleas. La has tenido en cuenta a la hora de hacer los números, o los has hecho con fosc=4 Mhz?

A ver si solucionas lo poco que te queda. Un saludo

Título: RE: Itoa y atoi en ccs
Publicado por: Algec en 18 de Enero de 2006, 02:27:00
Como parece que hay problemas con el proteus para depurar la rutina totalmente usare un equipo real, asi que tardare un poco ya que voy a hacer la placa de los displays.
Ya comentare como va y el resultado final por si le interesara a alguien.
Título: RE: Itoa y atoi en ccs
Publicado por: lovando en 26 de Enero de 2006, 23:43:00
Escrito originalmente por Algec
Como parece que hay problemas con el proteus para depurar la rutina totalmente usare un equipo real, asi que tardare un poco ya que voy a hacer la placa de los displays.
Ya comentare como va y el resultado final por si le interesara a alguien.



Estoy probandolo en proteus, y parece que hay problemas durante los delay.

Sigo revisando...
Título: RE: Itoa y atoi en ccs
Publicado por: Algec en 31 de Enero de 2006, 07:56:00
Bien ya esta probado en un equipo real  y funcionando
EL codigo quedaria asi

Codigo:


////////////////////////////////////////////////////////////////////////
// Rutina de visualizacion de Float en displays de 7 seg
// Funciona con una maximo de 8 displays de anodo comun
// Representa Floats por lo que el numero de decimales no puede ser inferior a uno
//
// Conexiones:
// · RD0 -> Display 1º 7seg
// · RD1 -> Display 2º 7seg
// · RD2 -> Display 3º 7seg
// · RD3 -> Display 4º 7seg
// · RD4 -> Display 5º 7seg
// · RD5 -> Display 6º 7seg
// · RD6 -> Display 7º 7seg
// · RD7 -> Display 8º 7seg
//
// se conecta los pines RD mediante un transistor BC557 y una resistencia de base
// ya que la corriente total de los 7 seg supera la capacidad de salida de la RD del pic
//
// · RC0 -> a 7seg
// · RC1 -> b 7seg
// · RC2 -> c 7seg
// · RC3 -> d 7seg
// · RC4 -> e 7seg
// · RC5 -> f 7seg
// · RC6 -> g 7seg
// · RC7 -> Punto 7seg
//
// Se conectan las salidas RC al display a traves de una resistencia de un valor adecuado a la corriente
// exijida por el display para su correcto encendido
// Puede ser un valor aproximado entre 10 mAmp y 20 mAmp
// por lo que la resistencia debe ser de entre 100 y 330 Ohmios aproximadamente
//////////////////////////////////////////////////////////////////////

#include <16f877.h>
#include <stdlib.h>
#include <math.h>


#fuses XT,NOWDT,NOPROTECT
#use delay (clock=4000000)
#USE FAST_IO (C)
#USE FAST_IO (D)




// para hacer el barrido de los 8 displays
   int muestra_digito[9]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F}; // Selecciona el display a visualizar

   // tabla de salidas de excitacion de siete segmentos
   // digitos a mostrar (0,1,2,3,4,5,6,7,8,9,Punto,E)

   int tab7seg[12]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xf8,0x80,0x98,0x7f,0x86}; // 7seg hex 0-9 anodo comun

   // ajuste del tiempo que se queda encendido cada diodo de el display
   // con este ajuste y el valor de tiempo de la interrupcion se quita el parpadeo

   int tiempo =2;




visualizar_display(float f, int numero_total_digitos, int numero_de_decimales)
{
   int32 x=0;
   float f1;
   int n=0;
   int ceros=0;
   char cadena[10];
   char cadena8[4];
   char cadena7[4];
   char cadena6[4];
   char cadena5[4];
   char cadena4[4];
   char cadena3[4];
   char cadena2[4];
   char cadena1[4];
   char cadena0[4];


   // en funcion del numero de decimales que queremos visualizar lo va a convertir
   // en entero y para no perder la parte decimal lo multiplica antes por el valor
   // correspondiente

   if(numero_de_decimales ==1)
      f1=f*10;
   if(numero_de_decimales ==2)
      f1=f*100;
   if(numero_de_decimales ==3)
      f1=f*1000;
   if(numero_de_decimales ==4)
      f1=f*10000;
   if(numero_de_decimales ==5)
      f1=f*100000;
   if(numero_de_decimales ==6)
      f1=f*1000000;
   if(numero_de_decimales ==7)
      f1=f*10000000;


   // redondea por arriba el float una vez multiplicado

   x=ceil(f1);


   // pasa el entero a cadena


    itoa(x,10,cadena);

   // calcula la longitud de la cadena

   n=strlen(cadena);

   // Pasa cada cada caracter del número a entero, empleando punteros:

   *cadena7=cadena[7]; // Unidades
   *cadena6=cadena[6]; // Decenas
   *cadena5=cadena[5]; // Centenas
   *cadena4=cadena[4]; //.....
   *cadena3=cadena[3];
   *cadena2=cadena[2];
   *cadena1=cadena[1];
   *cadena0=cadena[0];
   

  // si excede  el numero de digitos del visualizador lo señaliza con E

   if(n > numero_total_digitos)
      {
      output_c(tab7seg[11]);                 // Visualiza E en el display si se produce saturacion y sale de la rutina
        output_d(muestra_digito[0]);
      delay_ms(tiempo);
      output_c(0xff);
      return;
      }

  // muestra el punto decimal

  if(numero_de_decimales > 0)
      {
      output_c(tab7seg[10]);
      output_d(muestra_digito[numero_de_decimales]);
      delay_ms(tiempo);
      output_c(0xff);
      }


         // Si el valor es menor que 1, para que visualice el cero anterior a la coma
         // y los posteriores

      ceros = numero_de_decimales - n + 1;

      /* truco para ver valor de variables            

         output_c(tab7seg[ceros]);
         output_d(muestra_digito[7]);           // se muestra en el ultimo digito
         delay_ms(tiempo);
         output_c(0xff);*/


     if(ceros > 0 && f <1)
         {
            do{
               output_c(tab7seg[0]);
                 output_d(muestra_digito[numero_de_decimales-ceros+1]); // posicion del cero anterior al punto
               delay_ms(tiempo);
               ceros--;
               output_c(0xff);
               }While(ceros != 0);
         }

   // las siguientes lineas ponen cada caracter en la salida
   // y activan el display correspondiente

 
   output_c(tab7seg[atoi(cadena0)]);
   output_d(muestra_digito[n-1]);           // digito de menor peso
   delay_ms(tiempo);
   output_c(0xff);

   If(n==1)
      return;

   output_c(tab7seg[atoi(cadena1)]);
   output_d(muestra_digito[n-2]);
     delay_ms(tiempo);
   output_c(0xff);

   If(n==2)
      return;
       
   output_c(tab7seg[atoi(cadena2)]);
   output_d(muestra_digito[n-3]);
     delay_ms(tiempo);
   output_c(0xff);

   If(n==3)
      return;
         
   output_c(tab7seg[atoi(cadena3)]);
     output_d(muestra_digito[n-4]);
     delay_ms(tiempo);
   output_c(0xff);

   If(n==4)
     return;

     
   output_c(tab7seg[atoi(cadena4)]);
     output_d(muestra_digito[n-5]);
     delay_ms(tiempo);
   output_c(0xff);

   If(n==5)
     return;
 
   output_c(tab7seg[atoi(cadena5)]);      
   output_d(muestra_digito[n-6]);
   delay_ms(tiempo);
   output_c(0xff);

   If(n==6)
     return;

   output_c(tab7seg[atoi(cadena6)]);      
   output_d(muestra_digito[n-7]);
   delay_ms(tiempo);
   output_c(0xff);

   If(n==7)
     return;

   output_c(tab7seg[atoi(cadena7)]);      
    output_d(muestra_digito[n-8]);
     delay_ms(tiempo);
   output_c(0xff);

           }

float y=0;

// rutina de interrupcion por desbordamiento

#int_RTCC

pulse()
{
  visualizar_display(y,5,2);
  set_rtcc(256);
}


// Programa Principal

main()
   {
   setup_counters(RTCC_INTERNAL, 0);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);
   set_rtcc(256);

   set_tris_c(0x00);
   set_tris_d(0x00);




   // ejemplo de funcionamiento
    y=0;

  do{
      y=y+0.1;
      // para hacer pruebas considero que es el tiempo de ejecucion
      // del programa de uso es de 10 mseg
      // y simulo el programa asi
      delay_ms(10);
 
    }while(1);
  }
 



Si alguien hace mas pruebas y obtiene errores por favor que los pegue y me indique donde y como, y si colabora a solucionarlo mejor.
Muchas gracias  a Pocher por su colaboracion en este tema como en todos.
Lo dejo abierto para las sugerencias que tengais
Título: RE: Itoa y atoi en ccs
Publicado por: I3iT en 31 de Enero de 2006, 16:27:00
Solo hacer un comentario, sobre los punteros:

Asignas:
Codigo:

*cadena5=cadena[5];


Para luego llamar a:
Codigo:

output_b(tab7seg[atoi(cadena5)]);



Y no seria lo mismo utilizar el "operador direccion de"(no se como llamarlo) --> & :
Codigo:

output_b(tab7seg[atoi(&cadena[5])]);



>Salu2<

Título: RE: Itoa y atoi en ccs
Publicado por: Algec en 01 de Febrero de 2006, 11:49:00
Ya lo intente pero no funcionaba, el problema lo resolvio pocher, creo que es a el a quien corresponde explicar el porque, ademas yo no lo se.
De hecho el codigo seria mas simple y el uso de variables menos.
Si te fijas tengo que hacer los arrays de mas de 4 ya que si los hago de 2 como seria logico puesto que serian de un caracter mas el terminador nulo  funciona mal
Aun no me explico la causa, asi que si alguien tiene algo que aportar que lo aclare le estaria agradecido
Título: RE: Itoa y atoi en ccs
Publicado por: pocher en 02 de Febrero de 2006, 13:16:00
Pués va a ser que yo tampoco lo sé. Teoricamente debería de funcionar también así con el "&", pero si se hace así no funciona el programa (por lo menos en PROTEUS).
Título: RE: Itoa y atoi en ccs
Publicado por: Algec en 02 de Febrero de 2006, 13:22:00
Si tengo un hueco lo probare en el real a ver que pasa, ya os dire
Título: Re:Itoa y atoi en ccs
Publicado por: Arsenic en 06 de Mayo de 2017, 09:09:39
Hola, colegas! ¿Hay alguna manera de que se puedan mostrar los ceros a la izquierda? Hago esto, pero en el LCD no los muestra.
Código: CSS
  1. printf(lcd_putc,"DATO: %s",itoa(intDato,2,strDato);
y cuando intDato = 0b0101, en el LCD sólo veo "DATO: 101"

Acepto todo tipo de sugerencias. Gracias!
Título: Re:Itoa y atoi en ccs
Publicado por: KILLERJC en 06 de Mayo de 2017, 10:22:10
Desde el printf no y el itoa tampoco, la otra que te queda es hacerte tu propio "itoa", suponiendo que es de 4 bits

Código: C
  1. strDato[0] = (intDato & 0x08 ? '1' : '0');
  2. strDato[1] = (intDato & 0x04 ? '1' : '0');
  3. strDato[2] = (intDato & 0x02 ? '1' : '0');
  4. strDato[3] = (intDato & 0x01 ? '1' : '0');
  5. strDato[4] = '\0';
  6.  
  7. printf(lcd_putc,"DATO: %s",strDato);
Título: Re:Itoa y atoi en ccs
Publicado por: RedPic en 06 de Mayo de 2017, 13:16:41
Hola, colegas! ¿Hay alguna manera de que se puedan mostrar los ceros a la izquierda? Hago esto, pero en el LCD no los muestra.

Aunque consume muchos recursos, cuando me es imprescindible hacerlo recurro a dos pasos sucesivos:

Primero lo "imprimo" en una variable de cadena con la longitud (en caracteres) que necesito y después sustituyo los espacios por ceros.

Para lo primero utilizo la característica del spintf que me permite indicarle cuantos caracteres quiero que ocupe el numero con %nu (donde n es el número de caracteres y u que voy a imprimir un entero corto), esto produce el número en ascii y tantos espacios por la izquierda como dígitos le hayamos indicado al %nu y después ...

Segundo un simple bucle for para sustituir los 0x20 (ASCII 32 del space) por el 0x30 (ASCII 48 del '0').

Así si quiero generar números de tres dígitos completando por cero por la izquierda hago la siguiente función:

No se si te servirá algo así, por lo menos te doy una idea  :mrgreen:

Código: CSS
  1. // Ejemplo imprimiendo un entero corto con tres dígitos rellenando de ceros por la izquierda
  2. // Entrada: dato entero de 8 bits a "imprimir"
  3. // Salida: puntero a cadena donde devuelvo el número impreso
  4.  
  5. void sPrinfWithLeftZeroes(int8 dato, char* cadena){
  6.  
  7.    int8 i;
  8.    sprintf(cadena,"%3u",dato); tras esta instrucción cadena contiene "   5":
  9.    for(i=0;i<3;i++){
  10.       if(cadena[i]==0x20) cadena[i]=0x30;
  11.    }
  12.    // aquí cadena tiene "005";
  13. }
  14.  
  15. //
  16. // Desde main() lo llamamos y vemos los resultados comparándolos sin y con el formato
  17. //
  18.  
  19. void main(void){
  20.  
  21.    char s[3];                    // pongo 3 para que la cadena sea de tres dígitos más la terminación estándar de 0x00
  22.    int8 num=5;                   // valor 5, por ejemplo
  23.  
  24.    printf("%u/r/n",numero)       // Esto saca 5{0x0d}{0x0a}
  25.    sPrinfWithLeftZeroes(num,&s); // Esto convierte 5 a 005
  26.    printf("%s/r/n",s)            // Esto saca 005{0x0d}{0x0a}
  27.  
  28.    while(true);
  29.  
  30. }