7 years, 9 months ago.

Can't change system clock on lpc11u35

Hello,

I'm having a little problem with changing the system clock in a LPC11u35 (I have the QuickStart board).

So, I want to run the MCU the fastest possible (48MHz according to the datasheet). To do so, I've configured the PLL as the system clock source.

The code in question:

void setClk()
{
    // Power up PLL
    LPC_SYSCON->PDRUNCFG &= ~(0x00000080);
    // Set oscillator as PLL input
    LPC_SYSCON->SYSPLLCLKSEL |= 0x00000001;
    // Reset PLL
    LPC_SYSCON->SYSPLLCLKUEN &= ~(0x00000001);
    LPC_SYSCON->SYSPLLCLKUEN |= 0x00000001;
    // Set PLL output to 48MHz
    LPC_SYSCON->SYSPLLCTRL &= ~(0x0000007F);
    LPC_SYSCON->SYSPLLCTRL |= 0x00000003; // (M = 4)
    LPC_SYSCON->SYSPLLCTRL |= 0x00000020; // (P = 2)
    // Wait until PLL has locked
    while((LPC_SYSCON->SYSPLLSTAT & 0x00000001) == 0);
    // Set main clock to PLL
    LPC_SYSCON->MAINCLKSEL &= ~(0x00000003);
    LPC_SYSCON->MAINCLKSEL |= 0x00000003;
    LPC_SYSCON->MAINCLKUEN &= ~(0x00000001);
    LPC_SYSCON->MAINCLKUEN |= 0x00000001;
    SystemCoreClockUpdate();
}

I have even called the method SystemCoreClockUpdate() to update the SystemCoreClock variable (I don't know what is it for, but I suppose peripherals libraries use it). I have read in execution its value, and it is 48MHz.

So... it appears to be working, why do I ask this question?

Well, when I measure a 1sec pulse using one of the 32bits counters, I always get the same reading of about 1 mil (as if the MCU was running at 1MHz). I have to point out that I'm also using USBSerial library, and an InterruptIn object. Anybody has a clue?

Thanks!

This is the main code:

#include "mbed.h"
#include "USBSerial.h"

DigitalOut LedStatus(P0_13);
InterruptIn Pulse(P0_17);
USBSerial serial;

unsigned int count;

void toggle()
{
    // Read count
    count = LPC_CT32B1->TC;
    // Reset CT32B1
    LPC_CT32B1->TCR |= 0x00000002;
    LPC_CT32B1->TCR &= ~(0x00000002);
    // print count via USB
    serial.printf("*****%d*******", count);
}

int main()
{
    setClk();
    // Enable 1 sec pulse interrupt
    Pulse.rise(&toggle);
    // Enable timer CT32B1
    LPC_SYSCON->SYSAHBCLKCTRL |= 0x00000200;
    // Set precounter to 0
    LPC_CT32B1->PR |= 0x00000000;
    // Start CT32B1
    LPC_CT32B1->TCR |= 0x00000001;
    while(1);
}

1 Answer

7 years, 9 months ago.

Try using CT32B0 instead. B1 is already used for things like wait and Ticker. Which sets it to run at 1MHz using its prescaler. (Or one of the 16-bit timers).

It runs by default at 48MHz, otherwise USBSerial also wouldn't work. So the reason you are always seeing the same, is that your code does not actually change anything. See: https://github.com/ARMmbed/mbed-os/blob/master/targets/TARGET_NXP/TARGET_LPC11UXX/device/system_LPC11Uxx.c#L148

Now I have seen better documented clock setup files, however important is that SYSPLLCTRL is set to 0x23, which is identical to what you set it to.

Accepted Answer

Thanks! that was it indeed

posted by Joaquin Muguerza 07 Feb 2017