# Comunicación UART-Hyperterminal con MSP430



## 203toni (Oct 9, 2012)

Hola foreros. 
Quiero realizar una comunicación con el MSP430G2553 a través del modo UART en su USCI. Solo necesito mandar datos ASCII al pc, verlos en el hyperterminal. Los comunico con un puerto USB.
Utilizo para debuguear el CCS 5.1. 
He programado los registros de la UART con paridad par, un bit de stop y 9600 Baudios.
En el hyperterminal lo mismo 9600 Baudios, paridad par,... ect. También he puesto el número de COM al que se conecta el USB. 
Para probar mando la letra A (43Hex en ASCII), pero aunque he comprobado que la carga en el registro UCA0TXBUF para transferir, no me muestra nada en la pantalla del hyperterminal y también según el manual el flag de interrupcion UCA0TXIFG se pondría a 0, cosa que no hace. 
Por lo tanto no se si es culpa de la comunicación con el hyperterminal o problema de programación.
Espero vuestras sugerencias.

Esta es parte del programa:

```
#include  "msp430g2553.h"
#define __MSP430_HAS_USCI__                   

int contador = 0;
void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                           // Stop WDT
  BCSCTL1 = CALBC1_1MHZ;                                   // Set DCO
  DCOCTL = CALDCO_1MHZ;
  P1SEL = BIT1 + BIT2 ;                                         // P1.1 = RXD, P1.2=TXD
  P1SEL2 = BIT1 + BIT2 ;                                       // P1.1 = RXD, P1.2=TXD
  UCA0CTL0 |= UCPEN + UCPAR;                 // Selecciono paridad PAR
  UCA0CTL1 |= UCSSEL_2;                                    // SMCLK
  UCA0BR0 = 6;                                                   // 1MHz 9600
  UCA0BR1 = 0;                                                   // 1MHz 9600
  UCA0MCTL = 0x81;
  UCA0CTL1 &= ~UCSWRST;                                // **Initialize USCI state machine**
  IE2 |= UCA0TXIE;                                            // Enable USCI_A0 TX interrupt

  UCA0TXBUF = 'A';

  __bis_SR_register(LPM0_bits + GIE);       // Enter LPM0, interrupts enabled
}
#pragma vector=USCIAB0TX_VECTOR
__interrupt void USCI0TX_ISR(void)
{
    contador = contador+1;                     //Cuento para saber cuando entra en la ISR
}
```
Soy novato en estos temas, seguramente será un fallo tonto, pero no sé verlo...
Os agradezco de antemano vuestra ayuda. Gracias.


----------



## Ardogan (Oct 9, 2012)

Según el código de ejemplo de
http://www.ti.com/lit/sw/slac485a/slac485a.zip
Archivo msp430g2xx3_uscia0_uart_01_9600.c

  UCA0BR0 = 104;                            // 1MHz 9600 
  UCA0BR1 = 0;                              // 1MHz 9600 
  UCA0MCTL = UCBRS0;                        // Modulation UCBRSx = 1 

Es decir, creo que tenés mal el baudrate: 1 MHz / 6 = 166 Kbps en tu caso, y en el código de ejemplo es 1MHz / 104 = 9615

Desconozco si está bien el UCA0MCTL.


----------



## 203toni (Oct 10, 2012)

Gracias por la sugerencia Ardogan, pero también había probado con la modulación del ejemplo y no me resuelve el problema. He sacado los datos de los registros de las tablas que hay en la guía de usuario SLAU144I, por lo que creo que están bien de las dos formas (Depende del registro UCA0MCTL).

Mi problema está al mandarlo, cuando cargo el dato en el registro UCA0TXBUF, desconozco si hay que realizar alguna otra acción para enviarlo, ¿Es necesario mandar por software los bit de start stop y calcular la paridad? o todo eso lo realiza ya la propia interrupción?

Otra hipótesis es que tenga fallos en la comunicación con el hypertetminal, que el dato sea enviado por el micro pero el hyperterminal no lo reconozca (es la primera vez que lo uso).

¿Alguna solución? Si alguno ha usado esta interrupción con este micro o alguno similar, le agradecería que me enseñara el programa. Gracias!!


----------



## Ardogan (Oct 10, 2012)

No, no hace falta generar bits de arranque/parada con esos módulos.

Te diría que primero trates de trabajar con la configuración del ejemplo (sin paridad, 1 bit de stop, 9600) que es la más común y que viene por default en general para todo.
Programá el ejemplo msp430g2xx3_uscia0_uart_01_9600.c
Lo que hace este programa es repetir lo que le llega desde la PC, es decir, hace eco.
Con esa configuración verificá que pasa del lado de la PC cambiando la configuración del puerto serie para 9600, 8 bits de datos, sin paridad, sin control de flujo.

Tendrías que definir contador como volatile, porque se modifica desde una rutina de interrupción. En vez de
int contador = 0;
va
volatile int contador = 0;

No hace falta la línea
#define __MSP430_HAS_USCI__
Porque esas definiciones de hardware ya se hacen a través del
#include  "msp430g2553.h"

Algo que podés hacer para verificar que el módulo USCI trabaje bien (eliminando la PC como factor) es conectar la pata TX del UART a la pata RX del UART, en teoría deberías recibir lo mismo que transmitís (una especie de eco local), aunque para eso deberías poder depurar/ejecutar paso a paso el programa y ver como va respondiendo.
Si estás trabajando con un Launchpad deberías levantar los jumpers RXD y TXD para hacer esta prueba, después hacés la conexión RX <->TX, y depurás el programa (Code Composer Studio?, IAR?, mspgcc?).
Sería el mismo programa de ejemplo de arriba agregando una escritura a UCA0TXBUF, antes de entrar en modo de bajo consumo:


```
#include  "msp430g2553.h"

volatile int contador = 0;

void main(void) 
{ 
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT 
  BCSCTL1 = CALBC1_1MHZ;                    // Set DCO 
  DCOCTL = CALDCO_1MHZ; 
  P1SEL = BIT1 + BIT2 ;                     // P1.1 = RXD, P1.2=TXD 
  P1SEL2 = BIT1 + BIT2 ;                     // P1.1 = RXD, P1.2=TXD 
  UCA0CTL1 |= UCSSEL_2;                     // SMCLK 
  UCA0BR0 = 104;                            // 1MHz 9600 
  UCA0BR1 = 0;                              // 1MHz 9600 
  UCA0MCTL = UCBRS0;                        // Modulation UCBRSx = 1 
  UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine** 
  IE2 |= UCA0RXIE;                          // Enable USCI_A0 RX interrupt 
  UCA0TXBUF = 'A'; //Despues de ejecutar esta linea con el depurador, debería entrar a la rutina de interrupción de abajo
 
  __bis_SR_register(LPM0_bits + GIE);       // Enter LPM0, interrupts enabled 
} 
 
//  Echo back RXed character, confirm TX buffer is ready first 
#pragma vector=USCIAB0RX_VECTOR 
__interrupt void USCI0RX_ISR(void) 
{ 
  while (!(IFG2&UCA0TXIFG));                // USCI_A0 TX buffer ready? 
  //UCA0TXBUF = UCA0RXBUF;                    // TX -> RXed character 
  contador = contador + 1;
}
```
Con eso podés saber si es problema del manejo del micro o de la PC.

 Saludos


----------



## foso (Oct 10, 2012)

Hola 203tony. ¿Estás usando el Launch pad para comunicarte ?


----------



## 203toni (Oct 11, 2012)

Buenas.
Si foso, estoy intentando usar el LAunchPad de Texas para comunicarme.

Pues Ardogan he estado probando con el ejemplo msp430g2xx3_uscia0_uart_01_9600.c (Sin modificar nada)  al probarlo en el CCS y con el hyperterminal conectado al mismo COM, he intentado escribir en el hyper con el teclado del PC pero no me muestra nada.
Porque este programa funciona mandando datos desde el hyperterminal y haciendo el micro el eco, ¿No?

Luego he probado el código que me has puesto, tampoco funcionaba, he probado paso a paso cuando llega a UCA0TXBUF = 'A'; si que lo carga en el registro pero no salta a la interrupción pasa al modo bajo consumo y de allí el siguiente paso salta al running. (No entiendo en tu ejemplo por qué no activas el permiso de interrupción IE2 |= UCA0TXIE para la transmisión ¿No es necesario?)
Luego he mirado la comunicación uniendo las patillas T y R, quitando jumpers y demás... de este modo después del modo de bajo consumo salta a la interrupción. Ahí cuando entra se igualan los registros. Esto creo que funciona correctamente.

Igual necesito otro hyperterminal o un programa parecido, probaré con esa opción.

Saludos.


----------



## foso (Oct 11, 2012)

claro, los jumpers Tx y Rx tienen que estar a 90º para que funcione la comunicación.


----------



## 203toni (Oct 11, 2012)

Pero foso yo hago la comunicación por el USB de la Launch Pad, entonces tienen que estar conectados.


----------



## foso (Oct 11, 2012)

No te digo que saques los jumpers. Te digo que los pongas a 90º. O sea asi:

 -----------
|----------|
 -----------

 -----------
|----------|
 -----------


----------



## Ardogan (Oct 11, 2012)

203toni dijo:


> Buenas.
> Si foso, estoy intentando usar el LAunchPad de Texas para comunicarme.
> 
> Pues Ardogan he estado probando con el ejemplo msp430g2xx3_uscia0_uart_01_9600.c (Sin modificar nada)  al probarlo en el CCS y con el hyperterminal conectado al mismo COM, he intentado escribir en el hyper con el teclado del PC pero no me muestra nada.
> Porque este programa funciona mandando datos desde el hyperterminal y haciendo el micro el eco, ¿No?


Ajá.... la PC es candidata a ser el problema...



203toni dijo:


> Luego he probado el código que me has puesto, tampoco funcionaba, he probado paso a paso cuando llega a UCA0TXBUF = 'A'; si que lo carga en el registro pero no salta a la interrupción pasa al modo bajo consumo y de allí el siguiente paso salta al running. (No entiendo en tu ejemplo por qué no activas el permiso de interrupción IE2 |= UCA0TXIE para la transmisión ¿No es necesario?)



No es estrictamente necesario activar ninguna interrupción. Ni de recepción ni de transmisión. Las interrupciones son una manera útil de saber cuando pasó algún evento y poder responder en forma inmediata.
Tranquilamente podrías hacer un polling en el main del tipo
while(!(IFG2 & UCA0TXIFG));   //mientras no se haya activado el flag esperar

Pero no nos desviemos...
Para este caso, la interrupción de transmisión nos indicaría que no se está transmitiendo nada por el UART actualmente, y que al no estar ocupado podemos entonces escribir al registro UCA0TXBUF.



203toni dijo:


> Luego he mirado la comunicación uniendo las patillas T y R, quitando jumpers y demás... de este modo después del modo de bajo consumo salta a la interrupción. Ahí cuando entra se igualan los registros. Esto creo que funciona correctamente.


Bien, esto indica que al menos el módulo UART hace algo, es decir, puede escribir datos y recibirlos.

Está bien instalado el driver del launchpad?.
Elegiste bien el puerto COM en el administrador de dispositivos?. Fijate que en las propiedades del puerto COM tiene que decir algo como "MSP430 Application UART (COM X)"



203toni dijo:


> Igual necesito otro hyperterminal o un programa parecido, probaré con esa opción.
> 
> Saludos.



Probá con el PuTTY, acá hay un ejemplo 
http://dev.wlan-si.net/wiki/Modifications/LaunchpadMSP430

Ahora que veo esto... yo lo que usé hasta ahora es la versión vieja del Launchpad (la que viene con MSP430g2231 y MSP430g2211).
La versión nueva (que viene con el MSP430g2553) veo que cambió la disposición de jumpers. No sabía eso, fijate bien en que configuración tienen que estar los jumpers para usar la comunicación con la PC en el Launchpad nuevo.

Saludos


----------



## R-Mario (Oct 15, 2012)

Porque no usar la interfaz grafica GRACE y luego ves el codigo que genera


----------



## hander (Ene 9, 2013)

Hola, tengo la versión nueva del LaunchPad que viene con el microcontrolador msp430g2553 y estoy tratando de aprender a configurar la UART. Estoy utilizando el archivo msp430g2xx3_uscia0_uart_01_9600.c que lo que hace es hacer eco de lo que le llega del PC, es decir si le mando el caracter A me debería de devolver A. Utillizo el hyperterminal y escribo cualquier carácter pero no me responde nada. No sé si es que no tengo bien configurado el hyperterminal o es que no tengo bien conectados los Jumpers. Por favor necesito ayuda urgente.
El código del programa es: 

```
#include  "msp430g2553.h"

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  BCSCTL1 = CALBC1_1MHZ;                    // Set DCO
  DCOCTL = CALDCO_1MHZ;
  P1SEL = BIT1 + BIT2 ;                     // P1.1 = RXD, P1.2=TXD
  P1SEL2 = BIT1 + BIT2 ;                     // P1.1 = RXD, P1.2=TXD
  UCA0CTL1 |= UCSSEL_2;                     // SMCLK
  UCA0BR0 = 104;                            // 1MHz 9600
  UCA0BR1 = 0;                              // 1MHz 9600
  UCA0MCTL = UCBRS0;                        // Modulation UCBRSx = 1
  UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
  IE2 |= UCA0RXIE;                          // Enable USCI_A0 RX interrupt

  __bis_SR_register(LPM0_bits + GIE);       // Enter LPM0, interrupts enabled
}

//  Echo back RXed character, confirm TX buffer is ready first
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
  while (!(IFG2&UCA0TXIFG));                // USCI_A0 TX buffer ready?
  UCA0TXBUF = UCA0RXBUF;                    // TX -> RXed character
}
```

En el pdf adjunto tengo 2 fotos de como entiendo que son las 2 opciones que hay para conectar los jumpers en J3.

Por favor espero vuestra ayuda. muchisimas gracias.


----------



## 203toni (Ene 9, 2013)

hander dijo:


> Hola, tengo la versión nueva del LaunchPad que viene con el microcontrolador msp430g2553 y estoy tratando de aprender a configurar la UART. Estoy utilizando el archivo msp430g2xx3_uscia0_uart_01_9600.c que lo que hace es hacer eco de lo que le llega del PC, es decir si le mando el caracter A me debería de devolver A. Utillizo el hyperterminal y escribo cualquier carácter pero no me responde nada. No sé si es que no tengo bien configurado el hyperterminal o es que no tengo bien conectados los Jumpers. Por favor necesito ayuda urgente.
> El código del programa es:
> 
> ```
> ...



Pues creo que te sucede algo parecido a lo que me pasó a mí. 
Lo primero pienso que los jumpers tienen que estar en horizontal ya que es una conexión a través del USB del micro al PC ¿Supongo?. 
Pero yo estuve probando las diferentes soluciones que hay en las anteriores respuestas y no encontré solución. Los datos salían del micro pero el hyperterminal no aparecían... al final tuve que descartar esa opción. No se donde está el problema.

Suerte, un saludo!!


----------



## hander (Ene 9, 2013)

Ey!  203toni ya he encontrado la solución. he puesto los jumpers de forma horizontal y me funciona. En el pdf adjunto te paso como tienes que conectar los jumpers y te digo la configuración que usé del hyperterminal paso por paso (con fotos).

Espero que te sirva. Un saludo


----------



## kikecompilator (Feb 5, 2014)

Buenas.
Soy otro de los aventurados con esto de los microcontroladores.
Tengo un launchpad v1.5 con msp4302553G entre otros.
El mismo ejemplo y caso que os pasa a vosotros, es decir, no me rula este ejemplo básico de eco usando el hyperterminal.
Al principio pensaba que iba pero me di cuenta que todo era apariencia.

Me explico:
Con este ejemplo básico si se activa el eco de los caracteres que introducimos localmente en el hyperterminal lo que se consigue es que haga eco local, en vez de recibir el eco proveniente desde el microcontrolador.De esto puede percatarse uno mismo poniendo un punto de ruptura en la ISR de recepción y observando que no se llega a ese breakpoint pulsando cualquier tecla a excepción de la tecla intro que si lo hace. Para hacerlo mas legible y sin tener que acudir al modo despuración, yo he escrito en la propia ISR una par de lineas para encender alternadamente el led rojo o el verde cuando se reciba algo.Pues bien dichos leds no se encienden, así que hay algo que no esta bien y no sé que cosa es.

Y os digo como he llegado a pensar todo esto:
Resulta que cuando probé con el hyperterminal y metí una "p", este me mostraba "pp".
Hasta aquí súper ilusionado, pero procedí a probar otro ejemplo de Texas, el ejemplo que te devuelve de eco una string "Hello World".
Lo que pasó fue que seguía recibiendo "pp" y pensé "la placa sigue con el mismo código de antes", volví grabar el nuevo y de nuevo pasaba.."pp".
Entonces pensé, esto no va y para asegurarme desconecte la alimentación de la placa y deje solo conectado el cable de TX y RX que va a los pines Rx y Tx del puerto com1 respectivamente y vino la sorpresa.
Seguía dando  eco "pp". Así que por último quité los cables de Rx y Tx y ahora no hacia eco, sólo mostraba "p".
Lógicamente sin haber alimentación del chip no es posible que funcione y menos que de eco en este caso.
Por lo tanto la conclusión fue que estando conectadolos los cables del com1 a  Rx y Tx del microcontrolador  el circuito se cierra y viene a ser como si se puentease Rx con Tx en el puerto com1 y esto da el dichoso eco "pp".
He comprobado esto poniendo un jumper de Rx a Tx en el conector del puerto com1.

Bueno en resumen sigo con el problema.
Si alguien puede ayudar lo agradecería, mientras sigo investigando.
Un saludo a todos.

Os dejo mi código:

```
#include <msp430.h>
unsigned int estado=0;
int main(void)
{
  P1DIR=0xFF;
  P1OUT=0x00;
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  if (CALBC1_1MHZ==0xFF)                    // If calibration constant erased
  {                                            
    while(1);                               // do not load, trap CPU!!    
  }
  DCOCTL = 0;                               // Select lowest DCOx and MODx settings
  BCSCTL1 = CALBC1_1MHZ;                    // Set DCO
  DCOCTL = CALDCO_1MHZ;
  P1SEL = BIT1 + BIT2 ;                     // P1.1 = RXD, P1.2=TXD
  P1SEL2 = BIT1 + BIT2 ;                    // P1.1 = RXD, P1.2=TXD
  UCA0CTL1 |= UCSSEL_2;                     // SMCLK
  UCA0BR0 = 104;                            // 1MHz 9600
  UCA0BR1 = 0;                              // 1MHz 9600
  UCA0MCTL = UCBRS0;                        // Modulation UCBRSx = 1
  UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
  IE2 |= UCA0RXIE;                          // Enable USCI_A0 RX interrupt

  __bis_SR_register(LPM0_bits + GIE);       // Enter LPM0, interrupts enabled
}

//  Echo back RXed character, confirm TX buffer is ready first
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
  while (!(IFG2&UCA0TXIFG));                // USCI_A0 TX buffer ready?
  UCA0TXBUF = UCA0RXBUF;                    // TX -> RXed character
  if(estado==0)
      P1OUT=0x01;
  else
      P1OUT=0x40;
  estado^=0x01;
}
```


----------



## Nuyel (Feb 10, 2014)

kikecompilator tu ejemplo trabaja correctamente, pero te diré otra cosa, resulta que cuando intenté probarlo no me funcionó, recibía la cadena que el chip enviaba pero no recibía de la computadora, tuve que probar usando el eZ430-FET conectado lo a la LaunchPad y funcionó, revisé los voltajes y el ez430-FET da 3,5V en las lineas del UART sin nada conectado pero el LauchPad marca 1,2 en la TX, así que parece que no puede darle los datos al chip, no se como se habrá dañado, verifica en la tuya.


----------



## kikecompilator (Feb 10, 2014)

Buenas.
Lo primero muchas gracias por responder.
y bueno te digo lo que pasa, resulta que si 
el ejemplo basico de la uart se modifica para
enviar un caracter en vez el byte que recibe el 
mc, entonces con el com virtual com 7 funciona.
Yo en concreto pongo que si se recibe un 0 envie
una a y si se recibe un 1 envie una e.Ahora bien 
cuando se prueba este mismo ejemplo con un com
fisico conectandolo a un pc via cable entonces se 
observa en el hyperterminal que llegar llega el byte
que anteriormente se envio al mc en vez de uno de
los caracteres a o e. Es decir es como si rx estuviese puenteado con tx, y es que en este caso lo esta porque
los pines del j3 lo hacen activando el com virtual.
En base a ello probe quitando todos los jumpersde j3 y alimentando la placa a parte y vuelve a pasar lo mismo.
Asi que he abierto un post en el foro de Ti y me estan ayudando aunque por ahora no rula.
Lo que esta claro es que el mc escribir escribe en Tx porque si no no funcionaria con el com virtual, ya que Rx recibe lo que sale por Tx en este modo.
Bueno si me dicen algo nuevo y hay novedades lo digo aqui.
Gracias por tu info,la tendre en cuenta.


----------

