lpcware

LPCXpresso LPC11C24/301 + Timer0 32 b - doesn't work

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by teslabox on Fri Sep 30 05:05:26 MST 2011
Hi everyone!

I try to run Timer0 32-bit on my LPC11C24 (on LPCXpresso LPC11C24 board).
I wrote w few lines of source code as followed in the User Manual of LPC11C24 and I can not to make it run. I made a lot of changes in the source code but it still doesn't work. Below I send my source code in C language. This program should toggle the LED diode connected to the P0.7 pin every e.g. 1 second, when the Timer Counter will be equal the Match 0 value and the the interrupt will be trigged.
#include "LPC11xx.h"
#include <cr_section_macros.h>
#include <NXP/crp.h>
#include "delay.h"

__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;

void Timer0_32b_Init         (uint32_t TimerFrequency);
void TIMER_32_0_IRQHandler     (void);

int main (void)
{
    LPC_GPIO0->DIR   |= (1<<7);        // wyprowadzenie P0.7 jako wyj&#347;cie

    Timer0_32b_Init (2);            // inicjalizacja Timera0 32b o okre&#347;lonej cz&#281;stotliwo&#347;ci w Hz

    for (;;)
    {
//        LPC_GPIO0->DATA |=(1<<7);    // zmiana stanu na wyprowadzeniu P0.7
//        delay (100);                // opó&#378;nienie 10 ms
//        LPC_GPIO0->DATA &=~(1<<7);    // zmiana stanu na wyprowadzeniu P0.7
//        delay (100);                // opó&#378;nienie 10 ms
    }

    return (0) ;
}

// funkcja inicjalizuj&#261;ca TIMER0 32-bitowy
void Timer0_32b_Init (uint32_t TimerFrequency)
{
    uint32_t MatchValue        = 0;     // zmienna przechowuj&#261;ca warto&#347;&#263; porównania z warto&#347;ci&#261; licznika Timera0 (przepe&#322;enienia)

/***********************************************************************/
/** KONFIGURACJA I ODCZYT WARTO&#346;CI CZ&#280;STOTLIWO&#346;CI ZEGARÓW SYSTEMOWYCH **/
/***********************************************************************/

// zmienne pomocnicze

    // zmienne przechowuj&#261;ce warto&#347;&#263;i zegarów
    uint32_t MainOscFreq     = 0;    // czestotliwo&#347;&#263; taktowania g&#322;ównego oscylatora "XTAL" - kwarcu zewn&#281;trznego
    uint32_t PLLFreq         = 0;    // cz&#281;&#347;totliwo&#347;&#263; taktowania na wyj&#347;ciu p&#281;tli PLL (FCC0)
    uint32_t OUTFreq        = 0;    // cz&#281;stotliwo&#347;&#263; taktowania systemu PLL (p&#281;tla PLL + jej sprz&#281;&#380;enie zwrotne - FCLKOUT)
    uint32_t AHBFreq         = 0;    // cz&#281;stotliwo&#347;&#263; taktowania magistrali AHB (do której pod&#322;&#261;czony jest Timer32)

    // zmienne przechowuj&#261;ce warto&#347;ci dzielników preslalerów poszczególnych cz&#281;stotliwo&#347;ci taktownia
    // zmienne przechowuj&#261;ce warto&#347;ci dzielników w p&#281;tli PLL
    uint16_t PLL_MSEL         = 0;    // warto&#347;&#263; pola dzielnika sprz&#281;&#380;enia zwrotnego MSEL w p&#281;tli PLL
    uint16_t PLL_PSEL         = 0;    // warto&#347;&#263; pola dzielnika PSEL w p&#281;tli PLL0
    uint16_t PLL_MVal        = 0;    // warto&#347;&#263; dzielnika M sprz&#281;&#380;enia zwrotnego w p&#281;tli PLL
    uint16_t PLL_PVal        = 0;    // warto&#347;&#263; dzielnika P w p&#281;tli PLL

    // zmienna przechowuj&#261;ca warto&#347;&#263; dzielnika cz&#281;stotliwo&#347;ci taktowania magistrali AHB mikrokontrolera
    uint8_t AHBDiv            = 0;     // dzielnik cz&#281;stotliwo&#347;ci magistrali AHB mikrokontrolera

// obliczenie cz&#281;stotliwo&#347;ci poszczególnych zegarów
    // warto&#347;&#263; czestotliwo&#347;ci taktowania g&#322;ównego oscylatora "XTAL" - kwarcu zewn&#281;trznego
    MainOscFreq = 12000000;

    // warto&#347;&#263; cz&#281;&#347;totliwo&#347;ci na wyj&#347;ciu p&#281;tli PLL
    PLL_MSEL =  ((LPC_SYSCON->SYSPLLCTRL & 0x1F));            // warto&#347;&#263; pola dzielnika M (bity: 0-4 -> MSEL) w sprz&#281;&#380;eniu zwrotnym p&#281;tli PLL
    PLL_PSEL = (((LPC_SYSCON->SYSPLLCTRL & 0x60) >> 5));    // warto&#347;&#263; pola dzielnika P (bity: 5-6 -> PSEL) w p&#281;tli PLL

    PLL_MVal = PLL_MSEL + 1;                                // obliczenie warto&#347;ci dzielnika w sprz&#281;z&#281;niu zwrotnym p&#281;tli PLL

    // obliczenie warto&#347;ci dzielnika w p&#281;tli PLL
    if (PLL_PSEL == 0)
    {
        PLL_PSEL = 1;
    }
    else if (PLL_PSEL == 1)
    {
        PLL_PSEL = 2;
    }
    else if (PLL_PSEL == 2)
    {
        PLL_PSEL = 4;
    }
    else if (PLL_PSEL == 3)
    {
        PLL_PSEL = 8;
    }

    // obliczenie warto&#347;ci wspó&#322;czynnika dziel&#261;cego ("wspó&#322;czynnika dzielnika") 2xP w p&#281;tli PLL
    PLL_PVal = 2 * PLL_PSEL;

    PLLFreq = MainOscFreq * PLL_MVal * PLL_PVal;    // cz&#281;stotliwo&#347;&#263; p&#281;tli PLL (FCC0) na jej wy&#347;ciu
    OUTFreq = ((PLLFreq) / (PLL_PVal));                // cz&#281;stotliwo&#347;&#263; systemu PLL (p&#281;tla + sprz&#281;&#380;enie zwrotne)

    // warto&#347;&#263; cz&#281;stotliwo&#347;ci taktowania magistrali AHB (Advanced Highspeed Bus) mikrokontrolera
    AHBDiv  = (LPC_SYSCON->SYSAHBCLKDIV);            // warto&#347;&#263; dzielnika zegara magistrali AHB
    AHBFreq = (OUTFreq/AHBDiv);                        // warto&#347;&#263; cz&#281;&#347;totliwo&#347;ci magistrali AHB

/***********************************************************************/
/************** KONFIGURACJA REJESTRÓW TIMERa0 32-bitowego *************/
/***********************************************************************/

    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<9)|(1<<10);// w&#322;&#261;czenie sygna&#322;u zegarowego dla Timera0 i Timera1 32-bitowego
//    LPC_TMR32B0->TCR &=~(1<<0);                    // wy&#322;&#261;czenie/zablokowanie Timera0 32B

    MatchValue = (AHBFreq/TimerFrequency);        // warto&#347;&#263;, z któr&#261; b&#281;dzie porównywany stan licznika
    LPC_TMR32B0->MR0 = MatchValue;                // liczba cylki zegara AHB/APB, z któr&#261; porównywany jest stan licznika Timera0, kana&#322; 0

    LPC_TMR32B0->TC  = 0;                        // warto&#347;&#263; pocz&#261;tkowa Timera0
    LPC_TMR32B0->PR  = 2;                        // warto&#347;&#263; preskalera Timera0, wzi&#281;kszanie warto&#347;ci Timera na ka&#380;dy cykl AHB/APB
    LPC_TMR32B0->PC  = 1;                        // warto&#347;&#263; pocz&#261;tkowa licznika preskalera Timera0
    LPC_TMR32B0->MCR |= (1<<0);                    // generowanie przerwania, gdy warto&#347;&#263; MatchRegVal jest równa stanowi licznika Timera0
    LPC_TMR32B0->MCR |= (1<<1);                    // resetowanie warto&#347;ci licznika Timera0 po osi&#261;gni&#281;ciu warto&#347;ci MatchRegVal
    LPC_TMR32B0->IR  |= (1<<0);                    // reset flagi przerwania na kanale 0
    LPC_TMR32B0->TCR |= (1<<1);                    // r&#281;czny reset licznika Timera0 (wymuszony)
    LPC_TMR32B0->TCR &=~(1<<1);                    // koniec resetu licznika Timera0 (wymuszony)
    NVIC_EnableIRQ (TIMER_32_0_IRQn);             // w&#322;&#261;czenie globalnych przerwa&#324; od Timera0
    LPC_TMR32B0->TCR |= (1<<0);                    // Timer032B jest w&#322;&#261;czony
}

// funkcja wywo&#322;ania przerwania od Timera0 32-bitowego
void TIMER_32_0_IRQHandler (void)
{
    if ((LPC_TMR32B0->IR & 0x01) == 0x01)    // je&#347;li flaga wyst&#261;pienia przerwania jest ustawiona, to wykonuje dalej
    {
        LPC_TMR32B0->IR |= (1<<0);    // reset przerwania - skasowanie flagi wyst&#261;pienia przerwania od Timera0
        LPC_GPIO0->DATA ^= (1<<7);    // zmiana stanu wyprowadzenia P0.7
    }
}

Outcomes