logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

LPC1115 - Timer_16 nie wyłącza diody na porcie 2.1 po 1s, brak przerwań

HudyPB 24 Maj 2014 12:09 1845 22
REKLAMA
  • #1 13629621
    HudyPB
    Poziom 10  
    Posty: 23
    Ocena: 1
    Witam. Tak jak w temacie posiadam układ LPC1115 który w zasadzie nie różni się od LPC1114.

    Zatrzymałem się na problemie uruchomienia timera16.

    W moim kodzie po 1s. chcę wyłączyć diodę na porcie 2.1
    Niestety dioda nie gaśnie, a nawet wydaje mi się że mikrokontroler nie robi przerwania. Poniżej przedstawiam mój kod i z góry dziękuję za pomoc :)

    
    #ifdef __USE_CMSIS
    #include "LPC11xx.h"
    #endif
    
    
    void TIMER_16(int CZAS)
    {
    
    	   LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7);         //WLACZENIE ZEGARA NA TIMER_0
    
    	   LPC_TMR16B0->IR = (1<<0);	                      //RESETOWANIE PRZERWAN
    	   LPC_TMR16B0->TCR = (1<<1);					//RESETOWANIE TIMERA
    	   LPC_TMR16B0->MCR = (1<<0)|(1<<1);			//PRZERWANIE i RESETOWANIE TIMERA OD MR0
    	   LPC_TMR16B0->MR0 = CZAS;					    //ZLICZENIE IMPULSOW (U mnie CLK = 12MHz)
    	   LPC_TMR16B0->PR = 99;						//PRESKALER (100-1)
    
    	   LPC_TMR16B0->TCR = (1<<0);					//WLACZENIE TIMERA
    
    	   NVIC_EnableIRQ(TIMER_16_0_IRQn);				//USTAWIENIE PRZERWANIA OD TIMER_16_0
    
    }
    
    
    void TIMER16_0_IRQHandler(void)
    	{
    	        LPC_GPIO2->DATA &= ~(1<<1);
    
    	        LPC_TMR16B0->IR |= (1<<0);
    
    	}
    
    
    int main(void)
    {
    	LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);			//CLK DLA GPIO
    	LPC_GPIO2 -> DIR = 0x000F;
    	LPC_GPIO2 -> DATA |= 0x000F;
    	TIMER_16(12000);
        while (1)
        {
    
        }
        return 0;
    }
    
    
  • REKLAMA
  • #2 13629915
    alagner
    Poziom 26  
    Posty: 768
    Pomógł: 85
    Ocena: 29
    A wektory aliasowane do Default Handlera są weak? Bo rozumiem, że nie masz debugera?
  • REKLAMA
  • #4 13629969
    Badmaneq
    Poziom 23  
    Posty: 567
    Pomógł: 76
    Ocena: 23
    O ile timer jest prawidłowo skonfigurowany, a wydaję mi się że tak to obsługa przerwania ustawia stan niski na P2.1
    Spróbuj tak i zobacz czy dioda mruga:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #5 13629977
    HudyPB
    Poziom 10  
    Posty: 23
    Ocena: 1
    No właśnie nie ustawia stanu niskiego bo dida cały czas się świeci. Zamiana linijek w funkcji przerwania niestety nie pomaga.

    Ma ktoś może możliwość sprawdzenia mojego kodu na LPC1114? Może w LPC1115 coś jest zmienione????
  • #6 13630813
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    A może po prostu nie zauważasz tych 40 Hz?
  • #7 13631256
    michalko12
    Specjalista - Mikrokontrolery
    Posty: 3394
    Pomógł: 462
    Ocena: 321
    BlueDraco napisał:
    A może po prostu nie zauważasz tych 40 Hz?

    Co najwyżej 10 przerwań na sekundę czyli 5Hz.

    Jak masz podłączoną tą diodę i czy w ogóle jesteś pewien czy podłączyłeś ją pod dobry pin?
  • REKLAMA
  • #8 13632124
    HudyPB
    Poziom 10  
    Posty: 23
    Ocena: 1
    Tak jestem pewien że podłączyłem ją pod dobry pin i jest podpięta dobrze bo świeci, tylko nie gaśnie.

    Chyba się pogubiłem.

    Jak mam:
    LPC_TMR16B0->PR = 99; //PRESKALER (100-1)
    oraz:
    LPC_TMR16B0->MR0 = 12000;

    to przy CPU = 12MHz... jaki będzie okres??
  • #9 13632147
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    Częstotliwość przerwań to CLK/100/12001.
    Skąd wiesz, że masz zegar 12 MHz - ustawiłeś to w SystemInit() czy usunąłeś wywołanie SystemInit z modułu startowego?
  • #10 13632151
    HudyPB
    Poziom 10  
    Posty: 23
    Ocena: 1
    Ajajaj....

    LPC_TMR16B0->PR = 11 999;
    LPC_TMR16B0->MR0 = 1000;

    Dla takich danych powinienem zmieniać stan diody co sekundę. Wieczorem sprawdzę czy to działa i dam znać.

    Dodano po 2 [minuty]:

    Przy kompilacji kodu wyświetla mi się w jednej z linijek że zegar jest 12MHz. Nic nie zmieniałem w ustawieniach więc prawdopodobnie jest to standardowe 12MHz.
  • #11 13632218
    Badmaneq
    Poziom 23  
    Posty: 567
    Pomógł: 76
    Ocena: 23
    Ten moduł ma debugger LPC-LINK więc możesz podglądnąć na ile "napędzany" jest uC.
    Dodaj do main
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    wtedy podejrzysz wartość zmiennej czestotliwosc.
    Ja obstawiam że uC taktowany jest 48MHz, jednak nie zmienia to faktu dlaczego dla LPC_GPIO2->DATA &= ~(1<<1); w przerwaniu nie gaśnie dioda. Jak wrócę do domu sprawdzę Twój kod...
  • #12 13632260
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    A kto wyświetla te 12 MHz i skąd on wie, że jest to 12 MHz? Być może po prostu tak ustawiłeś w konfiguracji projektu. Skończ z tą magią - wszelkie ustawienia biorą się z kodu - jeśli wziąłeś oryginalny SystemInit i go nie modyfikowałeś - masz zapewne 48 MHz - sprawdź wartość zmiennej SystemCoreClock.
  • #13 13633449
    HudyPB
    Poziom 10  
    Posty: 23
    Ocena: 1
    Ok sprawdziłem i macie racje częstotliwość mojego procka to 48MHz....

    Wracając do tematu nadal nie działa przerwanie, zmieniłem diodę na P0.6 oraz próbuję wpływać przerwaniem na małą diodkę znajdującą się od razu na płytce Xpresso pod P0.7

    Niestety brak pozytywnych osiągnięć :(
  • REKLAMA
  • #14 13633591
    Badmaneq
    Poziom 23  
    Posty: 567
    Pomógł: 76
    Ocena: 23
    Powiedz jeszcze jak spolaryzowane są diody, bo coś mi się zdaje że zapalenie następuje po ustawienie stanu niskiego na pin portu, a nie stanu wysokiego.
  • #15 13633637
    HudyPB
    Poziom 10  
    Posty: 23
    Ocena: 1
    Port, Dioda, Rezystor 680 Ohm, Masa.
  • #16 13633655
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    Wyrzuć zbędne kasowanie znacznika przerwania i resetowanie timera z procedury inicjowania timera. Ten kod musi działać, chyba, że z jakiegoś powodu nie jest on wgrywany w mikrokontroler - sprawdź pod debuggerem, np. umieszczając w pętli głównej zmianę stanu innego portu.

    Do kasowania znacznika przerwania wystarczy podstawienie na początku procedury przerwania, |= może wręcz powodować błędy jeśli uruchomisz przerwania od innych kanałów timera.
  • #17 13633692
    HudyPB
    Poziom 10  
    Posty: 23
    Ocena: 1
    Zauważyłem jeden bardzo dziwny błąd ;/

    Jak stworzyłem sobie funkcje delay to dioda w main świetnie mrugała. Podłączyłem drugą diodę aby mrugać nią przez przerwanie od Timera. I wystarczy jedna linika a mianowicie włączenie zegara od Timer16... dioda która wcześniej mrugała przestaje mrugać.... tak jakby procek się zwiesza albo sam już nie wiem co się dzieje :(
  • #18 13634160
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    Pokaż aktualną i prawdziwą wersję kodu.
  • #19 13636023
    HudyPB
    Poziom 10  
    Posty: 23
    Ocena: 1
    Chyba wiem gdzie jest błąd:

    Kompilator nie wykonuje mi funkcji DelayS, nie wiem zupełnie dlaczego. Wstawienie przed void ,,inline'' powoduje że program poniższy działa poprawnie.

    Jeśli jest tak jak w poniższym kodzie, dioda mi nie mruga tylko cały czas świeci bo nie wykonuje się funkcja DelayS. Ktoś wie jak naprawić ten problem??

    
    #ifdef __USE_CMSIS
    #include "LPC11xx.h"
    #endif
    
    volatile uint32_t MHZ;
    
    void DelayS(void)
    {
    	for(unsigned int i =0;i<4800000;i++){    	}
    }
    
    int main(void)
    {
    	MHZ  = SystemCoreClock;
    	LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);			//CLK DLA GPIO
    
    	LPC_GPIO2 -> DIR |= (1<<10);
    	LPC_GPIO2 -> DATA |= (1<<10);
    
    	//TIMER_16(1000);
    
    	LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7);
        while (1)
        {
        	LPC_GPIO2->DATA &= ~(1<<10);
        	DelayS();
        	LPC_GPIO2->DATA |= (1<<10);
        	for(unsigned int i =0;i<4800000;i++){    	}
        }
        return 0;
    }
    
  • Pomocny post
    #20 13636469
    mi14chal
    Poziom 28  
    Posty: 1021
    Pomógł: 112
    Ocena: 23
    Nie wykonuje się bo kompilator pewnie usunął tę pętlę. Do zmiennej "i" dopisz jeszcze volatile.
  • #21 13636624
    HudyPB
    Poziom 10  
    Posty: 23
    Ocena: 1
    Coś mam jeszcze z linkerem... ciągle wyświetla mi błędy typu:

    undefined reference to `GPIOInit()

    Projekt tworze w C++.
  • #22 13637818
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    I znów narzekasz, że nie działa Ci kod, którego nawet nie pokazałeś.

    Po co piszesz w C++?

    Zapewne chodzi o extern "C", ale dlaczego my musimy to zgadywać nie widząc kodu?
  • #23 13638100
    HudyPB
    Poziom 10  
    Posty: 23
    Ocena: 1
    Kod jest dwa posty wyżej pokazany. Gdzieś musiał być błąd w kodzie. Stworzyłem od nowa cały projekt i wszystko śmiga.

Podsumowanie tematu

✨ Użytkownik napotkał problem z mikrokontrolerem LPC1115, polegający na tym, że timer 16 nie wyłącza diody na porcie 2.1 po upływie 1 sekundy, a przerwania nie są wywoływane. Po analizie kodu i konfiguracji, okazało się, że częstotliwość zegara wynosi 48 MHz, a nie 12 MHz, co wpłynęło na ustawienia timera. Użytkownik zaktualizował kod, aby poprawnie ustawić preskaler i wartość MR0, co powinno umożliwić miganie diody. Dodatkowo, zasugerowano, aby zmienna w funkcji opóźnienia była oznaczona jako volatile, aby kompilator nie usuwał pętli. Ostatecznie, po przepisaniu projektu, problem został rozwiązany.
Podsumowanie wygenerowane przez AI na podstawie treści dyskusji.
REKLAMA