Autor Tema: Comunicación serie sin UART  (Leído 4823 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado jomu

  • PIC10
  • *
  • Mensajes: 16
Comunicación serie sin UART
« en: 21 de Marzo de 2007, 05:54:05 »
Hola a tod@s,

Estoy metido en un proyecto con dos PIC16F688 (aunque podría ser otro con no más de 18pin), lo que pretendo hacer es una comunicación IR entre dos micros con uno de ellos conectado a un PC vía RS-232. El PIC1 emisor (que también receptor) envía el valor de temperatura que le proporciona un sensor analógico al otro PIC2 vía IR, este último procesa los datos los muestra unos 7 segmentos y los transmite al PC. En el PC se tiene que poder controlar un transistor de potencia conectado al PIC1.
Resumiendo, necesito una comunicación PIC1 <-> PIC2 con infrarrojos  y PIC2 <-> PC con RS232.

Pretendo usar las USART que traen los PIC para la comunicación IR, mi pregunta es pues: ¿Como implemento la comunicación RS-232 con el PIC2? ¿Se podría hacer con dos (Tx/Rx) pins cualesquiera del PIC2?  :?

Estoy trabajando en assembler, cualquier idea o ejemplo seria de ayuda :P

Muchas gracias de antemano!
« Última modificación: 21 de Marzo de 2007, 06:29:09 por jomu »

Deimos

  • Visitante
Re: Comunicación serie sin UART
« Respuesta #1 en: 21 de Marzo de 2007, 12:15:16 »
Dentro del mplab hay librerias (.h) que permiten simular un puerto asociado a registros como tu pretendes hacer. Estas librerias empiezan por sw (sw_i2c.h, sw_spi.h, sw_usart.h, ....). Excepto las entradas A/D, el resto de puertos I/O se pueden simular.

La pega, segun yo lo veo, es que la simulación del puerto usart la tendrás que hacer de modo secuencial, ya que no puedes asociar interrupciones a estas líneas, de manera que en tu sistema se vuelve prioritaria la comunicación usart y la monitorización de la temperatura pasa a ser secundaria. Es el problema de trabajar de manera secuencial, que llega un momento en el que los tiempos para consultar una entrada y actualizar una salida se vuelven tan rígidos que no puedes tocar una coma del programa sin que se te escacharre el resto del fuente.

Resumiendo: Sí es posible simular un puerto usart con un puerto convencional I/O. Necesitas para ello la libreria sw_usart.h.

Nota: La libreria sw_usart.h es para el c18, es decir lenguaje C, pero te dará una idea de como se realiza la simulación. Migrarlo al asm no te va a ser fácil.

Salu2!!!!

Desconectado jomu

  • PIC10
  • *
  • Mensajes: 16
Re: Comunicación serie sin UART
« Respuesta #2 en: 21 de Marzo de 2007, 14:52:14 »
Gracias por contestar Deimos!  :)

Tengo entendido que se puede agregar código C dentro de código ASM (con las instrucciones cblock i endc), ¿es así? Si se pudiera hacer, ¿ves viable que integre la librería y que la use como un bloque de código en C dentro del ASM? Las interrupciones generadas por la USART afectarían igual mientras se estuviera ejecutando el bloque C (ASM traducido) ¿no?  :?

Cuando me comentas: "La pega, según yo lo veo, es que la simulación del puerto usart la tendrás que hacer de modo secuencial, ya que no puedes asociar interrupciones a estas líneas, de manera que en tu sistema se vuelve prioritaria la comunicación usart y la monitorización de la temperatura pasa a ser secundaria."
No sería al revés, la monitorización de la temperatura será más prioritaria ya que al estar conectada la comunicación PIC1 <-> PIC2 al USART este si que dispone de interrupciones. Por lo tanto será mas prioritaria que la RS232 emulada. Corrigeme si me confundo.

Un saludo y mil gracias!  :lol:

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: Comunicación serie sin UART
« Respuesta #3 en: 21 de Marzo de 2007, 15:30:33 »
Hola jomu.

hasta donde se no se puede incrustar C dentro del asm, siendo posible pero al revés.
la directiva CBLOCK se usa para declarar registros GPR a partir de la dirección señalada

CBLOCK 0x20
registro1
registro2
..
..
ENDC

esto es para evitar tener que usar el EQU (que lo veía en programas antíguos), simplificando el código


La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: Comunicación serie sin UART
« Respuesta #4 en: 21 de Marzo de 2007, 16:57:45 »
Dentro del mplab hay librerias (.h) que permiten simular un puerto asociado a registros como tu pretendes hacer. Estas librerias empiezan por sw (sw_i2c.h, sw_spi.h, sw_usart.h, ....). Excepto las entradas A/D, el resto de puertos I/O se pueden simular.

Deimos quisiera aclarar un poco el punto, espero no te ofendas.

Siendo estricto con la terminología, los archivos .h no son librerías, son simplemente archivos de encabezado o header files que contienen los prototipos de las funciones.

Las librerías propiamente dichas (para los pics) son las .lib.

C18 trae muchas .lib ya compiladas y además adjuntan su código fuente (.c) .  Nosotros hacemos el include del .h (que contiene los prototipos de las funciones) y C18 las irá a buscar al directorio LIB del path de instalación.  Por eso siempre las encuentra (ya que los path se agregan al instalarse).

Es el .c el que realmente tiene el código fuente de lo que hace la librería.  Si queremos cambiar su comportamiento debemos editar el .c

Con la utilidad MPLIB se puede hacer una archivo compilada (.o) en un archivo de librería .lib



- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Deimos

  • Visitante
Re: Comunicación serie sin UART
« Respuesta #5 en: 22 de Marzo de 2007, 04:58:47 »
jomu tienes razón, no se como leí tu mensaje. Al utilizar dos pics cada uno se dedica a una cosa y con lo cual no tienes el problema de prioridades que te comentaba. Debe ser porque estoy acostumbrado a llevar los micros a tope siempre intentando usar el menor número de micros. Tenía en mente que estabas usando un solo micro y por eso te decía que en ese caso, al no tener interrupciones asociadas al usart, se debía ejecutar esa parte de manera secuencial, lo que lo volvía prioritario con respecto el resto del fuente. Pero usando dos micros como te digo, este problema no lo tienes.

Maunix eres un purista jejeje pero tienes toda la razón del mundo. Estamos tan acostumbrados a hacer lo que hacemos que cuando hablamos no nos damos cuenta que el que nos escucha es posible que no nos esté entendiendo.

Akí pego el sw_uart.h que viene dentro de la carpeta h del mcc18.

#ifndef __SW_UART_H
#define __SW_UART_H

/* PIC 18 Software UART library header
 *
 * The I/O pins must be specified for the software UART. The
 * corresponding TRIS bits must also be specified. The notation is:
 *     PORTx,y  where x is A,B,C etc. and y is the bit 0-7
 *     TRISx,y  where x is A,B,C etc. and y is the bit 0-7
 * This is in assembly language notation because assembly is
 * used to initialize the software UART.
 */

/* Function Prototypes */

#define PARAM_SCLASS auto

/* OpenUART
 * Configures the UART I/O pins
 */
void OpenUART(void);

/* ReadUART
 * Reads a byte from the UART
 */
char ReadUART(void);

/* WriteUART
 * Writes a byte to the UART
 */
void WriteUART(PARAM_SCLASS char);

/* getsUART
 * Reads a string from UART
 */
void getsUART(PARAM_SCLASS char *, PARAM_SCLASS unsigned char);

/* putsUART
 * Writes a string to the UART
 */
void putsUART(PARAM_SCLASS char *);

/* getcUART
 * getc is really read
 */
#define getcUART ReadUART

/* putcUART
 * putc is really write
 */
#define putcUART WriteUART

#endif /* __SW_UART_H */


Y esta es la usart.h dentro de la misma libreria. Te puede ser de ayuda.

#ifndef __USART_H
#define __USART_H

/* PIC18 USART peripheral libraries. */

/* There are three library modules, corresponding to register names:
 *  USART1  (TXSTA1, RCSTA1, etc.)
 *  USART2  (TXSTA2, RCSTA2, etc.)
 *  USART  (TXSTA, RCSTA, etc.)
 *  Each module is defined only for those devices for which the register
 *  names are defined.
 */

 /* Corresponding to each module, there are several routines:
  *
  * The 'open' routine takes two parameters:
  *   - 'config' is the bitwise 'and' of the appropriate configuration
  *     bit masks (defined below);
  *   - 'spbrg' is the baud rate.
  * The registers associated with the USART module are set according to these
  * parameters; then, the transmitter and receiver are enabled.
  *
  * The 'datardy' routine returns 1 if data has been received, 0 otherwise.
  *
  * The 'read' routine returns the received byte.  It also sets the framing
  * and overrun error status bits (FRAME_ERROR & OVERRUN_ERROR) if necessary;
  * also, the status receive bit 8 (RX_NINE) is significant if 9-bit mode
  * is enabled.
  * (See status bit structure definition below).
  *
  * The 'write' routine accepts the byte to transmit.  If 9-bit mode is
  * enabled, the status trasmit bit 8 (TX_NINE) is also trasmitted.
  *
  * The 'gets' routine accepts a buffer and the buffer length in bytes as
  * parameters.  It fills the buffer with bytes as they are received; it will
  * wait for data if necessary in order to fill the entire buffer.
  *
  * The 'puts' routine accepts a null-terminated byte string.  All bytes
  * are transmitted, including the null character.  It will wait until the
  * USART is not busy in order to transmit all the bytes.
  *
  * The 'putrs' routine is identical to 'puts', except the byte string
  * resides in ROM.
  *
  * The 'close' routine disables the receiver, the transmitter, and the
  * interrupts for both.
  *
  * The 'busy' routine returns 1 if the transmit shift register is not empty;
  * otherwise, it returns 0.
  *
  * For devices with enhanced USART capability, an additional 'baud'
  * routine is provided.  This routine takes a 'config' parameter, which
  * is a bitwise 'and' of the baud configuration bit masks (see below).
  * The BAUDCON (a.k.a. BAUDCTL) register is configured appropriately.
  */

/* Change this to near if building small memory model versions of
 * the libraries. */
#define MEM_MODEL far

/* storage class of library routine parameters; pre-built with auto;
 * do not change unless you rebuild the libraries with the new storage class */
#define PARAM_SCLASS auto

/* Configuration bit masks to be 'anded' together and passed as the 'config'
 * parameter to the 'open' routine. */
#define USART_TX_INT_ON   0b11111111  // Transmit interrupt on
#define USART_TX_INT_OFF  0b01111111  // Transmit interrupt off
#define USART_RX_INT_ON   0b11111111  // Receive interrupt on
#define USART_RX_INT_OFF  0b10111111  // Receive interrupt off
#define USART_BRGH_HIGH   0b11111111  // High baud rate
#define USART_BRGH_LOW    0b11101111  // Low baud rate
#define USART_CONT_RX     0b11111111  // Continuous reception
#define USART_SINGLE_RX   0b11110111  // Single reception
#define USART_SYNC_MASTER 0b11111111  // Synchrounous master mode
#define USART_SYNC_SLAVE  0b11111011  // Synchrounous slave mode
#define USART_NINE_BIT    0b11111111  // 9-bit data
#define USART_EIGHT_BIT   0b11111101  // 8-bit data
#define USART_SYNCH_MODE  0b11111111  // Synchronous mode
#define USART_ASYNCH_MODE 0b11111110  // Asynchronous mode

/* These devices have enhanced USARTs. */
#if defined(__18F6585) || defined(__18F6680) || \
    defined(__18F8585) || defined(__18F8680) || \
    defined(__18F2480) || defined(__18F2580) || \
    defined(__18F4480) || defined(__18F4580) || \
    defined(__18F2585) || defined(__18F2680) || \
    defined(__18F4585) || defined(__18F4680) || \
    defined(__18F64J15) || defined(__18F65J10) || defined(__18F65J15) || \
    defined(__18F66J10) || defined(__18F66J15) || defined(__18F67J10) || \
    defined(__18F84J15) || defined(__18F85J10) || defined(__18F85J15) || \
    defined(__18F86J10) || defined(__18F86J15) || defined(__18F87J10) || \
    defined(__18F1220) || defined(__18F1320) || \
    defined(__18F6525) || defined(__18F6621) || \
    defined(__18F8525) || defined(__18F8621) || \
    defined(__18F2515) || defined(__18F2525) || \
    defined(__18F2610) || defined(__18F2620) || \
    defined(__18F4515) || defined(__18F4525) || \
    defined(__18F4610) || defined(__18F4620) || \
    defined(__18F6310) || defined(__18F6390) || \
    defined(__18F6410) || defined(__18F6490) || \
    defined(__18F8310) || defined(__18F8390) || \
    defined(__18F8410) || defined(__18F8490) || \
    defined(__18F2455) || defined(__18F2550) || \
    defined(__18F4455) || defined(__18F4550) || \
    defined(__18F2510) || defined(__18F2520) || \
    defined(__18F4410) || defined(__18F4420) || \
    defined(__18F4510) || defined(__18F4520) || \
    defined(__18F6527) || defined(__18F6622) || \
    defined(__18F6627) || defined(__18F6722) || \
    defined(__18F8527) || defined(__18F8622) || \
    defined(__18F8627) || defined(__18F8722) || \
    defined(__18F24J10) || defined(__18F25J10) || \
    defined(__18F44J10) || defined(__18F45J10)

/* The baud configuration bit masks to be 'anded' together and passed to
 * the 'baud' routine. */
#define BAUD_IDLE_CLK_HIGH  0b11111111  // idle state for clock is a high level
#define BAUD_IDLE_CLK_LOW   0b11101111  // idle state for clock is a low level
#define BAUD_16_BIT_RATE    0b11111111  // 16-bit baud generation rate
#define BAUD_8_BIT_RATE     0b11110111  // 8-bit baud generation rate
#define BAUD_WAKEUP_ON      0b11111111  // RX pin monitored
#define BAUD_WAKEUP_OFF     0b11111101  // RX pin not monitored
#define BAUD_AUTO_ON        0b11111111  // auto baud rate measurement enabled
#define BAUD_AUTO_OFF       0b11111110  // auto baud rate measurement disabled
#endif


/* Only these devices have two USART modules: USART1 & USART2. */
#if defined(__18F6520) || defined(__18F6620) || defined(__18F6720) || \
    defined(__18F8520) || defined(__18F8620) || defined(__18F8720) || \
    defined(__18F64J15) || defined(__18F65J10) || defined(__18F65J15) || \
    defined(__18F66J10) || defined(__18F66J15) || defined(__18F67J10) || \
    defined(__18F84J15) || defined(__18F85J10) || defined(__18F85J15) || \
    defined(__18F86J10) || defined(__18F86J15) || defined(__18F87J10) || \
    defined(__18F6527) || defined(__18F6622) || \
    defined(__18F6627) || defined(__18F6722) || \
    defined(__18F8527) || defined(__18F8622) || \
    defined(__18F8627) || defined(__18F8722) || \
    defined(__18F6525) || defined(__18F6621) || \
    defined(__18F8525) || defined(__18F8621) || \
    defined(__18F6310) || defined(__18F6390) || \
    defined(__18F6410) || defined(__18F6490) || \
    defined(__18F8310) || defined(__18F8390) || \
    defined(__18F8410) || defined(__18F8490)


/* ***** USART1 ***** */

/* status bits */
union USART1
{
  unsigned char val;
  struct
  {
    unsigned RX_NINE:1;         // Receive Bit 8 if 9-bit mode is enabled
    unsigned TX_NINE:1;         // Transmit Bit 8 if 9-bit mode is enabled
    unsigned FRAME_ERROR:1;     // Framing Error for USART
    unsigned OVERRUN_ERROR:1;   // Overrun Error for USART
    unsigned fill:4;
  };
};


void Open1USART (PARAM_SCLASS unsigned char config, PARAM_SCLASS char spbrg);
#if defined(__18F6525) || defined(__18F6621) || \
    defined(__18F8525) || defined(__18F8621) || \
    defined(__18F64J15) || defined(__18F65J10) || defined(__18F65J15) || \
    defined(__18F66J10) || defined(__18F66J15) || defined(__18F67J10) || \
    defined(__18F84J15) || defined(__18F85J10) || defined(__18F85J15) || \
    defined(__18F86J10) || defined(__18F86J15) || defined(__18F87J10) || \
    defined(__18F6527) || defined(__18F6622) || \
    defined(__18F6627) || defined(__18F6722) || \
    defined(__18F8527) || defined(__18F8622) || \
    defined(__18F8627) || defined(__18F8722)

#define DataRdy1USART( ) (PIR1bits.RCIF)
#else
#define DataRdy1USART( ) (PIR1bits.RC1IF)
#endif
char Read1USART (void);
void Write1USART (PARAM_SCLASS char data);
void gets1USART (PARAM_SCLASS char *buffer, PARAM_SCLASS unsigned char len);
void puts1USART (PARAM_SCLASS char *data);
void putrs1USART (PARAM_SCLASS const MEM_MODEL rom char *data);
#define getc1USART Read1USART
#define putc1USART Write1USART
#define Close1USART( ) RCSTA1&=0b01001111,TXSTA1bits.TXEN=0,PIE1&=0b11001111
#define Busy1USART( )  (!TXSTA1bits.TRMT)
#if defined(__18F6525) || defined(__18F6621) || \
    defined(__18F8525) || defined(__18F8621) || \
    defined(__18F6310) || defined(__18F6390) || \
    defined(__18F6410) || defined(__18F6490) || \
    defined(__18F8310) || defined(__18F8390) || \
    defined(__18F8410) || defined(__18F8490) || \
    defined(__18F64J15) || defined(__18F65J10) || defined(__18F65J15) || \
    defined(__18F66J10) || defined(__18F66J15) || defined(__18F67J10) || \
    defined(__18F84J15) || defined(__18F85J10) || defined(__18F85J15) || \
    defined(__18F86J10) || defined(__18F86J15) || defined(__18F87J10) || \
    defined(__18F6527) || defined(__18F6622) || \
    defined(__18F6627) || defined(__18F6722) || \
    defined(__18F8527) || defined(__18F8622) || \
    defined(__18F8627) || defined(__18F8722)

void baud1USART (PARAM_SCLASS unsigned char baudconfig);
#endif


/* ***** USART2 ***** */

/* status bits */
union USART2
{
  unsigned char val;
  struct
  {
    unsigned RX_NINE:1;         // Receive Bit 8 if 9-bit mode is enabled
    unsigned TX_NINE:1;         // Transmit Bit 8 if 9-bit mode is enabled
    unsigned FRAME_ERROR:1;     // Framing Error for USART
    unsigned OVERRUN_ERROR:1;   // Overrun Error for USART
    unsigned fill:4;
  };
};

void Open2USART (PARAM_SCLASS unsigned char config, PARAM_SCLASS char spbrg);
#define DataRdy2USART( ) (PIR3bits.RC2IF)
char Read2USART (void);
void Write2USART (PARAM_SCLASS char data);
void gets2USART (PARAM_SCLASS char *buffer, PARAM_SCLASS unsigned char len);
void puts2USART (PARAM_SCLASS char *data);
void putrs2USART (PARAM_SCLASS const MEM_MODEL rom char *data);
#define getc2USART Read2USART
#define putc2USART Write2USART
#define Close2USART( ) RCSTA2&=0b01001111,TXSTA2bits.TXEN=0,PIE3&=0b11001111
#define Busy2USART( ) (!TXSTA2bits.TRMT)
#if defined(__18F6525) || defined(__18F6621) || \
    defined(__18F8525) || defined(__18F8621) || \
    defined(__18F64J15) || defined(__18F65J10) || defined(__18F65J15) || \
    defined(__18F66J10) || defined(__18F66J15) || defined(__18F67J10) || \
    defined(__18F84J15) || defined(__18F85J10) || defined(__18F85J15) || \
    defined(__18F86J10) || defined(__18F86J15) || defined(__18F87J10) || \
    defined(__18F6527) || defined(__18F6622) || \
    defined(__18F6627) || defined(__18F6722) || \
    defined(__18F8527) || defined(__18F8622) || \
    defined(__18F8627) || defined(__18F8722)
void baud2USART (PARAM_SCLASS unsigned char baudconfig);
#endif

#else


/* ***** USART (TXSTA, RCSTA, etc.) ***** */

/* status bits */
union USART
{
  unsigned char val;
  struct
  {
    unsigned RX_NINE:1;         // Receive Bit 8 if 9-bit mode is enabled
    unsigned TX_NINE:1;         // Transmit Bit 8 if 9-bit mode is enabled
    unsigned FRAME_ERROR:1;     // Framing Error for USART
    unsigned OVERRUN_ERROR:1;   // Overrun Error for USART
    unsigned fill:4;
  };
};

void OpenUSART (PARAM_SCLASS unsigned char config, PARAM_SCLASS unsigned spbrg);
#define DataRdyUSART( ) (PIR1bits.RCIF)
char ReadUSART (void);
void WriteUSART (PARAM_SCLASS char data);
void getsUSART (PARAM_SCLASS char *buffer, PARAM_SCLASS unsigned char len);
void putsUSART (PARAM_SCLASS char *data);
void putrsUSART (PARAM_SCLASS const MEM_MODEL rom char *data);
#define getcUSART ReadUSART
#define putcUSART WriteUSART
#define CloseUSART( ) RCSTA&=0b01001111,TXSTAbits.TXEN=0,PIE1&=0b11001111
#define BusyUSART( ) (!TXSTAbits.TRMT)
#if defined(__18F6585) || defined(__18F6680) || \
    defined(__18F8585) || defined(__18F8680) || \
    defined(__18F2480) || defined(__18F2580) || \
    defined(__18F4480) || defined(__18F4580) || \
    defined(__18F2585) || defined(__18F2680) || \
    defined(__18F4585) || defined(__18F4680) || \
    defined(__18F1220) || defined(__18F1320) || \
    defined(__18F2515) || defined(__18F2525) || \
    defined(__18F2610) || defined(__18F2620) || \
    defined(__18F4515) || defined(__18F4525) || \
    defined(__18F4610) || defined(__18F4620) || \
    defined(__18F2455) || defined(__18F2550) || \
    defined(__18F4455) || defined(__18F4550) || \
    defined(__18F2510) || defined(__18F2520) || \
    defined(__18F4510) || defined(__18F4520) || \
    defined(__18F24J10) || defined(__18F25J10) || \
    defined(__18F44J10) || defined(__18F45J10)
void baudUSART (PARAM_SCLASS unsigned char baudconfig);
#endif

#endif

#endif


Salu2!!!!!!!
« Última modificación: 22 de Marzo de 2007, 05:10:17 por Deimos »

Desconectado jomu

  • PIC10
  • *
  • Mensajes: 16
Comunicación serie sin UART
« Respuesta #6 en: 22 de Marzo de 2007, 08:38:31 »
Muchas gracias a todos!  :lol:

Pero estuve pensando y lo implementaré con un multiplexor, ya que no tengo necesidad de utilizar la comunicación RS-232 y IR al mismo tiempo. Así que utilizare un puerto para controlar un multiplexor 1:2 para seleccionar que comunicación quiero usar.

Gracias de todos modos, siempre viene bien saber cosas nuevas  :P