TODOPIC

Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: PabloPic en 18 de Abril de 2014, 21:28:32

Título: Convertir variables char a int16
Publicado por: PabloPic en 18 de Abril de 2014, 21:28:32
Hola muy buen dia, he estado probando un codigo que realmente no me sale, estoy intentando transformar una variable string (ejemplo char valor[5];) a una variable entera tipo int16 duty, se que la funcion es duty=atol(valor); pero no me sale nada. Ayuda porfavor se los agradecere  :-/  :-/ , os dejo el codigo:

#include <18f4550.h>
#fuses INTRC,PUT,BROWNOUT
#use delay(INTERNAL=4M)
#use RS232 (BAUD=9600, XMIT=PIN_C6, RCV=PIN_C7, PARITY=N,BITS=8)
#include <lcd.c>
#include <stdlib.h>
char valor[9];
int16 duty;

#INT_RDA
void serial_isr()
{
   fgets(valor);
   delay_ms(50);
   puts(valor);
   
   duty = atol(valor);
   printf(lcd_putc,"%Lu",duty);
}


void main()
{
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_RDA);
   set_tris_c(0x00);
   
   //CONFIGURACION PARA EL PWM, FRECUENCIA DE MOTOR A 1 KHz
   setup_timer_2(T2_DIV_BY_16,255,1);
   setup_ccp1(CCP_PWM);
   set_pwm1_duty(0);
   
   //INICIAR PRESENTACION
   lcd_init();
   lcd_gotoxy(3,1);
   printf(lcd_putc,"PIC18F4550");
   lcd_gotoxy(1,2);
   printf(lcd_putc,"PWM: PIC_LabVIEW");
   delay_ms(2000);
   printf(lcd_putc,"\f");
   lcd_gotoxy(1,1);
   printf(lcd_putc,"VALOR DEL DUTY:");
   lcd_gotoxy(1,2);

   while(TRUE)
   {
   }
}
Título: Re: Convertir variables char a int16
Publicado por: AngelGris en 18 de Abril de 2014, 21:37:43
  No estoy familiarizado con CCS, por lo cual tal vez esté equivocado en algunos puntos.

  Imagino que la función fgets, te devolverá un string terminado en el decimal (13) -que, creo, es el caracter de retorno de carro-.

  Ahora bien, por lo poco que la he utilizado, la función atoi o atol necesita una variable string terminada en 0 -caracter nulo- y tal vez allí es donde esté el error.
Título: Re: Convertir variables char a int16
Publicado por: MerLiNz en 18 de Abril de 2014, 21:40:04
es atoi no atol, la 2ª es para long, prueba a ver si te va
Título: Re: Convertir variables char a int16
Publicado por: PabloPic en 18 de Abril de 2014, 21:48:22
Pues no MerLiNz le puse atoi pero no me sale nada jeje. Mmm el valor que recibo desde la PC al PIC va de 0 a 1024, por lo que supongo yo es string en este caso valor, cambiaria a char valor[5]; ? jeje debido a que solo recibo caracteres de hasta 4 digitos y creo que el ultimo se completa con un caracter "NULL", aun asi no funciona jeje rayos  :5]
Título: Re: Convertir variables char a int16
Publicado por: AngelGris en 18 de Abril de 2014, 21:54:21
  Para ir descartando posibles problemas, yo crearía una variable char pero ya asignándole un valor e intentaría emplear atoi o atol en dicha variable en lugar de aplicarla a algo recibido desde el UART.

Código: C
  1. char palabra[10] = "1256";

 por ejemplo.
Título: Re: Convertir variables char a int16
Publicado por: PabloPic en 18 de Abril de 2014, 22:09:55
Muy bien AngelGris probe como me dijiste:

char valor[10]= "1024";
int16 duty;

despues viene la conversión:

duty=atol(valor);
printf(lcd_putc,"%Lu",duty);

En la pantalla display 16x2 me sale el valor convertido a una int16 solo me funciona con atol, probe con atoi y me salian puros ceros.
Por el momento se que atol funciona para int16, ahora como lo convierto y recibo ya con la UART

Título: Re: Convertir variables char a int16
Publicado por: AngelGris en 18 de Abril de 2014, 22:15:23
Muy bien AngelGris probe como me dijiste:

char valor[10]= "1024";
int16 duty;

despues viene la conversión:

duty=atol(valor);
printf(lcd_putc,"%Lu",duty);

En la pantalla display 16x2 me sale el valor convertido a una int16 solo me funciona con atol, probe con atoi y me salian puros ceros.
Por el momento se que atol funciona para int16, ahora como lo convierto y recibo ya con la UART



  Para mí el problema viene por lo que te comenté en la primer respuesta. fgets termina el string con un caracter distinto de 0 y por ello genera los inconvenientes.

  Si como indicas, sólo recibes datos de hasta 4 dígitos, puedes intentar lo siguiente antes de la conversión

Código: C
  1. valor[4] = 0;

  con ello eliminarías el caracter de retorno de carro y colocarías el caracter nulo. Para que la función atol no genere inconvenientes.
Título: Re: Convertir variables char a int16
Publicado por: PabloPic en 18 de Abril de 2014, 22:32:38
Mu bien, pues lo intente AngelGris, si recibo un numero string de 4 digitos mas un retorno de carro en total serian 5 espacios osea char valor[5]; al compilarlo me salia error, puesto que no podia insertar un valor cualsea en esa posicion del arreglo osea valor[5]=0; sigo sin llegar a algun exito. Siento que quizas deberia probar alguna logica diferente o cambiar la funcion fgets(valor) por alguna otra  :(
Título: Re: Convertir variables char a int16
Publicado por: AngelGris en 18 de Abril de 2014, 22:49:22
  Si tu defines de la siguiente forma

Código: C
  1. char valor[9];

indicas que valor tiene 9 espacios, pero el índice va desde 0 a 8. Por ello el quinto caracter va a tener como índice el número 4.

  No cambies tu definición de la variable, simplemente intenta escribir en el índice número 4 de la misma. Tal vez CCS no te permita hacerlo, no lo sé.
Título: Re: Convertir variables char a int16
Publicado por: PabloPic en 19 de Abril de 2014, 11:18:06
Bien, pues buscando y hallando otras maneras para resolver este problema, en alguna página y en algún codigo encontre que para trasformarla simplemente hacia una operacion de una variable tipo char y una entera, ¿Quien sabe porque?, simplemente no lo sé, solo se que funciona, pueden probarlo. Mas o menos quedaría así:

char valor;
int16 duty;

#INT_RDA
void serial_isr()
{
   valor=getchar();
   delay_ms(50);
   duty=(valor-48);

   printf(lcd_putc,"%Lu",duty);
Título: Re: Convertir variables char a int16
Publicado por: RALF2 en 19 de Abril de 2014, 11:32:40
Yo lo haria usando casting   :mrgreen:
Asi:

Citar
char caract = 'Z';
   int16 Num;
  
   Num = (int16)caract;
   printf("%lu ",Num);

Nota:
 El caracter 'Z' es igual a 90 (en decimal)

Saludos
Título: Re: Convertir variables char a int16
Publicado por: AngelGris en 19 de Abril de 2014, 12:02:08
Bien, pues buscando y hallando otras maneras para resolver este problema, en alguna página y en algún codigo encontre que para trasformarla simplemente hacia una operacion de una variable tipo char y una entera, ¿Quien sabe porque?, simplemente no lo sé, solo se que funciona, pueden probarlo. Mas o menos quedaría así:

char valor;
int16 duty;

#INT_RDA
void serial_isr()
{
   valor=getchar();
   delay_ms(50);
   duty=(valor-48);

   printf(lcd_putc,"%Lu",duty);

  En este caso simplemente conviertes 1 dígito , no 4 dígitos como tú necesitas. Y funciona por como es el código ascii.

código ascii                   número

48                                    0
49                                    1
50                                    2

y así sucesivamente. Por lo tanto si le restas 48 al valor del código ascii obtienes el valor decimal que te interesa.
Título: Re: Convertir variables char a int16
Publicado por: RALF2 en 19 de Abril de 2014, 12:26:50
Asi mismo Angelgris, solo que el necesita, segun el codigo que coloco mas arriba, el resultado en un long asi que usando el casting mata dos pajaros de un solo tiro   :D
Título: Re: Convertir variables char a int16
Publicado por: AngelGris en 19 de Abril de 2014, 12:45:31
Asi mismo Angelgris, solo que el necesita, segun el codigo que coloco mas arriba, el resultado en un long asi que usando el casting mata dos pajaros de un solo tiro   :D

  Si claro, mi respuesta fue porque a él parecía asombrarle que funcione el último código que mostró.
Título: Re: Convertir variables char a int16
Publicado por: PabloPic en 19 de Abril de 2014, 12:52:55
Lo que no entiendo es que segun RALF2, emplenado casting quedaria de esta manera:

char valor;
int16 duty;

#INT_RDA
void serial_isr()
{
   valor=getchar();
   duty=(int16)valor;
   printf("%Lu,valor);
}

Pero no me funciona, o ¿Esta mal el codigo?
Título: Re: Convertir variables char a int16
Publicado por: RALF2 en 19 de Abril de 2014, 13:38:29
Una pregunta las variables valor y duty son globales? o estan dentro de alguna funcion? que no te funciona?
Título: Re: Convertir variables char a int16
Publicado por: PabloPic en 19 de Abril de 2014, 13:46:47
Son variables globales que estan fuera de la funcion void main() y las de interrupciones seriales, no me funciona el casting al recibir datos seriales y convertirlos como me dijiste  :(
Título: Re: Convertir variables char a int16
Publicado por: RALF2 en 19 de Abril de 2014, 14:20:37
Yo lo probe sin la interrupcion como te lo pase y me funciona   :mrgreen:, lo estas probando a nivel de simulacion, con el proteus? que te aparece en la pantalla?
Título: Re: Convertir variables char a int16
Publicado por: PabloPic en 19 de Abril de 2014, 14:42:20
Bien a mi tambien me funciono sin interrupciones osea:

   while(TRUE)
   {
      valor=getchar();
      delay_ms(10);
      duty=(int16)valor;
      printf("%Lu",duty);
      printf(lcd_putc,"%Lu",duty);
   }

Pero veo que me lo muestra en codigo ASCII, osea el valor decimal por ejemplo 48 = 1
Pero lo que quiero es que obtenga de numero de 4 digitos tipo char y se transforme en entero
Título: Re: Convertir variables char a int16
Publicado por: RALF2 en 19 de Abril de 2014, 14:52:40
No entiendo bien lo que deseas hacer.
A ver quieres introducir solo numeros de 4 digitos en ascii y luego convertirlos a enteros?
Lo que te pase convierte un caracteres o numero, solo uno, en un int16.

Explicame un poco mejor.
Título: Re: Convertir variables char a int16
Publicado por: PabloPic en 19 de Abril de 2014, 15:17:02
Si, mira, exactamente quiero variar el PWM del PIC desde la PC, mando valores de 0 a 1024 osea la resolución máxima de salida del CCP1 a 10 bits, para ello mando
un numero tipo char de la PC al PIC osea el "Duty cycle", por lo que necesito convertir ese numero de 1, 2, 3 o 4 cifras a un entero largo para ponerlo en la instruccion:

 set_pwm1_duty(duty);  //Donde duty es una variable global int16

Título: Re: Convertir variables char a int16
Publicado por: PabloPic en 19 de Abril de 2014, 15:20:59
Si, mira, exactamente quiero variar el PWM del PIC desde la PC, mando valores de 0 a 1024 osea la resolución máxima de salida del CCP1 a 10 bits, para ello mando
un numero tipo char de la PC al PIC osea el "Duty cycle", por lo que necesito convertir ese numero de 1, 2, 3 o 4 cifras a un entero largo para ponerlo en la instruccion:

 set_pwm1_duty(duty);  //Donde duty es una variable global int16
Título: Re: Convertir variables char a int16
Publicado por: AngelGris en 19 de Abril de 2014, 15:31:52
  Antes que nada, deberíamos saber como estas enviando los datos desde el PC. Si los mandas desde una terminal (tú colocas un número y presionas "enter"), seguramente terminarán con el caracter de retorno de carro (decimal 13). Ahora, si los envías apenas presionas un tecla o desde un programa propio el asunto cambia.

  Para el primer caso, puedes utilizar la función fgets -que creo espera hasta el caracter de retorno de carro- (deberías buscar en el manual del compilador) y eliminar el último caracter como te he mencionado.
  Para el segundo caso, puedes implementar tu mismo el armado de tu "palabra" contando la cantidad de datos recibidos y almacenándolos en posiciones sucesivas de un array.

  Luego conviertes la palabra completa con atoi o atol según sea necesario.
Título: Re: Convertir variables char a int16
Publicado por: RALF2 en 19 de Abril de 2014, 15:34:21
ok entonces muy sencillo   :shock:
Primero utiliza gets()  para capturar el string de los datos que vas a enviar.
Luego utiliza atol para convertir el string que contiene el numero en un int16 y listo!   :mrgreen:

En resumen como dice angelGris.

Saludos
Título: Re: Convertir variables char a int16
Publicado por: PabloPic en 19 de Abril de 2014, 15:54:06
Por su puesto, y estas en lo cierto AngelGris, mi idea por un momento fue esa: Los datos los envío desde un programa llamado "LabVIEW", en el que de un control numérico, lo convertía a caracter y lo desconcatenaba, enviando el primer digito de la PC al PIC y guardandoló como dices en un arreglo tipo char, hasta juntar los cuatro digitos correspondientes al valor maximo en este caso 1024 y convirtiendolos en entero con atol, pero note un problema, al haber 3, 2 o un digito, se me recorren algunos numeros y la conversion no sale correcta, debido a que cuando por ejemplo cuando tengo el numero 12 las demas posiciones estan en blanco y como que no me lo realiza bien. Por lo que estoy intentando resolver ese problema pero aun no le doy jeje. Gracias por sus ayudas  :D Saludos
Título: Re: Convertir variables char a int16
Publicado por: RALF2 en 19 de Abril de 2014, 16:31:06
En tu programa de labview despues de enviar los caracters envias el \r (carrier return) para que el gets() detecte el final del string y luego con atol lo conviertes en int16   :mrgreen:

Podrias probar en principio con el hiperterminal o similar para que veas que funciona   :mrgreen:

Saludos
Título: Re: Convertir variables char a int16
Publicado por: PabloPic en 28 de Abril de 2014, 18:04:12
Pues por ahora tengo esto:   :-/


char valor1,valor2,valor3,valor4;
int8 dig1,dig2,dig3,dig4;
int16 duty[4];

#INT_RDA
void serial_isr()
{
   valor1=getchar();
   dig1=valor1-48;
   duty[0]=dig1;
   lcd_gotoxy(1,2);
   printf(lcd_putc,"%u",dig1);
   delay_ms(10);
   
   valor2=getchar();
   dig2=valor2-48;
   duty[1]=dig2;
   lcd_gotoxy(3,2);
   printf(lcd_putc,"%u",dig2);
   delay_ms(10);
   
   valor3=getchar();
   dig3=valor3-48;
   duty[2]=dig3;
   lcd_gotoxy(5,2);
   printf(lcd_putc,"%u",dig3);
   delay_ms(10);
   
   valor4=getchar();
   dig4=valor4-48;
   duty[3]=dig4;
   lcd_gotoxy(7,2);
   printf(lcd_putc,"%u",dig4);
   delay_ms(10);
}

Almaceno cada digito que envio de la PC al pic, numero por numero, lo convierto de string a int y lo almaceno en posiciones sucesivas de un array en este caso duty[4] que es un arreglo tipo entero. Mi problema ahora es jeje como convierto ese array tipo entero en un numero comun jeje como 1024 o 3