No funciona uart de pic a pic

Hola!!!

Soy nuevo en el foro, siempre me habia basado en el para tomar informacion y solucionar algunos problemas que he tenido, pero ahora no he podido encontrar alguien que haya tenido un problema similar o algo parecido, mi problema es el siguiente:

Necesito comunicar dos pics (18f4550) atraves del uart o usart, para mandar una lectura del adc del primer pic al segundo, el problema es que nisiquiera me funciona un programa simple para observar el envio de un numero del primer pic al segundo y poder visualizarlo en un lcd, no se mucho de pics solo lo basico, es por eso que a lo mejor no he podido solucionarlo, programo en C y los programas de los pics son los sig:

PROGRAMA DEL PIC EMISOR:


Código:
#include <18f4550.h>
#fuses XT,NOWDT,NOPROTECT
#use delay (clock=4000000)
#use rs232(baud=9600,xmit=pin_c6,rcv=pin_c7)
#include <lcd.c>


void main()
{
   int valor;
   lcd_init();
   
   while(1)
   {
      for(valor=0;valor<=10;valor++)
      {
         PUTC(valor);
         printf(lcd_putc,"\fEnviando=%1D",valor);
         delay_ms(500);
      }
   }
}


PROGRAMA DEL PIC RECEPTOR:


Código:
#include <18f4550.h>
#fuses XT,NOWDT,NOPROTECT
#use delay (clock=4000000)
#use rs232(baud=9600,xmit=pin_c6,rcv=pin_c7,parity=N,bits=8)
#include <lcd.c>
#BYTE TRISA=0X85
#BYTE PORTA=0X05


int valor;
#int_RDA
void RDA_isr(void)
{
   valor=GETC();
}

void main()
{
   bit_clear(TRISA,0);
   enable_interrupts(int_RDA);
   enable_interrupts(global);
   lcd_init();
   
   for(;; )
   {
      lcd_gotoxy(1,1);
      printf(lcd_putc,"Recibiendo=%1D",valor);
      }
}

Al simularlo en el proteus si me funciona, pero al hacerlo en fisico no pasa nada, el lcd del receptor solo se queda en "Recibiendo=0" pero no hace nada mas, si me pudieran ayudar se los agradeceria, ya que solo me hace falta la comunicacion de los pics y poder tratar de sustituir los cables por modulos XBee. Gracias de antemano
 
Te valdría leer un poco la hoja de datos del PIC18F4550. Los registros TRISx, PORTx, LATx usan otras direcciones de memoria y sospecho sobre la configuración de los fuses ya que este PIC tiene varias cosas solo para el oscilador, por eso hay que configurar bien.
salu2
 
Proba con esta configuración de fuses:

#fuses XT,PUT,NOBROWNOUT,NOWDT,NOLVP,NODEBUG,NOMCLR

Que cristal usas? Usas el USART por hardware o lo haces por software? Para configurar las entradas/salidas del PIC en CCS se usa la función:

set_tris_a(0b00110010);
set_tris_b(0b00101010);
set......

Antes de configurar de ese modo debes definir al comienzo del programa después de definir que PIC vas a usar esto:

#use FAST_IO(A)
#use FAST_IO(B)
#use.....

De este modo el compilador no genera el código para modificar el registro TRIS cada vez que se usa algún pin, si usas el USART por hardware tenes que definir los pines de esa manera sino no funciona poniendo el RX como entrada y el TX como salida y definiendo así:

#use RS232 (BAUD=9600,UART1)

Así usas el UART por hardware que trae el PIC. Postea tu código a ver como te queda ahora a ver si funciona.

Saludos!!
 
Ya probaste con la linea de datos?. Por ejemplo si las uart de los pic son del tipo DTE debes de usar un cable cruzado para conectarlos. Si uno es DTE y el otro es DCE se usa un cable derecho. Si los dos son DCE se deberia uasr un cable cruzado.
 
Mira amigo....yo pase por lo mismo..dure varios días en lo mismo
Y logre solucionar eso de la comunicación UART con la Configuración COMPLETA de los FUSIBLES DE CONFIGURACIÓN..
No tengo una configuración para tu caso, la tengo para el USB....Busca en Intenet una configuración completa de los #FUSES + CCS + PIC18F4550...
Saludos
 
Ya probaste con la linea de datos?. Por ejemplo si las uart de los pic son del tipo DTE debes de usar un cable cruzado para conectarlos. Si uno es DTE y el otro es DCE se usa un cable derecho. Si los dos son DCE se deberia uasr un cable cruzado.

A lo mejor parecera tonta la preg. pero kmo puedo saber de ke tipo son, de cualkier forma lo tenia conectado kn cable cruzado.

por lo otro, ya he tratado knlos fuses pero no he podido saber bie kmo configurarlos y sospecho ke por ahi es el error, aunke en proteus si me de la comunicacion.
 
Proba haciendo una pequeña prueba de que el PIC te encienda un LED en un PIN al iniciar el programa asi sabes si por lo menos el PIC esta arrancando y no es problema de FUSES.

Saludos
 
Se que el tema es un poco viejo, pero espero que alguien logre ver mi mensaje. Tengo el mismo problema que el compañero o por lo menos parecido, estoy comunicando dos PICs por USART, el transmisor es un 16f877a y el receptor es un 18f4550, solo como prueba de transmision realizo un pequeño programa el cual consiste en enviar un numero entero entre 1 y 250, esto lo hago con un push button que hace incrementar el valor desde el pic16f877a y enviar el mismo valor al pic18f4550 que lo muestra en una lcd16x2.

En la simulacion de proteus funciona perfectamente y sin problemas, me muestra el mismo valor que envio en la lcd del pic receptor 18f4550. La transmision es alambrica del pin TX al pin RX, pero aun asi en la practica en el pic18f4550 siempre recibo el numero 254 o 255, a pesar de que el pic transmisor esta enviando un 1 o 2 o 3, ... hasta 250.

Los pics los programe con MikroC y creo que el error tambien esta en los bits de configuracion- fuses pero por mas que le busco no logro solucionarlo. Por cierto la velocidad de transmision es de 9600 y uso cristales de 10mhz para ambos PICs. Alguien me podria ayudar a solucionar mi problema. Gracias
 
Cuando un uC no posee el puerto serie implementado por hardware, una forma de solventar ese problema, si se necesita si o si puerto serie, es implementarlo mediante código usando demoras e interrupciones externas, en otras palabras te tenés que hacer cargo de tomar bien todos los pulsos que vas a mandar o recibir.

En cambio una Uart por hardware simplemente se configura la velocidad, el tipo de datos, los bits de paridad y te olvidas como se realiza la transmisión, solo estás pendiente de la interrupción que genera en caso de que haya llegado un dato o que el puerto esté disponible para enviar nuevos datos.
 
Gracias cosmefulanito04! jejeje tengo otra pregunta hojalá también me puedas ayudar, cómo le puedo hacer una comunicación bidireccional entre la PC y el PIC, por ejemplo: el PIC está sensando continuamente la temperatura y esta la envia a la PC y aquí la grafico en tiempo real. Sin embargo, el programa en la computadora compara el valor actual de la temperatura con uno de referencia, si lo supera, debe enviar una señal al PIC de que encienda un ventilador. Mi pregunta es como lo puedo hacer siendo que el PIC envía continuamente la temperatura.

Gracias!!:)
 
Gracias cosmefulanito04! jejeje tengo otra pregunta hojalá también me puedas ayudar, cómo le puedo hacer una comunicación bidireccional entre la PC y el PIC, por ejemplo: el PIC está sensando continuamente la temperatura y esta la envia a la PC y aquí la grafico en tiempo real. Sin embargo, el programa en la computadora compara el valor actual de la temperatura con uno de referencia, si lo supera, debe enviar una señal al PIC de que encienda un ventilador. Mi pregunta es como lo puedo hacer siendo que el PIC envía continuamente la temperatura.

Gracias!!:)

Normalmente los uC que tienen uart comparten el mismo registro de datos tanto para la transmisión como para la recepción al igual que en la PC, entonces si bien tenés lineas físicas bidireccionales, no vas a poder realizar la transmisión y recepción en el mismo instante.

De todas formas, si vas a medir ºT, ¿tiene sentido estar mandando toooodo el tiempo los datos?, la ºT es una variable a medir muy lenta, con tal de que actualices 1 o 2 veces por segundo es muy probable que te alcance, además de que vas a reducir el consumo inútil por parte del ADC que tiene que estar convirtiendo todo ese tiempo.

Entonces te recomiendo evaluar primero si el sistema que vas a medir puede presentar una variación muy brusca de ºT en menos de 1 Seg y en base a eso te vas a dar cuenta que tan rápida debe ser la medición.

Por otro lado, tal vez quieras medir más de una vez para hacer un promediado... perfecto, ¿cuánto tiempo te puede tomar eso? 10... 100mSeg como mucho y todavía te quedan 900mSeg de sobra.
 
Hola muchos saludos a cosmefulanito04, una explicaciòn perfecta.

Les dejo un circuito donde se utiliza el Pic 16F84A que no tiene Uart propria y utiliza en RX (recepciòn en este caso) una Soft_Uart osea una implementaciòn de Uart mediante Software.
http://t-electron.webnode.it/, muchos saludos a TODOS.
 
La ventaja de hacer una comunicacion UART de pic a pic es la posibilidad de usar baudios a velocidad que uno quiera, si usas un cristal de 4Mhz recomiendo usar multiplos de esta frequencia: 1000 Baudios, 4000 Baudios, y con un muy buen diseño de plaqueta y distancia de menos de 15 cm de cable 10000 baudios. Salduos!
 
Hola gente. Tengo un problema con este programa que es sencillo pero no me funciona en proteus.

Aquí dejo el código en C del receptor:
PHP:
#include<18f1320.h>
 NOWDT,NOBROWNOUT,NOPUT,NOPROTECT,NOLVP,XT,NOMCLR

#use delay(CLOCK=4M)

#use rs232(baud=4800,rcv=PIN_B4,xmit=PIN_b1,parity=N,bits=8,stop=1)


int8 data=0x00;

#INT_RDA
void at_RSI(){




data=getc();

}

void main(void){
set_tris_A(0x00);
setup_adc_ports(NO_ANALOGS);
set_tris_B(0b00010010);//la hoja de dato que debo definit tris<1 y 4>=1

enable_interrupts(int_rda);

enable_interrupts(GLOBAL);
output_a(0x00);

while(true){



if(data==3){data=0x00;output_a(0x01);delay_ms(2000);output_a(0x00);delay_ms(20);}



}
}
Este es el código del transmisor:
PHP:
#INCLUDE<12f683.h>
#fuses NOWDT,NOBROWNOUT,NOPROTECT,NOMCLR
#use fast_io(A)
#use delay(INTERNAL=4M)
#use rs232(baud=4800,xmit=PIN_A0,rcv=PIN_A3,parity=N,bits=8,stop=1,FORCE_SW)

void RS232_criollo(int8);
#INT_EXT
void atie_isr(){

output_A(0x02);
delay_ms(1500);
output_a(0x00);

rs232_criollo(3);
}


void main(void){
//!TRISIO=0b00000100;
//!ANSEL=ANSEL&0b11110000;
setup_adc_ports(NO_ANALOGS);
set_tris_A(0b00001100);
ext_int_edge(H_TO_L);
enable_interrupts(INT_EXT);

enable_interrupts(GLOBAL);
while(1){
}



}
void RS232_criollo(int8 i){
putc(i);
delay_us(50);
}
 
Hola sosa2008... Revisando el código que subiste puedo decirte que en general esta bien pero hay algunos detallitos que se te fueron.

Estas unas ligeras correcciones.
Código:
#include<18f1320.h>
#fuses NOWDT,NOBROWNOUT,NOPUT,NOPROTECT,NOLVP,XT,NOMCLR
#use delay(CLOCK=4M)
#use rs232(uart1,baud=4800)

int8 data=0;

#INT_RDA
void at_RSI()
{
   data=getc();
}

void main(void)
{
   output_drive(pin_b1);         //pin tx como salida
   enable_interrupts(int_rda);
   enable_interrupts(GLOBAL);
   output_a(0);
   while(true)
   {
      if(data==3)
      {
         data=0;
         output_a(1);
         delay_ms(2000);
         output_a(0);
         delay_ms(20);
      }
   }
}
Código:
#INCLUDE<12f683.h>
#fuses NOWDT,NOBROWNOUT,NOPROTECT,NOMCLR
#use delay(INTERNAL=4M)
#use rs232(baud=4800,xmit=PIN_A0,rcv=PIN_A3,parity=N,bits=8,stop=1)


void RS232_criollo(unsigned int8 i)
{
   putc(i);
   delay_us(50);
} 
#INT_EXT
void atie_isr()
{
   output_high(pin_a1);
   delay_ms(1500);
   output_low(pin_a1);
   rs232_criollo(3);
}
void main(void)
{
   output_drive(pin_a0);         //pin tx como salida
   ext_int_edge(H_TO_L);
   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);
   while(true);
}
Dibujo.PNG
 

Adjuntos

  • ejemplo_rs232.rar
    116.3 KB · Visitas: 20
Buenas. Soy nuevo programando PIC y estoy haciendo un programa donde al presionar un botón, me encienda un LED y también me envíe un dato por UART.

El problema es que enciende el LED, pero no envía el dato.
¿Si alguien sabe qué error tengo o qué me falta, podría decirme cómo solucionarlo?
PHP:
#include <16F628A>

#fuses XT
#fuses NOWDT
#fuses NOLVP, PUT, BROWNOUT
#use FAST_IO(A)
#use FAST_IO(B)
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=pin_B2, rcv=pin_B1)        //manejo del RS232

void main(){

   set_tris_a(0b00010011);
   set_tris_b(0b00000010);
   enable_interrupts(INT_TBE);
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
  
  int aux1=0;
  int Ban1=0;
  int Brr1=0;
  int Brr=0;
   //Setup_Oscillator parameter not selected from Intr Oscillator Config tab
   
   // TODO: USER CODE!!
       
while(1){

if(input(PIN_A1)==0){output_toggle(PIN_B7);}
   else{output_bit(PIN_B7,0);}


if(input(PIN_A4)==0 && Ban1==0){

aux1++;
      Ban1=1;
      if(aux1==1){printf("a");
                  output_bit(PIN_B5,1);
                  output_bit(PIN_B4,0);
                  output_bit(PIN_B6,0);}
      if(aux1==2){puts("b");
                  output_bit(PIN_B4,1);
                  output_bit(PIN_B5,0);
                  output_bit(PIN_B6,0);}
      if(aux1==3){puts("r");
                  output_bit(PIN_B6,1);
                  output_bit(PIN_B5,0);
                  output_bit(PIN_B4,0);
                  aux1=0;}
      }

if(input(PIN_A4)==1){Ban1=0;}


if(input(PIN_A0)==0 && Brr1==0){Brr1=1;
                                puts("c");}
if(input(PIN_A0)==1){Brr1=0;}


if(input(PIN_B0)==0 && Brr==0){Brr=1;
                              puts("d");}                          
if(input(PIN_B0)==1){Brr=0;}

}

}
 
Última edición por un moderador:
No sé qué es lo que quieras hacer, pero tienes configuraciones que no estás usando, sobre todo, las interrupciones.
Si no las usas y las activas, pueden provocar conflictos, ya que no tienen un controlador en el programa.

Prueba de ésta forma y haciendo uso de una selección de datos con "switch ()"
PHP:
#include <16F628A.h>
#use delay(crystal = 4MHz)
#use rs232(UART1)

void main (void)
{
   int8 aux1 = 0;
   int1 Ban1 = 0, Brr1 = 0, Brr = 0;
       
   while (true)
   {
      if(!input(PIN_A1))
         output_toggle(PIN_B7);
      else
         output_low(PIN_B7);


      if(!input(PIN_A4) && !Ban1)
      {
         aux1 ++;
         Ban1 = 1;
         
         switch (aux1)
         {
            case 1:
               printf("a");
               output_high(PIN_B5);
               output_low(PIN_B4);
               output_low(PIN_B6);
               break;
         
            case 2:
               puts("b");
               output_high(PIN_B4);
               output_low(PIN_B5);
               output_low(PIN_B6);
               break;
      
            case 3:
               puts("r");
               output_high(PIN_B6);
               output_low(PIN_B5);
               output_low(PIN_B4);
               aux1=0;
         }
      }

      if(input(PIN_A4))
         Ban1 = 0;

      if(!input(PIN_A0) && !Brr1)
      {
         Brr1 = 1;
         puts("c");
      }
      
      if(input(PIN_A0))
         Brr1 = 0;


      if(!input(PIN_B0) && !Brr)
      {
         Brr = 1;
         puts("d");
      }
      
      if(input(PIN_B0))
         Brr = 0;
   }
}
 
Atrás
Arriba