TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: chicodita03 en 16 de Noviembre de 2014, 02:51:11
-
Buenas noches gente, curioseando sobre proyectos con PIC encontré el tema de comunicación serial entre dos de ellos lo cual me pareció bastante interesante. Entonces como para ir entrando suave, me propuse a encender un led en el PIC B (recepción) pulsando un botón en el PIC A (transmisión)
Aquí los códigos
PIC A (Transmisión)
#include "C:\\Users\\ADMIN\\Documents\\PRUEBA RS232\\TRANSMISION\\tx.h"
#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7)
char flag;
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_CLOCK_DIV_2);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
while(true)
{
if(input(pin_b0)==1)
{
flag=1;
putc(flag);
delay_ms(500);
}
else
{
flag=0;
putc(flag);
delay_ms(500);
}
}
}
PIC B (Recepción)
#include "C:\\Users\\ADMIN\\Documents\\PRUEBA RS232\\RECEPCION\\rx.h"
#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7, bits=8)
#int_RDA
char flag;
void RDA_isr()
{
flag=getc();
delay_ms(100);
}
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_CLOCK_DIV_2);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
while(true)
{
if(flag==1)
{
output_high(pin_b0);
delay_ms(500);
}
}
}
Estoy simulando esto en Proteus y pasa que el PIC A funciona perfecto, al presionar un botón en B0 el virtual terminal muestra un 01, pero el de recepción nada que enciende el led y la verdad no sé que pueda estar pasando. Sé que hay mucha información en este foro y la he leído pero llevo mucho intentandolo y nada, espero me puedan echar una mano
Agradezco mucho su ayuda. ...
-
Se me olvidó decirles el pic que estoy usando :lol: : 16F877A
-
En la forma en que lo haces desde el PIC transmisor, estas leyendo continuamente el boton pulsado, por lo tanto estas enviando a destajo y sin pausa alguna al pic esclavo.
Encima en el PIC esclavo lees el puerto y en la interrupción pones un delay de 100 ms dentro (algo que esta desaconsejado en transmisión rs232) seguramente viene el otro byte cuando estas temporizando y ya se bloquea el puerto, porque no leiste el byte siguiente.
Deberas hacer dos cosas:
- Escribir desde el PIC que envía solamente cuando ocurran cambios de estado del botón, y ademas agregar un retardo para eliminar los rebotes que se producen en un switch al pulsarlo, si buscas en el foro debe haber cientos de ejemplos para hacerlo...
- En el PIC receptor, eliminar la temporizacion dentro de la interrupción y ademas en el Use RS232 () poner el tratamiento de errores (creo que es errors) así si ocurre nuevamente, la rutina se encarga de borrar los flags de error por ti...
-
Hola MGLSOFT, gracias por ayudarme. Te cuento que he seguido los pasos y sigue sin encender el led.
Así modifiqué el de transmisión
#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7)
char flag;
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_CLOCK_DIV_2);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
while(true)
{
if(input(pin_b0)==1)
{
delay_ms(10);
flag=1;
putc(flag);
delay_ms(500);
}
}
}
Y el de recepción
#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7, bits=8, ERRORS)
#int_RDA
char flag; //Char o int?
void RDA_isr()
{
flag=getc();
}
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_CLOCK_DIV_2);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
set_tris_b(0);
while(true)
{
if(flag==1)
{
output_high(pin_b0);
delay_ms(1000);
}
}
}
Al colocar "ERRORS" aparece esta advertencia
Warning 202 "rx.c" Line 2(5,8): Variable never used: rs232_errors
Gracias
-
No veo el problema, podrás poner el código y el archivo de Proteus, para probarlo en simulación??
-
Hola amigos.
Debes colocar #int_rda, he inmediatamente despues void RDA_ISR(); asi se define la rutina de interrupcion, por eso nunca se ejecuta esta, debes colocarla asi:
#int_rda
void rda_isr()
{
char flag;
flag=getc();
}
Ademas en la rutina de recepcion el led al encenderse nunca se apagara :?
Saludos
-
MGLSOFT aquí adjunto los códigos, los .hex y la simulación hecha en Proteus 8. Gracias mil!
-
RALF2 Gracias!!!!! :) ((:-)) Muchas gracias en serio. Tal y como lo escribiste ese era el error. Ya hice el código para que encendiera y apagara, lo importante era que recibiera.
Muchísimas gracias de nuevo.
-
Me alegro mucho de haberte podido ayudar, para eso estamos en el foro :mrgreen:
Para ayudarnos entre todos!
Saludos