TODOPIC
Otros Microcontroladores / Dispositivos programables => Microcontroladores ARM => Mensaje iniciado por: martaelectronica en 04 de Marzo de 2014, 13:02:01
-
Hola,
He desarrollado una placa con un ARM LPC2114 y estoy intentando lograr la comunicación serial por puerto serie y no logro ver nada por el hyperterminal.
Mi placa posee un cristal de 12MHz y tengo configurada la UART0 a 38400 baudios.
El micro se graba perfectamente, pero al conectar al hyperterminal no muestra nada, sólo caracteres sueltos al llamar y descolgar en el terminal.
Estoy usando un código sencillito que muestre por pantalla contínuamente: "Esto es una demostración" ç
El puerto COM seleccionado y la velocidad y todo lo he revisado en el hyperterminal pero no sé por qué no sincroniza.
¿Alguien me puede ayudar?
Muchas gracias
/**********************************************************
Function prototypes
**********************************************************/
void _U0prtnum(unsigned int);
void _U0prthex(unsigned int);
void _U0prthex8(unsigned char);
void _U0puts(unsigned char *);
void _U0putch(unsigned char);
unsigned char _U0getch();
void _delay_loop(unsigned int);
/**********************************************************
Header files
**********************************************************/
#include "lpc2114.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FOSC 12000000 // 14745600 // Crystal frequency
#define MSEL 5 // PLL multiplier
#define CCLK (FOSC*MSEL) // CPU clock
#define PCKDIV 1 // APB divider
#define PCLK (CCLK/PCKDIV) // Peripheral clock
// delays
#define _delay_us(n) _delay_loop(CCLK/4000000*n-1)
#define _delay_ms(n) _delay_loop(CCLK/4000*n-1)
// ===================================================================
#define U0LSR_DR (U0LSR&(1<<0))
#define U0LSR_OE (U0LSR&(1<<1))
#define U0LSR_PE (U0LSR&(1<<2))
#define U0LSR_FE (U0LSR&(1<<3))
#define U0LSR_BI (U0LSR&(1<<4))
#define U0LSR_THR_E (U0LSR&(1<<5))
#define U0LSR_TX_E (U0LSR&(1<<6))
#define U0LSR_RX_ERROR (U0LSR&(1<<7))
void UART0_Init()
{
U0LCR = 0x83; // 10000011 Line Control Register
// .. Character length 11 = 8 bits
// . Stop bits 0 = 1 bit
// . Parity enable 0 = No parity
// . Even parity non sense
// . Stick parity non sense
// . Break control 0 = No break
// . DLAB 1 = Access to DLM,DLL
U0DLL = 98;
U0DLM = 0; // Baud = 5*12000000/(16* 98) = 38400
U0LCR = 0x03; // Same a above, but DLAB = 0 = Normal access to RBR/THR & IER
U0FCR = 0x07; // 00000111 FIFO Control Register
// . FIFO enable 1 = TX&RX FIFOs enabled
// . RX FIFO Reset 1 = Reset RX FIFO
// . TX FIFO Reset 1 = Reset TX FIFO
// .. RX interrupt trigger level 00 = 1 byte
};
void UART0_putch(char c)
{
while(!(U0LSR_THR_E)); // mientras que U0LSR.THRE == 0
U0THR = c;
IOSET0 |=(1<<19);
}
char UART0_getch()
{
while(!(U0LSR_DR)); // mientras que U0LSR.DR == 0
return U0RBR;
}
void print(char * s)
{
int i;
i= 0;
while(s[i]) UART0_putch(s[i++]);
}
/**********************************************************
MAIN SECTION
**********************************************************/
///////////////////////////////// The actual MAIN ///////////////////////////
int main (void)
{
char c;
char S[]="Hola caracola\r\n";
PINSEL1 &=(3<<30); // P0.31 is GPIO
IODIR0 |=(1<<31); // P0.31 is output
IOSET0 |=(1<<31); // P0.31 high
PINSEL1 &=(7<<19); //P0.19,P0.20,P0.21 is GPIO
IODIR0 |=(1<<19); // P0.19 is output
UART0_Init();
print( S );
print("Esto es una demostracion\r\n");
while(1)
{
print("Esto es una demostracion\r\n");
//c = UART0_getch();
//UART0_putch(c);
//if(IOPIN0&(1<<31)) IOCLR0|=(1<<31);
//else IOSET0|=(1<<31);
}
}
-
El programa se queda en alguna parte? no entraste en modo debug para ejecutar paso a paso? podes poner un osciloscopio a la salida del pin Tx del micro para ver que realmente tengas datos saliendo y que la velocidad sea correcta?
Saludos!
-
Hola,
Gracias por responder tan rápido.
EL programa se que corre sin problemas tras grabar el micro. El "make" y grabar el programa lo hago desde el propio cmd.exe de windows dentro del directorio donde tengo el proyecto.
Ejecuto el código programado que es el que envíe en mi primera entrada ("make terminal") y en el propio cmd sale contínuamente "Esto es una demostración" que es lo deseado.
El problema es que en el hyperterminal no sale nada , sólo si le doy al reset pone algunos caracteres pero nada más.
He comprobado como me sugieres con el osciloscopio la salida TXD del micro y funciona y realmente está transmitiendo pulso y todo en orden.
Ahora mismo estoy pensando que puede que los pines que tengo conectados al /RESET y al BOOTLOADER que pasan por un FTDI232RL sean el problema. Es decir, que en estas patillas no exista un nivel adecuado puesto que las tengo conectadas al /DTR y /RTS , respectivamente, del driver usb. Cuando ejecuto en el cmd.exe el código (make terminal) es el propio programa del bootloader el que me debe estar poniendo los niveles correctos y puede que en el hyperterminal de windows el USB no tenga esos niveles adecuados.
Estoy dándole vueltas a esto pero no llego a nada en claro aún....
De todas formas muchas gracias por tu consejo y ayuda porque aún no me había parado a comprobarlo :)
Un saludo.
-
Otra cosa que debeias verificar con el osciloscopio es el ancho de pulso de un 1 o un 0. Para 38kb serían 26.04useg aproximadamente. A lo mejor configuras el UART suponiendo una velocidad y le erras en el cálculo...
Te nombro todas las cosas que me han pasado cuando pongo una uart de un uC a funcionar por primera vez y siempre me ha servido primero ver que salga del micro la señal de forma correcta. Con eso ya sabes si es software o hardware. Luego avanzar...
Saludos!
PD: me comentarías un poco las caracteristicas del micro que estas usando? es un ARM7? como queda en comparacion con un cortex m3, por ejemplo el 1769 (que uso yo)?
Saludos!
-
Hola!!!
He verificado todas las patillas críticas:
-En TXD0 (del uC) tengo la señal de 8 bit, que se ve perfectamente. En total son los 8 bit de datos, 1 bit de parada y el de inicio de trama, es decir, los 10 bit a 38400 baudios y efectivamente obtengo los aproximadamente 26.62us.
-En cuanto al BOOTLOADER que pasa por el driver FTDI está funcionando correctamente cuando programo la flash (patilla P0.14 de mi microcontrlador). La configuración para poder grabar sería el RESET a nivel lógico 0 y al grabar el P0.14 baja a nivel lógico 0 para luego volver a su estado inicial.
Al tener el hyperterminal configurado sin "break Control" esta patilla no se tiene en cuenta y no afectará para nada al control de flujo.
- El RESET también funciona correctamente cuando pulso mi botón.
- Las patillas Dminus y Dplus del USB también funcionan bien y se ven los datos.
- Los parámetros y los cálculos de la UART0 están correctos con los registros ajustados bien a os 38400 con un error de aproximadamente un 3% , pero eso es debido a que mi oscilador es de 12MHz. Estoy pensando en pasarme a un cristal de 14745600 .
Seguiré investigando a ver qué ocurre.
En cuanto a tu pregunta sobre el micro que he elegido es un LPC2114 (http://www.nxp.com/documents/data_sheet/LPC2114_2124.pdf). Posee 32 bit y yo lo he elegido por sus características de velocidad. Sólo me he pegado con los dos periféricos GPIO , TIMER0/1 y las UART0/1. No parece mucho más difícil que un PIC pero al principio el cambio fue un poco tedioso. Aún no me he metido con el resto de periféricos porque para hacer el ANalizador Lógico que estoy intentando hacer no necesito más en principio. Por eso , necesito comprobar primero que mi placa transmite correctamente algo sencillo porque tengo que enviar muchas tramas de datos de 32bit que provienen de una configuración de 4 registros de desplazamiento serie/paralelo.
En cuanto al entorno de desarrollo que estoy empleando es el VSMStudio con el compilador cruzado de Yagarto y la simulación en Proteus. Aunque.... es algo complicado porque hay que crearse todos los archivos *.ld , etc.
Un saludo y gracias de nuevo.
-
Finalmente, he resuelto mi problema.
Como descarté que el problema fuera hardware gracias a tus consejos me he metido más en el funcionamiento de los pines RTS y DTR del USB que controlan desde el driver y lo he mirado desde el otro lado, es decir, mi aplicación de usuario desarrollada en Wxdevcpp.
Finalmente, he tocado mi código y he deshabilitado el dcb para el RTS y el DTR:
dcb.fRtsControl = (DWORD) RTS_CONTROL_DISABLE;
dcb.fDtrControl = (DWORD) DTR_CONTROL_DISABLE;
Estas dos líneas en mi función ABRIRCOM() han dado la solución y ya ejecuta el código contínuamente.
Muchas gracias.
Un saludo.