Algoritmo String-Entero







    Buscando por internet no encontré mucho acerca de como separar datos numéricos de un string. Por ello, he decidido publicar esta entrada, con el objetivo de aportar un poco más acerca de este tema.

    A la hora de realizar proyectos en los que es necesario enviar o recibir datos, los strings son muy útiles, ya que podemos enviar varios datos seguidos de una manera muy sencilla. Para enviar un string en CCS a través de RS232, podemos utilizar la función printf(). Utilizando los formatos, podemos enviar los datos a través del string según sea necesario. Ej:

    [...]
    #use rs232(.....)
    [...]
    int8 var=234;
    [...]
    printf("Dato: %u\0",var);
    [...]

    Con este código, se enviará un string con terminación NULL de la siguiente manera:   Dato: 234.

    Los formatos principales para printf() son los siguientes:

               %c                                  caracter
               %u                                  entero sin signo
               %d                                  entero con signo
               %lu                                 entero largo sin signo
               %ld                                 entero largo con signo
               %x                                  hexadecimal
               %lx                                 hexadecimal largo
               %f                                   flotante con decimal truncado
               %g                                  flotante con decimal redondeado
               %e                                  flotante en notación científica



    Pero... ¿Y para recibir un string y saber interpretarlo? Pues bien, utilizaremos una función para recoger el string y guardarlo en un array para posteriormente extraer el dato que nos interese.

    Para poder guardar un string en un array, es necesario que el array tenga al menos una posición libre para guardar el carácter NULL, es decir, si la cadena tiene una longitud de 6 caracteres, será necesario guardarla en un array que tenga 7 posiciones. Para recoger el string del RS232 en un array, utilizaremos la función gets(). Veamos el siguiente ejemplo:


    <String enviado: "Hola Mundo">

    [...]
    #use rs232(.....)
    [...]
    char arraystr[11];
    [...]
    gets(arraystr);
    [...]

    Como se puede observar, la cadena de texto "Hola Mundo" está formada por 10 caracteres: las cuatro letras de "Hola", el espacio y las cinco letras de "Mundo". Por este motivo tenemos que definir un array con 11 posiciones, con el objetivo de que quede una libre para el carácter NULL.

   Una vez hemos guardado el string en el array, ya podemos manejarlo de manera sencilla. Al referirnos a la posición 0 del array, éste nos devolverá una 'H'; al referirnos a la posición 1, nos devolverá una 'o'; posición 2, 'l'; etc. Pero a nosotros nos interesa extraer un dato numérico, por lo tanto aplicaremos un algoritmo para realizar esta acción.

    Tomaremos el siguiente string, del cual vamos a extraer el número 468 y guardarlo en una variable definida como int16 (entero de 16 bits)

    <String enviado: "Dato: 468">

    [...]
    #use rs232(.....)
    [...]
    int8 i,cen,dec,und;
    int16 dato;
    const char tablaascii[10]={'0','1','2','3','4','5','6','7','8','9'};
    char strdata[10];
    [...]
    gets(strdata);
    for(i=0;i<10;i++){
        if(strdata[6]==tablaascii[i]) cen=i;
        if(strdata[7]==tablaascii[i]) dec=i;
        if(strdata[8]==tablaascii[i]) und=i;
    }
    dato=(cen*100)+(dec*10)+und;
    [...]

    El algoritmo guarda en tres variables las cifras de las centenas, decenas y unidades del número, utilizando un bucle for(). Al referirnos a la posición 6 del array strdata, nos devolverá un '4', pero ojo, esto no es número, se trata de un carácter; por ello lo compararemos con el otro array tablaascii, el cual nos devuelve el carácter numérico de la posición que le especifiquemos; utilizamos para ello unos condicionales if(). De esta manera, si se igualan el carácter de la posición 6 del array strdata con la posición 4 del array tablaascii, se guardará en la variable cen la posición a la que se ha referido, es decir, la posición 4; quedando guardado como dato numérico. 

    Igualmente se hace con las decenas y las unidades; i toma todos los valores entre 0 y 9, definiendo así las cifras de las unidades, decenas y centenas. 

    Finalmente se unen las tres cifras en un único número de 16 bits: dato=(cen*100)+(dec*10)+und;

   Este algoritmo puede utilizarse para extraer varios datos numéricos que enviemos a través de un string sean de la longitud que sean.

Programar PICs







      En este apartado veremos como programar PICs mediante un ordenador que disponga de puerto serie DB9. Necesitaremos realizar un sencillo Hardware para poder programar el PIC, así como un Software específico para poder grabar el código hexadecimal en el microcontrolador.

      Mediante programas de entorno y compilación podremos realizar nuestros códigos usando lenguajes de programación de alto nivel (como C) o de bajo nivel (como ensamblador). Un buen compilador de lenguaje C es CCS. Éste nos permite generar un código hexadecimal a partir de lenguaje C orientado a microcontroladores. Es un Software gratuito y se pueden encontrar numerosos manuales acerca de este famoso lenguaje de programación.

      Una vez tenemos el código hexadecimal, tendremos que grabarlo en el PIC. Para ello será necesario un Hardware y un Software.


HARDWARE:

       El Hardware consiste en un pequeño circuito que nos permite conectar el PIC al ordenador para poder programarlo, en este caso veremos un sencillo programador del tipo JDM.


      Circuito impreso en ARES disponible en este enlace: Layout_Download

      El puerto ICSP nos permite conectar el microcontrolador al programador. Consiste en un simple conector de 5 pines alineados y separados entre sí 0.1 pulgadas. Para poder programar un microcontrolador, podemos utilizar una placa para prototipos. Colocamos el microcontrolador y el conector separados en la placa. Utilizando 5 cables rígidos unimos los pines del microcontrolador con los respectivos pines del puerto ICSP:

            1 - Vpp    →    Vpp - MCLR/RA5 (pin 4)
            2 - Vdd    →    Vdd - (pin 14)
            3 - Vss     →    Vss  - (pin 5)
            4 - Dat     →    Dat  - PGD/RB7 (pin 13)
            5 - Clk     →     Clk  - PGC/RB6 (pin 12)





   
SOFTWARE:

      WinPic800 (Descarga: http://www.winpic800.com).

      Una vez hayamos instalado WinPic800, lo abrimos y realizaremos la configuración de Hardware. Para ello vamos a Configuración>>Hardware. Seleccionamos el Hardware JDM Programmer, seleccionamos el puerto en el que está conectado y le damos a Confirmar cambios. Después vamos a Dispositivo>>Test hardware para comprobar que todo este correcto. Saldrá una ventana con un: Hardware Ok. Una vez hayamos comprobado el Hardware, iremos a Dispositivo>>Detectar Dispositivo. Saldrá una ventana con el nombre del dispositivo que está conectado, en este caso el PIC16F628A:




      Ahora ya podremos programar los microcontroladores cargando el archivo hexadecimal en WinPic800 (Archivo>>Abrir) y programarlo en el microcontrolador (Dispositivo>>Programar Todo).