1
\$\begingroup\$

I've been trying to configure UART module of LPC1768. Board comes with a crystal oscillator of 12Mhz. It does nothing more than receiving a character and transmitting it at the same time. I am using Keil simulator. This is the code,

#include <LPC17xx.H>

void uart_init()
{
    LPC_PINCON->PINSEL0 = 0X0500000;
    LPC_UART2->LCR = 0X83;
    LPC_UART2->DLL = 162;
    LPC_UART2->LCR = 0X03;
}

int main()
{
    uart_init();

    while(1)
    {
        while(LPC_UART2->LSR & (1<<0));
        LPC_UART2->THR = LPC_UART2->RBR;
        while(LPC_UART2->LSR & (1<<6));
    }
}

I'm not configuring any PLL register, only using default values.

I"ve referred several forums to find the baud rate, https://www.google.co.in/search?q=lp1768+pclk&rlz=1C1CHBF_enIN754IN754&oq=lp1768+pclk&aqs=chrome..69i57.5207j0j1&sourceid=chrome&ie=UTF-8

By referring system_LPC17xx.c,

#define CLOCK_SETUP           1
#define SCS_Val               0x00000020
#define CLKSRCSEL_Val         0x00000001
#define PLL0_SETUP            1
#define PLL0CFG_Val           0x00050063
#define PLL1_SETUP            1
#define PLL1CFG_Val           0x00000023
#define CCLKCFG_Val           0x00000003
#define USBCLKCFG_Val         0x00000000
#define PCLKSEL0_Val          0x00000000
#define PCLKSEL1_Val          0x00000000
#define PCONP_Val             0x042887DE
#define CLKOUTCFG_Val         0x00000000

From #define PLL0CFG_Val 0x00050063,

Bit 14-0 supplies the M value, and the value stored here is M-1; 0x0063 which is 99 in decimal, So M = 100,

Bit 23-16 Supplies the value "N", The value stored here is N - 1; 0x05=5 in decimal, so N = 6

From #define CCLKCFG_Val 0x00000003,

Bit 7-0, Selects the divide value for creating the CPU clock (CCLK), By putting a value of 3, CCLK = PLLCLK/4

I'm using UART2, which comes under PCLKSEL2,

From #define PCLKSEL2_Val 0x00000000,

when set 0, PCLK_peripheral = CCLK/4

TO find PLL0 freq, PLL0_clk = (2 * M * FOSC) / N Cr ==>PLL0CLK = (2 * 100 * 12)/6 ==>PLL0CLK = 400Mhz

Now, CCLK = PPL0CLk/4 ==>CCLk = 400 / 4 = 100Mhz

and PCLK = CCLK/4 = 100/4 = 25Mhz

To calculate DLL, DLL = PCLK/(16 * Baud rate) for 9600 Bpm, DLL = 25000000/(16 * 9600) ==>DLL = 162

But I can't transmit or receive anything when I tried to simulate the program I've only limited knowledge in ARM, that's why I wrote my calculation method so that anyone can correct me if I'm wrong.

Also, In the datasheet, they've given a table showing Multiplier values for PLL0 with a 32 kHz input enter image description here

But using this equation PLL0_clk = (2 * M * FOSC) / N, I couldn't find any value given in the table, eg: for M = 4272 and N = 1, PLL0clk = (2 * 4272 * 32)/1 = 273408 kHz, 273.408 Mhz, But in given table it's 279.9698

Thanks

\$\endgroup\$
2
\$\begingroup\$

It might be because the "32kHz" is actually 32.768 kHz

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ For example: 32,768 * 2 * 4272 = 279,969,792. Not sure where the extra factor of two comes from, but it's probably explained somewhere in the datasheet. Note that I got this by simply dividing the two numbers in one entry of the table: 279.9698 MHz/4272 = 65536.00187 kHz, which is obviously a power of 2, plus or minus a small round-off error. \$\endgroup\$ – Dave Tweed Apr 16 '18 at 20:31
  • \$\begingroup\$ Thanks for the reply. That was my second question. First question was about configuring UART2 for a baud rate of 9600. External crystal oscillator used is 12Mhz. I used above equations to calculate DLL, but couldn't make the uart work \$\endgroup\$ – Athul Apr 17 '18 at 9:13
  • \$\begingroup\$ How are you testing the UART - are you using another comm port to listen to it (so that baud rates, etc., must match), or are you using a scope? \$\endgroup\$ – mike65535 Apr 17 '18 at 14:33
  • \$\begingroup\$ I'm simulating it in Keil4. Either receive a character and sent it to give it to THR register to view it. or by setting LPC_UART2->THR = 'A'; while(LPC_UART2->LSR & (1<<6)); \$\endgroup\$ – Athul Apr 17 '18 at 20:50
0
\$\begingroup\$
  1. In keil4, in debugging mode, view->serial windows ==> UART #*

UART#1 = UART0 module of LPC1768

UART#2 = UART1 module of LPC1768

UART#3 = No idea!! ; I tried this window for UART2 & 3 but didn't work I will ask this in KEIL forum

If I change my code this way,

#include <LPC17xx.H>

void uart_init()
{
    LPC_PINCON->PINSEL0 |= 5 << 4; //uart 0
//  LPC_PINCON->PINSEL0 |= 5 << 20; //uart 2
//  LPC_PINCON->PINSEL0 |= 1 << 30; //uart 1
//  LPC_PINCON->PINSEL1 |= 0x01; //uart 1
//  LPC_PINCON->PINSEL0 |= 0X0A; //uart 3
    LPC_UART0->LCR = 0X83;
    LPC_UART0->DLL = 162;
    LPC_UART0->LCR = 0X03;
}

int main()
{
    uart_init();

    while(1)
    {
        while(!(LPC_UART0->LSR & (1<<0)));
        LPC_UART0->THR = LPC_UART0->RBR;
        while(!(LPC_UART0->LSR & (1<<5)));
    }
}

I could view recieved characters in the UART#0 window of KEIL.

  1. I made some mistakes in my code when I asked the question,

while((LPC_UART0->LSR & (1<<0))); LPC_UART0->THR = LPC_UART0->RBR; while((LPC_UART0->LSR & (1<<5)));

It should be,

while(!(LPC_UART0->LSR & (1<<0))); LPC_UART0->THR = LPC_UART0->RBR; while(!(LPC_UART0->LSR & (1<<5))); enter image description here

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.