Controlar el encendido de Leds según cadena recibida por puerto serie

Buenos días a todos!
Quisiera plantearos lo que quiero conseguir: tengo unas máquinas con las que me comunico desde un pc a traves del puerto serie. lo que obtengo desde las maquinas es una de cadena de texto que contiene diversa informacion la cual extraigo con funciones sencillas en visual.basic y que posteriormente uso para otros objetivos. Hasta aquí sin problema.Lo que ahora me gustaria es utilizar ese string de salida y controlar el encendido de varios leds segun la informacion que contiene. Por ejemplo, digamos que obtengo algo \'**130***120***190***\', me gustaria ser capaz de extraer los valores de manera que una serie de leds simulen un rango entre 120 y 190 y se enciendan solo los equivalentes al 130. Obviamente quiero hacerlo sin la intervencion del PC.

Querria saber si creeis si es posible o no llevar a cabo este proyecto, antes de embarcarme en comprar material y demás. Si veis que esposible,agradecería de veras cualquier pista sobre cómo realizarlo. En mi ignorancia sobre microcontroladores se me ha ocurrido que quizá podria hacerlo con algún PIC o algo así, pero jamás he trabajado con ellos, aunque pienso que si puedo programarlo en una PC, tambien podria hacerlo en un microcontrolador investigando lo que hiciera falta.

Espero haberme medio explicado,
Muchisimas gracias de antemano!

Saludos! ...
 
Me parece que una buena solucion para ti y este proyecto es usar una placa Arduino
 
con un pic barato como el 16f716 , o el mas barato que encuentres
un max232 para comunicar el pic con el rs232 , quitarte el miedo
y programar en C como el CCS o algun compilador BASIC por que dices que sabes programar BASIC

ahora leer una cadena de caracteres con CCS no es dificil

leo la cadena con un gets(); y con atoi la convierto en entero a una variable entera
ejemplo

char cadena[10]; //mi cadena medira 10 caracteres
int numero; //mi entero

while(1)bucle infinito

{
gets(cadena); //leo la cadena con gets
numero=atoi(cadena); //igualo numero con atoi

//HAGO LO QUE TENGO QUE HACER//
//METER CODIGO AQUI//

}

facil no?
 
En primer lugar, gracias por la respuesta, Trilo-byte! No parece difícil desde luego... ¿Es posible simular eso que dices con alguna aplicación de PC para luego pasar a diseñar el circuito ya sabiendo que funcionaría?

Muchísimas gracias!
 
si con el proteus

descarga el proteus y para simularlo el programa es isis el ares hace los PCB

puedes simular todo con el proteus , hay tutoriales de como hacerlo , es cuestion de quitarse el miedo
 
Hola de nuevo!
He instalado Proteus y el CCS c compiler y he conseguido leer el puerto serie programando en c, pero solo la primera cadena que llega. El problema es que necesito "monitorizar" en todo momento la información que llega desde el ComPim de Proteus (puerto serie),el cual envia información actualizada cada 100 milisegundos. Intento actualizar la variable que la almacena dentro de un bucle infinito, mediante gets(inputData) pero no se actualiza,sino que continúa con el mismo valor que tenía al comienzo. Insertando en el simulador un terminal virtual sí vero todo lo que ocurre, pero necesito tratar esas cadenas desde el código

Siento mi ignorancia en el tema, agradezco de antemano cualquier ayuda!
 
Aquí va el código.
Conseguía obtener alguna información con el PIC18f4550, pero al cambiar al PIC16f877, Proteus no hace absolutamente nada. Si elimino las líneas de código correspondientes a la la comunicación ("gets(testInput)"), si que consigo encender del led D3 que asigno a la condición por defecto dentro de "switch". También subo una captura de pantalla con la simulación de Proteus.


Código:
#include <16f877.h>
#device adc=8
//fuses  PUT, HS, NOWDT, NOLVP, NOBROWNOUT
#FUSES XT,NOWDT, NOLVP,NOPROTECT                   //No Watch Dog Timer
#use delay(clock=20000000)
//#include <utility.c>
//#use rs232(baud=9600, bits=8, UART1, SYNC_SLAVE)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

#define use_portb_lcd true//***
#include <lcd.c>            //***

 
#int_rda
void main()
{
   lcd_init();
   printf(lcd_putc, "\f");
   delay_ms(500);
   char testInput[20];
   gets(testInput);

while(1)
   {
    printf(lcd_putc,"\n %s",testInput);
          //{
             //data = getc();
             gets(testInput);
             delay_ms(100);
             //data=inputData[1];
             switch(testInput[9]){
             //switch(data){
             case 'g':output_high(PIN_A1);
                      output_low(PIN_A2);
                      output_low(PIN_A3);
                      printf(lcd_putc,"%s","g");
             break;
             case 'y':output_low(PIN_A1);
                      output_high(PIN_A2);
                      output_low(PIN_A3);
                      printf(lcd_putc,"%s","y");
             break;
             case 'r':output_low(PIN_A1);
                      output_low(PIN_A2);
                      output_high(PIN_A3);
                      printf(lcd_putc,"%s","r");

             break;
             case 'N':output_high(PIN_A1);
                      output_high(PIN_A2);
                      output_high(PIN_A3);
                      //printf(lcd_putc,"%s","VALUING");
                      printf(lcd_putc,"\n %s","N");

             break;
              default:output_low(PIN_A1);
                      output_low(PIN_A2);
                      output_high(PIN_A3);
                      printf(lcd_putc,"%s","default");
             break;

                           }
    }
}

Por cierto, hay alguna manera de mostrar valores de variables procedentes del código ccs en proteus?? (el LCD no me funciona en este caso, con el PIC18F4550 si lo hacia)


Muchas gracias!.
(Siento las tildes, pero es que estoy escribiendo desde el extranjero)

Proteus1.jpg
 
Última edición por un moderador:
veo que esta usando la librería lcd.c entonces esta mal conectado el lcd en tu simulación
pin6(enable) va al pin rb0
pin5(r/w) pin rb2
pin4 (rs)pin rb1

bueno si has modificado la librería estaría bien entonces :)
ademas la interrupción no tiene ninguna función a realizar
 
Última edición:
Bueno, dado que el lcd me funciona para el PIC18F4550, he decidido continuar con el proyecto con el. El problema que tengo ahora es el siguiente: Consigo extraer la informacion en una cadena de caracteres "testInput", pero no soy capaz de hacer ninguna comparacion, dado que en switch, siempre me salta a la opcion "default". como puedo extraer una subcadena y pasarla a formato "double" para luego comparar con un "switch" y asi poder ejecutar cualquier accion en funcion de ese valor dado?. En codigo c++ normal podria, pero no lo consigo en ccs, ya que son diferentes funciones


Muchas gracias de nuevo!
 
Basicamente lo que obtengo es una cadena tal como "CD000000NW0.000gTW0.0000, donde los ceros pueden ser cualquier cifra. Yo necesito extraer el "0.000" después de "NW", pasarlo a double y luego encender unos leds u otros según sea ese valor, pero no sé cómo hacerlo en c para el ccs compiler, ya que las funciones que he intentado no funcionan.

Muchas gracias luis por la respuesta, el lcd sigue sin funcionar, pero por el momento necesito centrarme en mi problema principal
 
es que tu codigo esta medio raro amigo por eso tienes fallar

no se que quieres hacer exactamente , releyendo veo que quieres leer una cadena y convertirla a entero,
pero aparte metes condiciones si S , no N y asi.

hay 3 eventos S ,N y un numero 1234

el swich escoje si es S ,N y si es diferente a S y N el default es el numero

yo haria esto


char leido[10]; //leo lo que viene
int numero;

while(1)

{
gets(leido);

switch(leido[0]) //leo el primer char
{
case 'N':
//codigo no
break;

case 'S':
//codigo si
break;

default:

numero=atoi(leido);
//imprime numero

break;

}



}


no se si te sirva
 
Por supuesto que me sirve, Trilo-Byte!. La instruccion "switch" que he incluido era solo para comprobar que detectaba el carácter y entraba en en la condición adecuada, ¡pero siempre se me va a "default"!, es como si ignorara todas las demás condiciones del switch ¿tendrá algo que ver con codificación de caracteres?. Mañana comprobaré tu código, pero ¿cómo podría extraer la cadena "0.000" desde la entrada original "CD00000NW0.000gTH0000?, ya que esa es la parte fundamental que contiene el valor a convertir a entero mediante "atoi"

Muchas gracias por tu ayuda desinteresada!
 
o_O desinteresada no es que mi mente vuela tengo muchos problemas en el trabajo hay maquinas que necesitan examinarse y mi aprendiz que quedara en mi lugar.

bueno digamos que tengo CD00000NW0.000gTH0000 que tiene 21 letras y quiero obtener 0.000

digo si siempre conservare el formato X.XXX que tiene 5 letras el punto cuenta
ejemplo 3.141 puedo sacarlo facilmente


char contador1=0;
char contador2=0;
char numero[6];
char cadena[22]="CD00000NW0.000gTH0000";

float flotante;

// hacemos un conteo con el numer de letras de la cadena 21 letras

for(contador1=0;contador1!=21; contador1++)
{
//cuando llega a 9 que es donde esta 0.000 empieza a copiar en la cadena
if(contador1>=9)
{
//como el numero 0.000 tiene 5 elementos despues de el 6 ya no copiara
if(contador2<=5)
{
numero[contador2]=cadena[contador1]
}
contador2++;
}
}

flotante=atof(numero);


bueno supongo que debe funcionar :rolleyes: pero si funciona me rife :LOL:
 
Bueno, he modificado el código y he conseguido que funcione. Uno de los fallos que he tenido es que al extraer el array debía "cerrarlo" con un 0 al final, pero ya funciona.

Llegado a este punto positivo en que obtengo lo que quería, ahora me surgen varias dudas:

- El circuito con el que funciona es el utilizando el PIC18F4550 (Imagen 1), pero al intentar realizar exactamente lo mismo con el PIC16F877A (que me imagino sera mas barato) no funciona!. He creado una versión muy básica del programa para intentar buscar el problema, pero tampoco funciona (en la imagen 2 muestro una captura del registro de errores), aunque en el Virtual Terminal si que puedo ver la información que viene por el puerto serie.

- En la versión que si me funciona (con el PIC18F4550), si paro la simulación y la reinicio en Proteus, el código deja de funcionar y para resolverlo tengo que reconectar el cable de red, volver a crear el archivo .hex e iniciar la simulación de nuevo ¿alguna pista de por que esto ocurre? Lo que no quiero es que cuando construya el PCB final me ocurra algo similar

- Finalmente, Trilo-Bite me decías al principio que debería usar un max232 para conectar el PIC con el puerto, pero no me ha hecho falta para la simulación. ¿lo necesitare para construir el circuito real? ¿no podría conectar los cables directamente a los pines del pic, tal y como hago en la simulación?

Y siento tantas preguntas, pero ya que medio he conseguido encarrilar el proyecto, me gustaría terminarlo con una mínima calidad.

Muchísimas gracias por todo, especialmente a Trilo-byte. Cualquier cosa que pueda ayudar, estaría encantado!

Saludos!

-



Olvidé adjuntar las imágenes.

Este el código "básico" que no consigo hacer funcionar con el PIC16F877A:
Código:
#include <16F877a.h>
#device adc=8
#FUSES XT,NOWDT, NOLVP,NOPROTECT                   //No Watch Dog Timer
//#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#define use_portb_lcd true
#include <lcd.c>

#include <stdio.h>
#include <stdlib.h>

#include <string.h>

/*
 * 
 */
void main() {

    printf(lcd_putc,"%s","hello!");
    char cadena[30];

    lcd_init();                         //Init LCD Display

    delay_ms(500);

    gets(cadena);                       //Read the incoming data
    
    printf(lcd_putc, "\f");
    printf(lcd_putc,"%s","test:!");
    printf(lcd_putc,"\n%s",cadena);     //show the string in the LCD


    output_high(PIN_A1);                //turn on a LED to discard any error in the code above


    while(1) {
    }
}
 

Adjuntos

  • 3_ErrorLog.JPG
    3_ErrorLog.JPG
    38.9 KB · Visitas: 14
  • 2_ProteusSimPIC16F877A.jpg
    2_ProteusSimPIC16F877A.jpg
    153.9 KB · Visitas: 18
  • 1_ProteusSimPIC18F4550.jpg
    1_ProteusSimPIC18F4550.jpg
    151.8 KB · Visitas: 12
Última edición por un moderador:
Dejaste tu programa en un bucle sin hacer nada deberías leer los datos que llegan.
Que quieres hacer exactamente recibir un número binario y prender una cierta cantidad de led.

El max232 es el mas utilizado ya que puesto que los niveles de voltaje en el pic varían desde 0 hasta 5 voltios, y el puerto serie del PC funciona desde +12V hasta -12V .El max232 cambia los niveles de voltaje que requiere la pc .
 
Muchas gracias Luis,

El motivo de no hacer nada en el bucle es solo porque es un codigo de prueba, de manera que para el test solo leeria el dato que viene justo en el momento de ejecutar el programa, pero parece ser que se produce un error al leer la cadena de entrada "gets(cadena)", ya que ni siquiera se llega a encender el led. En cualquier caso, si mi programa funciona para el PIC18F4550 podria usar ese y olvidarme del 16f877a no?

Con respecto al max232, realmente el PIC va a recibir la informacion procedente de una balanza, sin intervencion alguna de un PC ¿aun asi seria necesario?. Esto entra ya dentro de lo que es el montaje final, del que seguro que me surgiran mil dudas :S
 
aa pues el max232 es totalmente necesario en una comunicacion RS232
en el proteus funciona sin problemas por que es una SIMULACION no es real:unsure:

ahora veo que estas usando el PUERTO B en la LCD pero no imprime
eso es un BUG del CCS "el CCS luego da dolores de cabeza por sus famosos bugs :("

pero veo que pusiste esto:

#define use_portb_lcd true

pero luego el CCS no lo respeta

hay que poner una directiva diferente por ejemplo yo queria poner mi LCD en el puerto D
y tube que usar una directiva diferente
como:

#define LCD_DATA_PORT getenv("SFR:pORTD")

un ejemplo de como escribir es el siguiente : ;)

#include <16f877.h>

#fuses XT,NOWDT
#use delay(clock=4M)
#define LCD_DATA_PORT getenv("SFR:pORTD")
#include <lcd.c>



otra cosa tu codigo deberia ir asi



void main() {

lcd_init(); //Init LCD Display
char cadena[30];


printf(lcd_putc,"%s","hello!");

delay_ms(500);//retardo para mostrar mensaje








/* DEBE IR DENTRO DEL BUCLE PARA LEER REPETIDAMENTE LO QUE LLEGA DEL PUERTO*/


while(1) {

gets(cadena); //Read the incoming data

printf(lcd_putc, "\f");
printf(lcd_putc,"%s","test:!");
printf(lcd_putc,"\n%s",cadena); //show the string in the LCD


output_high(PIN_A1); //turn on a LED to discard any error in the code above
delay_ms(100);



}


}
 
Última edición:
Hola:

Te muestro algunos ejemplos del PIC16F886 para el puerto COM.

Ejemplo 8.1
Código:
/*
El módulo USART. 
Transmisión asíncrona

El módulo USART de los dispositivos PIC16F87X incorpora el hardware necesario para implemen-
tar comunicación serie asíncrona full-duplex o sincrona half-duplex. En este último caso el
USART se puede comportar como Master o Slave.

El ejemplo transmite una trama cada segundo con el carácter ASCII de la letra A. */
    
#include <16f886.h>

/* Ajusta los valores de las palabras de configuración durante el ensamblado.Los bits no empleados
adquieren el valor por defecto.Estos y otros valores se pueden modificar según las necesidades */

#fuses     NOLVP,PUT,NOWDT,EC_IO,NOFCMEN,NOBROWNOUT    //Palabra 1 de configuración
#fuses    NOWRT,BORV40                                //Palabra 2 de configuración

/* Con estas directivas las funciones "input" y "output_bit" no reprograman
el pin de la puerta cada vez que son utilizadas. Si no se indica el
modo fast_io se asume por defecto standard_io el cual reprograma el pin
siempre antes de ser utilizadas estas funciones. */

#use fast_io (C)
#use delay(clock=4000000)

//Habilita las funciones RS232, velocidad a 9600 baudios

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
    
main()
{      
    SETUP_ADC_PORTS(NO_ANALOGS);    //Puerta A y B Digitales
    set_tris_c(0b10111111);            //RC7/Rx entrada, RC6/Tx salida
    
    while(1)
    {    
        putc('A');                    //Transmite el caracter
        delay_ms(1000);                //Temporiza 1 segundo
    }
}
Ejemplo 8.2
Código:
/*El módulo USART. 
Recepción asíncrona. 

El módulo USART de los dispositivos PIC16F87X incorpora el hardware necesario para implemen-
tar comunicación serie asíncrona full-duplex o sincrona half-duplex. En este último caso el
USART se puede comportar como Master o Slave.

En el ejemplo se provoca una interrupción cada vez que se recibe un carácter vía serie. El
programa de tratamiento visualiza, sobre los leds del laboratorio conectados a la Puerta B,
el código binario del carácter recibido. Igualmente retransmite el carácter recibido, a 
modo de ECO. */
    
#include <16f886.h>

/* Ajusta los valores de las palabras de configuración durante el ensamblado.Los bits no empleados
adquieren el valor por defecto.Estos y otros valores se pueden modificar según las necesidades */

#fuses     NOLVP,PUT,NOWDT,EC_IO,NOFCMEN,NOBROWNOUT    //Palabra 1 de configuración
#fuses    NOWRT,BORV40                                //Palabra 2 de configuración

/* Con estas directivas las funciones "input" y "output_bit" no reprograman
el pin de la puerta cada vez que son utilizadas. Si no se indica el
modo fast_io se asume por defecto standard_io el cual reprograma el pin
siempre antes de ser utilizadas estas funciones. */

#use fast_io (B)
#use fast_io (C)
#use delay(clock=4000000)

//Habilita las funciones RS232, velocidad a 9600 baudios

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#int_rda            //Vector de interrupción al recibir por el UART

//Función de tratamiento de la interrupción al recibir

tratamiento()
{    
    int    dato;                        //Variable para almacenar el dato recibido
    dato=getc();                    //Lee el dato recibido
    output_b(dato);                    //Lo saca por la puerta B
    putc(dato);                        //Lo transmite vía RS232    
}    
    
main()
{      
    SETUP_ADC_PORTS(NO_ANALOGS);    //Puerta A y B Digitales
    output_b(0x00);                    //Borra las salidas
    set_tris_b(0x00);                //Puerta B salida
    set_tris_c(0b10111111);            //RC7/Rx entrada, RC6/Tx salida
    enable_interrupts(INT_RDA);        //Activa interrupción en la recepción
    enable_interrupts(global);        //Habilita interrupciones
    
    while(1)
    {    

    }
}
Ejemplo 8.3
Código:
/* El módulo EUSART. Auto detección de baudios

El módulo EUSART de los dispositivos PIC18 soporta la auto detección automática de los baudios
del transmisor al que está conectado. Este ejemplo empieza tratando de sincronizar los baudios
y a continuación si limita a retransmitir, a modo de eco, los caracteres que se van recibiendo */

#include <16f886.h>

/* Ajusta los valores de las palabras de configuración durante el ensamblado.Los bits no empleados
adquieren el valor por defecto.Estos y otros valores se pueden modificar según las necesidades */

#fuses     NOLVP,PUT,NOWDT,EC_IO,NOFCMEN,NOBROWNOUT    //Palabra 1 de configuración
#fuses    NOWRT,BORV40                                //Palabra 2 de configuración

/* Con estas directivas las funciones "input" y "output_bit" no reprograman
el pin de la puerta cada vez que son utilizadas. Si no se indica el
modo fast_io se asume por defecto standard_io el cual reprograma el pin
siempre antes de ser utilizadas estas funciones. */

#use fast_io (B)
#use fast_io (C)
#use delay(clock=4000000)            //Frecuencia de trabajo

#byte BAUDCTL= 0x187                //Registro de control de baudios

//Habilita las funciones RS232, a alta velocidad y generador de baudios de 16 bits

#use rs232(baud=57600,xmit=PIN_C6, rcv=PIN_C7)

//Función de tratamiento de la interrupción al recibir

#int_rda                            //Vector de interrupción al recibir por el UART
tratamiento()
{    
    int    dato;                        //Variable para almacena el dato recibido
    dato=getc();                    //Lee el dato recibido
    output_b(dato);                    //Lo saca por la puerta B
    putc(dato);                        //Lo retransmite    
}    

main()
{      
    SETUP_ADC_PORTS(NO_ANALOGS);    //Puerta A y B Digitales
    output_b(0x00);                    //Borra las salidas
    set_tris_b(0x00);                //Puerta B salida
    set_tris_c(0b10111111);            //RC6/TxD salida de datos y RC7/RxD entrada del EUSART    

/* Esta rutina trata de sincronizar de forma automática los baudios del EUSART con el del 
transmisor al que está conectado. Para ello espera a recibir el carácter 0x55 ("U")como 1er. 
carácter. De no ser así, el ajuste de baudios es totalmente incorrecto */

    bit_set(BAUDCTL,0);
    while(bit_test(BAUDCTL,0)==1);
    getc();

//Sincronismo realizado, activar transmisor e interrupciones    

    enable_interrupts(INT_RDA);        //Activa interrupción en la recepción
    enable_interrupts(global);        //Habilita interrupciones

    while(1)
    {    
    }
}
Ejemplo 8.4
Código:
/*
El módulo EUSART. Auto detección de baudios. Transmitiendo mensajes

El módulo EUSART de los dispositivos PIC18 soporta la auto detección automática de los baudios
del transmisor al que está conectado. Este ejemplo empieza tratando de sincronizar los baudios
y a continuación transmite una serie de mensajes almacenados en la memoria de programa */

#include <16f886.h>

/* Ajusta los valores de las palabras de configuración durante el ensamblado.Los bits no empleados
adquieren el valor por defecto.Estos y otros valores se pueden modificar según las necesidades */

#fuses     NOLVP,PUT,NOWDT,EC_IO,NOFCMEN,NOBROWNOUT    //Palabra 1 de configuración
#fuses    NOWRT,BORV40                                //Palabra 2 de configuración

/* Con estas directivas las funciones "input" y "output_bit" no reprograman
el pin de la puerta cada vez que son utilizadas. Si no se indica el
modo fast_io se asume por defecto standard_io el cual reprograma el pin
siempre antes de ser utilizadas estas funciones. */

#use fast_io (B)
#use fast_io (C)
#use delay(clock=4000000)            //Frecuencia de trabajo

#byte BAUDCTL= 0x187                //Registro de control de baudios

//Habilita las funciones RS232, a alta velocidad y generador de baudios de 16 bits

#use rs232(baud=57600,xmit=PIN_C6, rcv=PIN_C7)

//Almacena en la memoria de programa todos los caracteres de las distinas cadenas o mensajes.

const char Mens_0[3][40]={    "Se ha producido la sincronizacion.   ",
                            "Ahora se transmiten estos mensajes   ",
                            "(c) Mikel Etxebarria (Orozko-Bizkaia)"};

int x;
int y;

main()
{      
    SETUP_ADC_PORTS(NO_ANALOGS);    //Puerta A y B Digitales
    set_tris_c(0b10111111);            //RC6/TxD salida de datos y RC7/RxD entrada del EUSART    

/* Esta rutina trata de sincronizar de forma automática los baudios del EUSART con el del 
transmisor al que está conectado. Para ello espera a recibir el carácter 0x55 ("U")como 1er. 
carácter. De no ser así, el ajuste de baudios es totalmente incorrecto */

    bit_set(BAUDCTL,0);
    while(bit_test(BAUDCTL,0)==1);
    getc();

//Sincronismo realizado, mandar CR y avance de línea inicialmente
    putc(0x0d);putc(0x0a);    //Transmite CR y avance de línea    

    while(1)
    {
        for(y=0;y<3;++y)
            {
            for (x=0;x<40;++x)        
                putc(Mens_0[y][x]);    //Transmite un mensaje
                
            putc(0x0d);putc(0x0a);    //Transmite CR y avance de línea            
            delay_ms(1000);            //Temporiza 1 seg.
            }                        //Siguiente mensaje
        putc(0x0a);                    //Transmite avance de línea
    }
}
Ejemplo 8.5
Código:
/* El módulo EUSART. Monitorización remota

Este ejemplo transmite, previa conversión a ASCII, el estado de las líneas de entrada 
RA7:RA0 a modo de monitorización */

#include <16f886.h>

/* Ajusta los valores de las palabras de configuración durante el ensamblado.Los bits no empleados
adquieren el valor por defecto.Estos y otros valores se pueden modificar según las necesidades */

#fuses     NOLVP,PUT,NOWDT,EC_IO,NOFCMEN,NOBROWNOUT    //Palabra 1 de configuración
#fuses    NOWRT,BORV40                                //Palabra 2 de configuración

/* Con estas directivas las funciones "input" y "output_bit" no reprograman
el pin de la puerta cada vez que son utilizadas. Si no se indica el
modo fast_io se asume por defecto standard_io el cual reprograma el pin
siempre antes de ser utilizadas estas funciones. */

#use fast_io (A)
#use fast_io (C)
#use delay(clock=4000000)            //Frecuencia de trabajo

//Habilita las funciones RS232, velocidad a 9600 baudios

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#byte PORTA =0x05                    //Dirección de la puerta A

main()
{  
    signed int Contador;

    SETUP_ADC_PORTS(NO_ANALOGS);                        //Puerta A y B Digitales
    set_tris_a(0b11111111);                                //Puerta A entrada    
    set_tris_c(0b10111111);                                //RC6/TxD salida de datos y RC7/RxD entrada del EUSART    
    putc('\r');                                            //Transmite CR
    putc('\n');                                            //Transmite avance de línea

    while(1)
    {
        for (Contador=7;Contador>=0;Contador--)            //Contador con Nº de bits a chequear
            printf ("%c",bit_test(PORTA,Contador)+'0');    //Transmite los bits convertidos a ASCII
            putc('\r');                                    //Transmite CR
    }
}
Ejemplo 8.6
Código:
/* 
El módulo EUSART. Control remoto y monitorización

Este ejemplo recibe una serie de comandos ('0'-'7') que permiten cambiar de estado las salidas
RB7:RB0. Constantemente se transmite, previa conversión a ASCII, el estado actual de esas salidas 
a modo de monitorización */

#include <16f886.h>

/* Ajusta los valores de las palabras de configuración durante el ensamblado.Los bits no empleados
adquieren el valor por defecto.Estos y otros valores se pueden modificar según las necesidades */

#fuses     NOLVP,PUT,NOWDT,EC_IO,NOFCMEN,NOBROWNOUT    //Palabra 1 de configuración
#fuses    NOWRT,BORV40                                //Palabra 2 de configuración

/* Con estas directivas las funciones "input" y "output_bit" no reprograman
el pin de la puerta cada vez que son utilizadas. Si no se indica el
modo fast_io se asume por defecto standard_io el cual reprograma el pin
siempre antes de ser utilizadas estas funciones. */

#use fast_io (B)
#use fast_io (C)
#use delay(clock=4000000)            //Frecuencia de trabajo

//Habilita las funciones RS232, velocidad a 9600 baudios

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#byte PORTB =0x06                    //Dirección de la puerta B

/*Programa de tratamiento de la interrupción que se produce al recibir un carácter. Analiza el
comando recibido ('0' -'7') y actua sobre la salida apropiada haciéndola cambiar de estado */

#int_rda            //Vector de interrupción al recibir por el UART
tratamiento()
{    switch(getc())        //Lee el carácter recibido
    {
        case '0': output_toggle(pin_b0);break;    //Si es el comando '0' , RB0 cambia de estado
        case '1': output_toggle(pin_b1);break;    //Si es el comando '1' , RB1 cambia de estado
        case '2': output_toggle(pin_b2);break;    //Si es el comando '2' , RB2 cambia de estado
        case '3': output_toggle(pin_b3);break;    //Si es el comando '3' , RB3 cambia de estado
        case '4': output_toggle(pin_b4);break;    //Si es el comando '4' , RB4 cambia de estado
        case '5': output_toggle(pin_b5);break;    //Si es el comando '5' , RB5 cambia de estado
        case '6': output_toggle(pin_b6);break;    //Si es el comando '6' , RB6 cambia de estado
        case '7': output_toggle(pin_b7);break;    //Si es el comando '7' , RB7 cambia de estado
    }    
}

main()
{  
    signed int Contador;

    SETUP_ADC_PORTS(NO_ANALOGS);    //Puerta A y B Digitales
    output_b(0x00);                    //Borra las salidas
    set_tris_b(0b00000000);            //Puerta B salida
    set_tris_c(0b10111111);            //RC6/TxD salida de datos y RC7/RxD entrada del EUSART    
    putc('\r');                        //Transmite CR
    putc('\n');                        //Transmite avance de línea

    enable_interrupts(INT_RDA);        //Activa interrupción en la recepción
    enable_interrupts(global);        //Habilita interrupciones

    while(1)
    {
        for (Contador=7;Contador>=0;Contador--)    //Contador con Nº de bits a chequear
            printf ("%c",bit_test(PORTB,Contador)+'0');    //Transmite los bits convertidos a ASCII
            putc('\r');                //Transmite CR
    }
}

Espero que tengas ejemplos que te puedan ayudar de verdad. También los tengo en asm.

Saludo.
 
Atrás
Arriba