Hello guys! I'm new to ARM7 and I'm using a MCB2140 board from Keil with LPC2138. Well, I'm having some issues to communicate via UART0 to my PC. Could someone take a look to my code and give some tips?
I have researched on Keil's forum, and found this thread, from 10 years ago: http://www.keil.com/forum/9719/
I have UART0 and UART1 configured at the same way in my code. When I try to send data via UART0, nothing happens. But, via UART1 the data is sent. I dont if it's a program or a jumper board issue.
Here is my code. Most comments are in portuguese, sorry.
#include <lpc213x.h> void config_pins (void); void init_pll (void); void init_uart0 (void); void uart0_write(char data); void init_uart1 (void); void uart1_write(char data); void config_timer0_compare (void); void config_timer1_compare (void); void delay_us(unsigned int microseconds); void delay_ms(unsigned int miliseconds); int main (void) { config_pins(); init_pll(); config_timer0_compare(); config_timer1_compare(); init_uart0(); char msg[] = { 'H','I','\0' }; int c=0; // counter while(1) { IO1SET = (1<<16); //LED ON delay_ms(500); //delay 1s IO1CLR = (1<<16); //LED OFF delay_us(500000); //delay 1s while( msg[c]!='\0' ) { uart0_write(msg[c]); c++; } uart0_write('\n'); //get to the next line below c=0; // reset counter } } void init_uart1 (void) { PINSEL0 = 0x00050000; //Enable uart1 RxD1 and TxD1 //U0LCR = 3 | (1<<7) ; //8 bits, no Parity, 1 Stop bit | DLAB set to 1 U1LCR = 0x83; //8-bit, 1 stop bit, no parity, enable divisor latch //Divisores para BAUDRATE: 9600 U1DLM = 0x01; U1DLL = 0x86; U1LCR = 0X03; //DLAB set to 0 } void uart1_write(char data) { while ( !(U1LSR & (1<<5) ) ); // wait till the THR is empty // now we can write to the Tx FIFO U1THR = data; } void init_uart0 (void) { PINSEL0 = 0x00000005; //TxD P0.0 RxD P0.1 //U0LCR = 3 | (1<<7) ; //8 bits, no Parity, 1 Stop bit | DLAB set to 1 U0LCR = 0x83; //8-bit, 1 stop bit, no parity, enable divisor latch //Divisores para BAUDRATE: 9600 U0DLM = 0x01; U0DLL = 0x86; U0LCR = 0X03; //DLAB set to 0 } void uart0_write(char data) { while ( !(U0LSR & (1<<5) ) ); // wait till the THR is empty // now we can write to the Tx FIFO U0THR = data; } void config_pins (void) { //Pino P1.16 como saida IODIR1 = (1<<16); //Pino P1.16 ao¨P1.24 como saida //for (int i = (1<<16); i <= (1<<24); i <<= 1) //{ // IODIR1 = IODIR1 | i; //Incrementa 1 em IODIR, caso contrario deixaria como 0 //} IODIR1 = 0xFF0000; //Seta P1.16, P1.20-23 em nivel 1 IOSET1 = 0x00F10000; } void init_pll (void) { //Configura M e P PLL PLLCFG = 0x024; //P:2 M:5 //01 00100 //100101 = 0x24 //Sequencia FEED para alterar parametros PLL PLLFEED = 0xAA; PLLFEED = 0x55; //Habilita PLL PLLCON = 0x01; //Sequencia FEED para alterar parametros PLL PLLFEED = 0xAA; PLLFEED = 0x55; // Quando lock status, que esta no bit 10, mudar para 1, sai do while. Somente quando mudar para 1 poderemos prosseguir while (!(PLLSTAT & 0x0400)); //mantem o PLL em enable e conecta o PLL à CPU PLLCON = 0x03; //Sequencia FEED para alterar parametros PLL PLLFEED = 0xAA; PLLFEED = 0x55; //Coloca divisor de PCLK = CCLK VPBDIV = 0x01; } void config_timer0_compare (void) { //Assumindo que PCLK: 60MHz //Timer 0: 1 ms // T0CTCR = 0x0; //Sera incrementado pelo PCLK, borda de subida // // T0PR = 60000-1; //Valor prescale: a cada 60000 ciclos de CCLK incrementa 1 TOTC = 1ms // //Conta inicia em 0, por isso o -1 // // T0TCR = 0x02; //Reseta timer //Timer 0: 1 us T0CTCR = 0x0; //Sera incrementado pelo PCLK, borda de subida T0PR = 60-1; //Valor prescale: a cada 60 ciclos de CCLK incrementa 1 TOTC = 1us //Conta inicia em 0, por isso o -1 T0TCR = 0x02; //Reseta timer } void config_timer1_compare (void) { //Assumindo que PCLK: 60MHz //Timer 1: 1 ms T1CTCR = 0x0; //Sera incrementado pelo PCLK, borda de subida T1PR = 60000-1; //Valor prescale: a cada 60000 ciclos de CCLK incrementa 1 TOTC = 1ms //Conta inicia em 0, por isso o -1 T1TCR = 0x02; //Reseta timer } void delay_us(unsigned int microseconds) { //1s = 1000ms = 1000000us //Utilizando timer0 para esta funcao T0TCR = 0x02; //Reseta timer0 T0TCR = 0x01; //Habilita timer0 //T0TC armazena valor contador while(T0TC < microseconds); //aguarda ate que timer chegue ao valor requerido T0TCR = 0x00; //Desabilita timer0 } void delay_ms(unsigned int miliseconds) { //1s = 1000ms //Utilizando timer1 para esta funcao T1TCR = 0x02; //Reseta timer0 T1TCR = 0x01; //Habilita timer0 //T0TC armazena valor contador while(T1TC < miliseconds); //aguarda ate que timer chegue ao valor requerido T1TCR = 0x00; //Desabilita timer0 }
In main, I can change the data source, from UART0 or UART1
int main (void) { config_pins(); init_pll(); config_timer0_compare(); config_timer1_compare(); init_uart0(); char msg[] = { 'H','I','\0' }; int c=0; // counter while(1) { IO1SET = (1<<16); //LED ON delay_ms(500); //delay 1s IO1CLR = (1<<16); //LED OFF delay_us(500000); //delay 1s while( msg[c]!='\0' ) { uart0_write(msg[c]); c++; } uart0_write('\n'); //get to the next line below c=0; // reset counter } }
We figured out.
#1 The #include <lpc213x.h> was wrong, change it for: #include <lpc214x.h>, because MCB2140 has a LPC2148.
#2 If you are using a ULINK2, download the program normally to the board. Then remove the jumpers J1(ISP) and J10(RST).
And enjoy your MCB2140 UART0 properly (: