Please help to find the error in the code

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Please help to find the error in the code

1,061 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by akhilpo on Tue Jul 19 19:13:03 MST 2011
I am trying implement UART communication. It worked fine when using the drivers in the NXP examples. But it when I tried to implement the 'UARTInit()' on my own, it is sending occasionally some wrong characters. I have refereed the Uart driver code and the datasheet, but still cant figure out what I am doing wrong. Please help me.

#ifdef __USE_CMSIS
#include "LPC11xx.h"
#endif

#include <cr_section_macros.h>
#include <NXP/crp.h>

__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;

#include "uart.h"
// TODO: insert other definitions and declarations here

int main(void) {
    
    uint8_t key[1];
    key[0] = 'n';
    uint32_t fdiv, regVal;

    //UARTInit(115200);
    LPC_IOCON->PIO1_6 |= 1;
    LPC_IOCON->PIO1_7 |= 1;

    LPC_SYSCON->SYSAHBCLKCTRL |= 1<<12;
    LPC_SYSCON->UARTCLKDIV = 12;

    //fdiv = 48/(16*12*115200);
    regVal = LPC_SYSCON->UARTCLKDIV;

      fdiv = (((SystemCoreClock*LPC_SYSCON->SYSAHBCLKDIV)/regVal)/16)/115200 ;    /*baud rate */


    LPC_UART->LCR |= 1<<7;
    LPC_UART->DLM = fdiv/0x100;
    LPC_UART->DLL = fdiv%0x100;
    LPC_UART->LCR &= ~(1<<7);

    LPC_UART->LCR = 3;
    LPC_UART->FCR = 7;
    fdiv = LPC_UART->LSR;




    while(1){
        UARTSend(key,1);
    }
}

0 Kudos
Reply
6 Replies

1,047 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by gbm on Thu Jul 21 12:59:59 MST 2011
Actually the formula used everywhere in examples for calculating UART divisor is suboptimal (to express it nicely). The better one should be:
fdiv = (((SystemCoreClock*LPC_SYSCON->SYSAHBCLKDIV)/regVal)/16 + BAUD_RATE/2)/BAUD_RATE;

This provides proper rounding of the divisor and results in smaller baud rate errors.
0 Kudos
Reply

1,047 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by akhilpo on Wed Jul 20 18:52:00 MST 2011
:eek:Ooh silly mistakes again... its working fine now.. thanks for the calculations stephan.
0 Kudos
Reply

1,047 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by StephenHawkings on Wed Jul 20 10:02:59 MST 2011
You can use an UARTCLK divider as follows:

48MHz / 115.200 = 416,67.
UARTCLK must be 16xBaudrate => 416,67 / 16 = 26,0417.
Of course, only divider of 26 is possible.
48MHz / 16 / 26 = 115.384,62 bps.
This is 100 / 115.200 * 115.384,62 = 100.16% or just a difference of 0,16% if I'm correct, and a very good result.
SH
0 Kudos
Reply

1,047 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Rob65 on Wed Jul 20 08:24:14 MST 2011

Quote: akhilpo
Then why does it work when I use the driver function and doesnt work when I try to do it myself?



Because in the uart.c file it states:
  /* Enable UART clock */
  LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12);
  LPC_SYSCON->UARTCLKDIV = 0x1;     /* divided by 1 */


and you are setting UARTCLKDIV to 12 :eek:
If you copy, copy wisely ...

Rob
0 Kudos
Reply

1,047 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by akhilpo on Wed Jul 20 08:08:39 MST 2011

Quote:
fdiv = (((SystemCoreClock*LPC_SYSCON->SYSAHBCLKDIV)/regVal)/16)/115200 ;

I copied this right from the UARTInit definition in the uart.c driver file included in the example files. Then why does it work when I use the driver function and doesnt work when I try to do it myself? :/
0 Kudos
Reply

1,047 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by NXP_Europe on Wed Jul 20 07:51:16 MST 2011
Hi akhilpo,
It probably doesn't work because of the fdiv calculation.

As you indeed state:

Quote:
//fdiv = 48/(16*12*115200);

Assuming your SystemCoreClock*LPC_SYSCON->SYSAHBCLKDIV = 48MHz, fdiv will be 2.17, which is a bit hard to handle for a uC and introduces a large baudrate error.

I'd advice to keep the UARTCLKDIV @ 1 for now.

Kind regards,
0 Kudos
Reply