TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: freshdesing en 12 de Septiembre de 2012, 08:34:43
-
Buenas, tengo conectado 2 pics mediante el puerto RS232, y los pines RC6 y RC7. el Pic A envia datos y el Pic B los recibe. El problema que me surge es que cuando el Pic A envia el dato al instante recibe un dato que no se cual es. El Pic B recibe bien el dato y lo muestra por el LCD, pero en su programa no envia nada. El Pic A envia otro dato, y vuelve a recibir un dato raro, un símbolo, y el Pic B lo recibe bien y lo muestra por el LCD. Si quito la interrupcion #int_RDA en el PIC A, sesoluciona le problema, pero creo que hay algo funcionando mal. Dejo los dos programas a ver si podríais ayudarme. He puesto dos resistencias de Pull up tanto a RX como a TC, pero el problema persiste. Gracias por adelantado.
PIC A:
////////////////////////////////////////////////////////////////////////////////
// Comunicacion Serial SR232 entre pics
// Abril 2010
// Realizado:
// Programa: Comunicacion Serial SR232 entre pics A
// Proyecto:
//
// -Versión: 1.0 Septiembre 2012
//
//
// Dispositivo: PIC 16F876 Compilador: CCS vs4.049
//
// FUNCIONAMIENTO:
// COMUNICACION SERIE ENTRE DOS PICS. EL A ACTUA DE EMISOR Y EL B DE
// RECEPTOR. SE ESCRIBE LO QUE SE ENVIA Y SE RECIBE POR UN LCD 2x16.
//
////////////////////////////////////////////////////////////////////////////////
#include <16f876.h> //pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT //ordenes para el programador
#use delay(clock=4000000,RESTART_WDT) //Fosc=4Mhz
//
//#include<lcd_C.c> //libreria manejo LCD 16x2 4 bits PORTC
#use rs232(baud=9600,XMIT=PIN_C6, RCV=PIN_C7,PARITY=N,BITS=8)
#define use_portb_lcd TRUE
#include<lcd.c>
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#byte port_a = 0x05
#byte port_b = 0x06
#byte port_c = 0x07
char dato;
//!//Subrutina para refrescar el display
void display (void)
{
printf(lcd_putc,"\f");
printf(lcd_putc,"COM RS232\n");
printf(lcd_putc,"TRANSMITER");
}
//Subrutina de interrución del TMR1 Cada 0.5 segundos.
//fos/4=frec del TMR1 -> 0-65535
//0,5 seg=(4/Fosc)*8*(65536-valorTMR1)
//TMR 62500 -> 3036
#INT_TIMER1
void control_timer1(void)
{
output_bit(pin_b3,!input(pin_b3));
set_timer1(3036);
}
#int_RDA //Interrupción por recepción de datos
void RDA_isr()
{
dato=getc(); //En "dato" el dato recibido via RS232
printf(lcd_putc, "\fRecibido %c ", dato); //Se muestra en pantalla información recibida
delay_ms(3000);
printf(lcd_putc, "\f");
}
///PROGRAMA
void main(void)
{
disable_interrupts(GLOBAL);
set_tris_a(0x01); // RA0 --> XMIT
// RA1 --> RCV
// RA2 -->
// RA3 -->
// RA4 -->
// RA5 -->
port_b_pullups(false); // Resistencias de polarización del puerto B
set_tris_b(0x00); // RB7 --> OUT D7
// RB6 --> OUT D6
// RB5 --> OUT D5
// RB4 --> OUT D4
// RB3 -->
// RB2 --> OUT RW
// RB1 --> OUT RS
// RB0 --> OUT E
set_tris_c(0x80); // RC0 -->
// RC1 -->
// RC2 -->
// RC3 -->
// RC4 -->
// RC5 -->
// RC6 -->
// RC7 -->
lcd_init(); //inicializa lcd
delay_ms(1000);
printf(lcd_putc,"\fLCDInicializado");
delay_ms(1000);
display();
delay_ms(2000);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
enable_interrupts(INT_TIMER1);
disable_interrupts(INT_RB);
disable_interrupts(INT_EXT);
//ext_int_edge (L_TO_H);
enable_interrupts(int_rda);
enable_interrupts(GLOBAL);
while(1)
{
dato='a';
printf(lcd_putc,"\fDato enviado:\n");
printf(lcd_putc,"%c",dato);
putc(dato);
delay_ms(1000);
printf(lcd_putc,"\fEsperando...");
delay_ms(3000);
dato='b';
printf(lcd_putc,"\fDato enviado:\n");
printf(lcd_putc,"%c",dato);
putc(dato);
delay_ms(1000);
printf(lcd_putc,"\fEsperando...");
delay_ms(3000);
dato='c';
printf(lcd_putc,"\fDato enviado:\n");
printf(lcd_putc,"%c",dato);
putc(dato);
delay_ms(1000);
printf(lcd_putc,"\fEsperando...");
delay_ms(3000);
}
}
PIC B
////////////////////////////////////////////////////////////////////////////////
// Comunicacion Serial SR232 entre pics
// Abril 2010
// Realizado:
// Programa: Comunicacion Serial SR232 entre pics B
// Proyecto:
//
// -Versión: 1.0 Septiembre 2012
//
//
// Dispositivo: PIC 16F876 Compilador: CCS vs4.049
//
// FUNCIONAMIENTO:
// COMUNICACION SERIE ENTRE DOS PICS. EL A ACTUA DE EMISOR Y EL B DE
// RECEPTOR. SE ESCRIBE LO QUE SE ENVIA Y SE RECIBE POR UN LCD 2x16.
//
//
////////////////////////////////////////////////////////////////////////////////
#include <16f876.h> //pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT //ordenes para el programador
#use delay(clock=4000000,RESTART_WDT) //Fosc=4Mhz
//#include<lcd_C.c> //libreria manejo LCD 16x2 4 bits PORTC
#use rs232(baud=9600,XMIT=PIN_C6, RCV=PIN_C7,PARITY=N,BITS=8)
#define use_portb_lcd TRUE
#include <lcd.c>
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#byte port_a = 0x05
#byte port_b = 0x06
#byte port_c = 0x07
char dato;
//!//Subrutina para refrescar el display
void display (void)
{
printf(lcd_putc,"\f");
printf(lcd_putc,"COM RS232\n");
printf(lcd_putc,"RECEIVER");
}
//Subrutina de interrución del TMR1 Cada 0.5 segundos.
//fos/4=frec del TMR1 -> 0-65535
//0,5 seg=(4/Fosc)*8*(65536-valorTMR1)
//TMR 62500 -> 3036
#INT_TIMER1
void control_timer1(void)
{
output_bit(pin_b3,!input(pin_b3));
set_timer1(3036);
}
#int_RDA //Interrupción por recepción de datos
void RDA_isr()
{
dato=getc(); //En "dato" el dato recibido via RS232
printf(lcd_putc, "\fRecibido %c ", dato); //Se muestra en pantalla información recibida
delay_ms(1000);
printf(lcd_putc,"\nEspernado....");
//printf(lcd_putc, "\f");
}
///PROGRAMA
void main(void)
{
disable_interrupts(GLOBAL);
set_tris_a(0x01); // RA0 --> XMIT
// RA1 --> RCV
// RA2 -->
// RA3 -->
// RA4 -->
// RA5 -->
port_b_pullups(false); // Resistencias de polarización del puerto B
set_tris_b(0x00); // RB7 --> OUT D7
// RB6 --> OUT D6
// RB5 --> OUT D5
// RB4 --> OUT D4
// RB3 -->
// RB2 --> OUT RW
// RB1 --> OUT RS
// RB0 --> OUT E
set_tris_c(0x80); // RC0 -->
// RC1 -->
// RC2 -->
// RC3 -->
// RC4 -->
// RC5 -->
// RC6 -->
// RC7 -->
lcd_init(); //inicializa lcd
delay_ms(1000);
printf(lcd_putc,"\fLCDInicializado");
delay_ms(1000);
display();
delay_ms(2000);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
enable_interrupts(INT_TIMER1);
disable_interrupts(INT_RB);
disable_interrupts(INT_EXT);
//ext_int_edge (L_TO_H);
enable_interrupts(int_rda);
enable_interrupts(GLOBAL);
lcd_init(); //inicializa lcd
delay_ms(1000);
printf(lcd_putc,"\fLCDInicializado");
delay_ms(1000);
display();
delay_ms(2000);
while(1)
{
}
}
-
No entiendo porque en el PIC que envía datos haces uso de la interrupción de UART y a su vez dentro de la interrupción lees el dato y lo muestras.
Si nunca vas a recibir datos, no hagas la lectura. Es más, ni siquiera incluyas la interrupción de UART.
Otras cosas a mejorar son que dentro de la rutina de interrupción no debes consumir demasiado tiempo.
La instrucción "printf" consume muchos siclos de instrucción y ni hablar de quedarse esperando 3 segundos
-
No entiendo porque en el PIC que envía datos haces uso de la interrupción de UART y a su vez dentro de la interrupción lees el dato y lo muestras.
Si nunca vas a recibir datos, no hagas la lectura. Es más, ni siquiera incluyas la interrupción de UART.
Otras cosas a mejorar son que dentro de la rutina de interrupción no debes consumir demasiado tiempo.
La instrucción "printf" consume muchos siclos de instrucción y ni hablar de quedarse esperando 3 segundos
La idea es en el siguiente paso hacer que el PIC B mande algo al PIC A. Por eso el dejar la interrupción. Pero no entiendo que aunque este habilitada, si no le llega nada no debería de entrar en ella. Pero quito de la interrupcion todo. Gracias.
-
tenia puesto set_tris_c(0x40); en vez de set_tris_c(0x80);. Tenia cambiada la entrada/salida de RX y TX.....
Ya funciona... Lo modifico en el programa por si alguien quiere hacer uso de el.