Recibir RS-232 y enviar RS-485

Buenas, pues me encontré un código muy bueno en otra página, ya lo probé en proteus y funciona muy bien.
Este código es para una red de pics con comunicación por medio de rs485.
Quisiera saber si se puede adaptar para recibir los datos por otro pin (RS232) y después los envíe por medio del rs485
Sé que se manejan de la misma manera las dos comunicaciones, pero no sé cómo adaptar para recibir por un lado y enviar por el otro.
Estoy iniciándome en la programación y para mi es un poco complicado.

Si me pueden orientar, mil gracias.


http://www.todopic.com.ar/foros/index.php?topic=19057.0

Código:
/** \file firmware_iRELE485-628.c
    * \brief Este fichero contiene el cuerpo principal del Firmware del\n
    * dispositivo auxiliar satélite de la iACD V1.0.4. denominado iRELE485-628
    *
    * Integra todos los subsistemas y funciones implementados.\n
    * Source para el compilador CCS C v.3.242
    *
    * Microprocesador : <b>16F628A</b> (18 pines PDIP) \n\n
    * Fuses utilizados: \n
    * \li <b>INTRC</b> Internal RC Osc
    * \li <b>MCLR</b> Master Clear pin enabled
    * \li <b>NOWDT</b> No Watch Dog Timer
    * \li <b>NOPROTECT</b> Code not protected from reading
    * \li <b>NOPUT</b> No Power Up Timer
    * \li <b>NOBROWNOUT</b> No brownout reset
    * \li <b>NOLVP</b> No low voltage prgming, B3(PIC16)
    * \li <b>NOCPD</b> No EE protection
    *
    * \author Diego Márquez García-Cuervo \n
    * <http://picmania.garcia-cuervo.net>
    *
    * \version 1.0.0.A
    */
     
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // Definiciones estándar del 16F628A
    //
    ///////////////////////////////////////////////////////////////////////////////////////////////////
     
    #include <16F628A.h>
     
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // Fuses y ajuste de Clock
    //
    ///////////////////////////////////////////////////////////////////////////////////////////////////
     
    #fuses INTRC,MCLR,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP,NOCPD
    #use delay(clock=4000000)
     
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // Defines y Constantes
    //
    ///////////////////////////////////////////////////////////////////////////////////////////////////
     
    /*! \def DRIVER_RELE
    *   Pin accionador del Relé número 1 \li HIGH : Relé ON.
    */
    #define DRIVER_RELE PIN_B4
     
    /*! \def TX_485_ENABLE
    *  Pin que habilita la transmisión por el canal RS485
    * \li LOW Habilita recepción RS485
    * \li HIGH Habilita transmisión RS485.
    */
    #define TX_485_ENABLE PIN_B5
     
    /*! \def bytes_for_USART_buffer
    *  \brief Establece el número de bytes de longitud del buffer de la USART.
    */
    #define bytes_for_USART_buffer 12
     
    /*! \var const char VERSION
    *  \brief Versión del Firmware.
    */
    const char VERSION[]="1.0.0\0";
     
    /*! \var const char WhatAmI
    *  \brief Identificador de tipo de dispositivo: 'R' Relé.
    */
    const char WhatAmI = 'R';
     
    /*! \var const char WhoAmI
    *  \brief Identificador de dispositivo.
    */
    const char WhoAmI = '1';
     
    /*! \var const char Command_Execute
    *  \brief Comando que indica ejecución de acción : Activar Relé
    */
    const char Command_Execute = 'X';
     
    /*! \var const char end_of_transmit
    *  \brief Carácter que indica fin de transmisión (no buffereable)
    */
    const char end_of_transmit = '!';
     
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // Canal de Comunicación
    //
    ///////////////////////////////////////////////////////////////////////////////////////////////////
     
    #use rs232(baud=9600,xmit=PIN_B2,rcv=PIN_B1)
     
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // Prototipos de Funciones
    //
    ///////////////////////////////////////////////////////////////////////////////////////////////////
     
    void USART_activa_tx(void);
    void USART_activa_rx(void);
    void USART_add_to_buffer(char c);
     
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // R A M : Variables Globales Estáticas
    //
    ///////////////////////////////////////////////////////////////////////////////////////////////////
     
    /*! \var USART_buffer
    *  \brief Buffer de la USART
    */
    static char USART_buffer[bytes_for_USART_buffer];
     
    /*! \var USART_nextRec
    *  \brief Indice del Buffer de la USART
    */
    static int8 USART_nextRec;
     
    /** \var Command
     * \brief Comando válido para ejecutar.
     */
    int8 Command;
     
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // Funciones
    //
    ///////////////////////////////////////////////////////////////////////////////////////////////////
     
    /** \brief Abre el canal RS485 para transmitir.
     * \return void
     */
    void USART_activa_tx(void){
     output_high(TX_485_ENABLE);
     delay_ms(5);
    }
     
    /** \brief Abre el canal RS485 para recibir.
     * \return void
     */
    void USART_activa_rx(void){
     delay_ms(5);
     output_low(TX_485_ENABLE);
     delay_ms(1);
    }
     
    /** \brief Inicializa el Buffer de la USART
     *
     * Recoge el último carácter recibido desde la USART sobre USART_buffer
     * e incrementa en 1 el índice USART_nextRec.\n\n
     * Si el carácter recibido es Retorno de carro '\\r' ó 0x0D comprueba identidad de dispositivo y comando recibido
     *
     * \return void
     */
    void USART_add_to_buffer(char c){
     
      USART_buffer[USART_nextRec++]=c;
      if(USART_nextRec==bytes_for_USART_buffer){
         USART_nextRec=0;
      }
     
      if(c==end_of_transmit){
         --USART_nextRec;
         if(USART_buffer[USART_nextRec-3]==WhatAmI){
            if(USART_buffer[USART_nextRec-2]==WhoAmI){
              if(USART_buffer[USART_nextRec-1]==Command_Execute){
                 Command=0x01;
              }
            }
         }
         USART_nextRec = 0;
      }
    }
     
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // Rutinas de Servicio de Interrupciones
    //
    ///////////////////////////////////////////////////////////////////////////////////////////////////
     
    #int_rda
    /** \brief Interrupción por : Recepción del Canal Serie.
     *
     */
    void interrupt_service_rutine_rda(void) {
     
      char USART_nextChar;
     
      USART_nextChar='\0';
      if(kbhit()){
         USART_nextChar=getc();
         USART_add_to_buffer(USART_nextChar);
      }
    }
     
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // M A I N
    //
    ///////////////////////////////////////////////////////////////////////////////////////////////////
     
    /** \brief Constituye el núcleo principal del sistema
     *
     * \return void.
     */
    void main(void) {
     
      setup_oscillator(OSC_4MHZ);
      setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
      setup_timer_1(T1_INTERNAL|T1_DIV_BY_4);
      setup_timer_2(T2_DISABLED,0,1);
      setup_comparator(NC_NC_NC_NC);
      setup_vref(FALSE);
      port_b_pullups(False);
      set_tris_b(0b00000010);
      output_low(DRIVER_RELE);
      delay_ms(100);
     
      USART_nextRec = 0;
      Command = 0x00;
     
      USART_activa_rx();
      delay_ms(333);
     
      enable_interrupts(global);
      enable_interrupts(int_rda);
     
      USART_activa_tx();
      printf("[iRELE485-628] v.%s\r\n",version);
      USART_activa_rx();
     
      do{
     
         if(Command==0x01){
            Command =0x00;
     
            USART_activa_tx();
            printf("R%cA%c\r\n",WhoAmI,end_of_transmit);
            USART_activa_rx();
     
            output_high(DRIVER_RELE);
            delay_ms(2000);
            output_low(DRIVER_RELE);
          }
     
      } while(true);
    }
     
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // End of firmware
    //
    ///////////////////////////////////////////////////////////////////////////////////////////////////
 
Última edición por un moderador:
Creo que más que un problema de programación es de hardware, para lo que quieres lograr basta con conectar el pin RX del PIC a un interfaz (232) y el de TX a la otra (485) o viceversa.

Saludos
 
Buenas Daniel, gracias por contestar, mas bien lo que nesecito es poner un pic entre la pc y la 485 y este pic debe de recibir y transmitir por ambos conexiones, en el 485 se usan ambos tx y rx, he visto que se puede configurar otros pins para embiar y recibir datos pero en este programa no se como hacerlo esta un poco dificil aun para mis conocimientos, aclaro, se que podria poner la RS485 directo pero nesecito por asi decirlo un intermediariaro entre RS232 y 485, gracias

PC----RS232----PIC----RS485
 
Ok, ahora ¿la comunicación será transparente?, es decir el PIC sólo actúa como puente entre la PC y el RS485, si es así sólo será necesaria una interfaz RS232-RS485.

En cambio, si el PIC procesa los datos recibidos/enviados puedes hacer uso de una UART "virtual" hecha por software en el PIC para usar una para el RS232 y otra ara el RS485, o bien diseñar una especie de multiplexor por hardware que direccione los datos de entrada y salida de la UART en función de un bit de control.
 
Yo logré (al menos en simulación :rolleyes:) hacer algo similar a lo que intentas, sólo que con dos canales RS232.

Lo que hace el código es crear "n" canales de comunicación, con sus respectivos pines TX y RX cada uno, a la vez que se les asigna un nombre (denominado "stream") a cada uno, para que así al momento de recibir o enviar los datos, tengas referencia para esperar un dato de determinado canal o enviarlo por determinado canal.

Te adjunto el código que vienen en la ayuda del PCW CCS C Compiler :LOL:

Código:
printf("Continue (Y,N)?");
do {
   answer=getch();
}while(answer!='Y' && answer!='N');

#use rs232(baud=9600,xmit=pin_c6,rcv=pin_c7,stream=HOSTPC)
#use rs232(baud=1200,xmit=pin_b1,rcv=pin_b0,stream=GPS)
#use rs232(baud=9600,xmit=pin_b3,stream=DEBUG)
...
while(TRUE) {
   c=fgetc(GPS);
   fputc(c,HOSTPC);
   if(c==13)fprintf(DEBUG,"Got a CR\r\n");
}

Saludos.
 
Atrás
Arriba