EmbeddedRelated.com
Forums

Problem getting simple UART working on LPC2148

Started by vg8open November 3, 2007
Hello,

I am having some problem getting the UART working on the PLC2148. I
am trying to send a character to the PC, but all I got was junk. Can
some one look over my code to see what's going on?

thanks,

---------------

#include

void init (void)
{
U0IER = 0x00; //-disable all interrupts
U0IIR; //-clear interrupt ID
U0RBR; //-clear receive register
U0LSR; //-clear line status register

//-Init Clock
PLL0CON = 0x1; //-Activate the PLL
PLL0CFG = 0x14; //-CCLK = Fosc x 5 = 60MHz, Fcco = 240MHz
PLL0FEED=0xAA; //-This sequence must be written to the PLLFEED
register in order
PLL0FEED=0x55; //for changes to the PLLCON and PLLCFG registers to
take effect
while(!(PLL0STAT & 0x0400)); //-Wait until PLL is locked onto the
requested frequency.
//PLL0CON=0x3; //-Use PLL as a clock source for the processor,
instead of Fosc
//PLL0FEED=0xAA;
//PLL0FEED=0x55;
VPBDIV = 0x1; //-APB bus clock (PCLK) set to be the same as the
processor clock

//-Init Pins
SCS = 0x3; //-Using fast GPIO, no backward compatibility
PINSEL0 |= 0x5; //-Enable p0.0 and p0.1 as TX and RX respectively

//-Initilize UART
U0LCR = 0x83; //-8 bit character length, 1 stop bit, no parity,
enable DLAB (to set U0DLL & U0DLM)
U0DLL = 0x25; //-U0DLL, U0DLM, and U0FDR set baud rate to 9600
U0DLM = 0x00;
U0FDR = 0x9A;

U0LCR = 0x3; //-Clear DLAB - now the divisor registers can't be modified
// and access to the TX and RX buffers is available
U0FCR = 0x7; //-Enable UART0 Rx and TX FIFOs and U0FCR[7:1] access,
clear all bytes in UART0 Rx and Tx FIFO

}
void SendChar (unsigned char data)
{
while ((U0LSR & 0x20) == 0); // wait for completion of previous data
U0THR = data;
}
unsigned char GetData (void)
{
while ((U0LSR & 0x01) == 0); // wait for data
return U0RBR;
}

int main (void)
{
char temp;

init();
while(1)
{
//temp = GetData();
SendChar('c');
}
}
----------------------------------

An Engineer's Guide to the LPC2100 Series

1) Where is the problem? uC, PC or cable?

Scope the tx output to see if a stream of 'c' characters is being sent
at 9.6k. If it then clear that your code is at fault, you have a
better idea where to look for the problem.

Rgds,
Martin
When I look in HyperTerminal on the PC, all I see are junk characters.
I don't have access to an oscilloscope at the moment, so I am not
sure if the characters are being send at 9600bps.

-Brian
--- In l..., "mjames_doveridge" wrote:
>
> 1) Where is the problem? uC, PC or cable?
>
> Scope the tx output to see if a stream of 'c' characters is being sent
> at 9.6k. If it then clear that your code is at fault, you have a
> better idea where to look for the problem.
>
> Rgds,
> Martin
>
vg8open wrote:
> When I look in HyperTerminal on the PC, all I see are junk characters.
> I don't have access to an oscilloscope at the moment, so I am not
> sure if the characters are being send at 9600bps.
>

I would suspect your DLL, DLM, and FDR values.

U0DLL = 0x25; //-U0DLL, U0DLM, and U0FDR set baud rate to 9600
U0DLM = 0x00;
U0FDR = 0x9A;
These are some valid settings for a PCLK of 60MHz:

DLM DLL MULVAL DIVADDVAL Actual % Err
--- --- ------ --------- --------- --------
0 186 10 11 9600.61 0.006401
1 23 15 6 9600.61 0.006403
1 23 5 2 9600.61 0.006403
1 23 10 4 9600.61 0.006403
> -----Original Message-----
> From: l...
> [mailto:l...]On Behalf
> Of vg8open
> Sent: Saturday, November 03, 2007 3:20 PM
> To: l...
> Subject: [lpc2000] Re: Problem getting simple UART working on LPC2148
> Joel,
>
> I am confused.
>
> I have a 12MHz crystal for my processor. I assigned the VPBDIV = 0x1,
> which set the PCLK to 12MHz.
>
> As I understand, the UART only use the PCLK to determine the baud
> rate, not the CCLK, which is 60MHz. Am I correct or did I
> miss something?
>
> I tried some of the value you recommended, but it didn't work either.
>
> Thanks,
>
> brian

Correct, the baud rate is dependant on PCLK. But PCLK is derived from
the CCLK, so you need to divide CCLK by 5 to get 12MHz, which is not
possible.
By setting VPBDIV to 1, you are using a PCLK of 60MHz.

Mike
>From my code earlier, I set PLL0CON = 0x1, which activated the PLL,
but didn't use the PLL for the processor clock. For some reasons,
when I set PLL0CON = 0x3 to use the PLL as the clock for the
processor, the processor hang up and never get pass the following code:

PLL0CON = 0x3;
PLL0CFG = 0x14;
PLL0FEED=0xAA;
PLL0FEED=0x55;
while(!(PLL0STAT & 0x0400));

do you know why?
--- In l..., "Michael Anton" wrote:
>
> > -----Original Message-----
> > From: l...
> > [mailto:l...]On Behalf
> > Of vg8open
> > Sent: Saturday, November 03, 2007 3:20 PM
> > To: l...
> > Subject: [lpc2000] Re: Problem getting simple UART working on LPC2148
> >
> >
> > Joel,
> >
> > I am confused.
> >
> > I have a 12MHz crystal for my processor. I assigned the VPBDIV = 0x1,
> > which set the PCLK to 12MHz.
> >
> > As I understand, the UART only use the PCLK to determine the baud
> > rate, not the CCLK, which is 60MHz. Am I correct or did I
> > miss something?
> >
> > I tried some of the value you recommended, but it didn't work either.
> >
> > Thanks,
> >
> > brian
> >
> > Correct, the baud rate is dependant on PCLK. But PCLK is derived from
> the CCLK, so you need to divide CCLK by 5 to get 12MHz, which is not
> possible.
> By setting VPBDIV to 1, you are using a PCLK of 60MHz.
>
> Mike
>
> -----Original Message-----
> From: l...
> [mailto:l...]On Behalf
> Of vg8open
> Sent: Saturday, November 03, 2007 4:49 PM
> To: l...
> Subject: [lpc2000] Re: Problem getting simple UART working on LPC2148
> From my code earlier, I set PLL0CON = 0x1, which activated the PLL,
> but didn't use the PLL for the processor clock. For some reasons,
> when I set PLL0CON = 0x3 to use the PLL as the clock for the
> processor, the processor hang up and never get pass the
> following code:
>
> PLL0CON = 0x3;
> PLL0CFG = 0x14;
> PLL0FEED=0xAA;
> PLL0FEED=0x55;
> while(!(PLL0STAT & 0x0400));
>
> do you know why?
>

I know that I enable the PLL, wait for lock, and then connect it. I'm
not sure if it will work done another way, but this is how the user
manual says it should be done.

Here is the code I use:
// Setup PLL0 for the main oscillator
PLL0CFG = MSEL(PLL0_MSEL) | PSEL(PLL0_PSEL); // Set multiplier and
divider
PLL0CON = PLLE; // Enable PLL
feed(PLL0FEED); // Feed sequence

while (!(PLL0STAT & PLOCK)) // Wait for PLL lock (PLOCK bit is set if
locked)
;
PLL0CON = PLLE | PLLC; // Connect and enable the PLL
feed(PLL0FEED); // Feed sequence

Remember that the feed sequences must be done with interrupts disabled.

Good luck,

Mike
On Sat, 3 Nov 2007, Michael Anton wrote:

> Remember that the [PLL] feed sequences must be done with interrupts
> disabled.

(Well, except the PLL IRQ on some chips, (if used) of course :))

-Kenny

--
Kenneth R. Crudup Sr. SW Engineer, Scott County Consulting, Los Angeles
O: 3630 S. Sepulveda Blvd. #138, L.A., CA 90034-6809 (888) 454-8181
Ok, I finally found the problem. I overlook the bits assigned to PSEL
[bits 6-5] (I though it was bits 5 and 4), and so I set the PSEL wrong
value to the PLL0CFG register. It need to be PSEL = 0x2 which give
PLL0CFG = 0x24.

Thank you everyone. I appreciate you taking your time helping me.

-brian

--- In l..., "Michael Anton" wrote:
>
> > -----Original Message-----
> > From: l...
> > [mailto:l...]On Behalf
> > Of vg8open
> > Sent: Saturday, November 03, 2007 4:49 PM
> > To: l...
> > Subject: [lpc2000] Re: Problem getting simple UART working on LPC2148
> >
> >
> > From my code earlier, I set PLL0CON = 0x1, which activated the PLL,
> > but didn't use the PLL for the processor clock. For some reasons,
> > when I set PLL0CON = 0x3 to use the PLL as the clock for the
> > processor, the processor hang up and never get pass the
> > following code:
> >
> > PLL0CON = 0x3;
> > PLL0CFG = 0x14;
> > PLL0FEED=0xAA;
> > PLL0FEED=0x55;
> > while(!(PLL0STAT & 0x0400));
> >
> > do you know why?
> > I know that I enable the PLL, wait for lock, and then connect it. I'm
> not sure if it will work done another way, but this is how the user
> manual says it should be done.
>
> Here is the code I use:
> // Setup PLL0 for the main oscillator
> PLL0CFG = MSEL(PLL0_MSEL) | PSEL(PLL0_PSEL); // Set multiplier and
> divider
> PLL0CON = PLLE; // Enable PLL
> feed(PLL0FEED); // Feed sequence
>
> while (!(PLL0STAT & PLOCK)) // Wait for PLL lock (PLOCK bit is set if
> locked)
> ;
> PLL0CON = PLLE | PLLC; // Connect and enable the PLL
> feed(PLL0FEED); // Feed sequence
>
> Remember that the feed sequences must be done with interrupts disabled.
>
> Good luck,
>
> Mike
>
Joel,

I am confused.

I have a 12MHz crystal for my processor. I assigned the VPBDIV = 0x1,
which set the PCLK to 12MHz.

As I understand, the UART only use the PCLK to determine the baud
rate, not the CCLK, which is 60MHz. Am I correct or did I miss something?

I tried some of the value you recommended, but it didn't work either.

Thanks,

brian

--- In l..., Joel Winarske wrote:
>
> vg8open wrote:
> > When I look in HyperTerminal on the PC, all I see are junk characters.
> > I don't have access to an oscilloscope at the moment, so I am not
> > sure if the characters are being send at 9600bps.
> >
>
> I would suspect your DLL, DLM, and FDR values.
>
> U0DLL = 0x25; //-U0DLL, U0DLM, and U0FDR set baud rate to 9600
> U0DLM = 0x00;
> U0FDR = 0x9A;
> These are some valid settings for a PCLK of 60MHz:
>
> DLM DLL MULVAL DIVADDVAL Actual % Err
> --- --- ------ --------- --------- --------
> 0 186 10 11 9600.61 0.006401
> 1 23 15 6 9600.61 0.006403
> 1 23 5 2 9600.61 0.006403
> 1 23 10 4 9600.61 0.006403
>