Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

NXP LPC1768 i wewnętrzny przetwornik ADC - nie działa

Kubbaz 16 Jun 2011 11:34 2099 21
Computer Controls
  • #1
    Kubbaz
    Level 26  
    Witam wszystkich Elektrodowiczów!

    Próbuję uruchomić wewnętrzny przetwornik analogowo-cyfrowy (ADC) na mikrokontrolerze NXP LPC1768. Dokumentacja jest bardzo krótka, jeśli chodzi o to urządzenie peryferyjne mikrokontrolera i na jej podstawie napisałem kilka linii kodu C, który powinien uruchamiać przetwornik, ale tak się nie dzieje ;/. Przetwornik ani drgnie.

    Proszę o pomoc w tym temacie. Poniżej zamieszczam swój kod C.
    Code: c
    Log in, to see the code
  • Computer Controls
  • #2
    User removed account
    User removed account  
  • #3
    michalko12
    MCUs specialist
    Kubbaz wrote:
    LPC_SC->PCLKSEL0 &=~(1<<24)|(1<<25); // włączenie sygnału zegarowego dla ADC, ADC_CLK = CCLK/4 = 25 MHz


    Jaki jest sens umieszczania komentarzy skoro nie sa aktualizowane?
    Ma byc max 13MHz


    Kubbaz wrote:
    LPC_ADC->ADCR |= (1<<21); // no PDN (Power DOwn Mode); PDN bit = 1


    Punkt 29.1.1 user manuala mówi kiedy tą operacje należy wykonać
  • #4
    Kubbaz
    Level 26  
    michalko12 wrote:
    Jaki jest sens umieszczania komentarzy skoro nie sa aktualizowane? Ma byc max 13MHz


    Core_CLK mam ustawione na 100 MHz, APB_CLK dla ADC mam ustawione na 25 MHz.
    I dodatkowo dziele 25 MHz przez wartość '5' w preskalerze - bity 8-15 CLKDIV w rejestrze ADC0CR co daje 5 MHz. -> Nie tak to działa?

    Wprowadziłem zmiany, ale bez pozytywnego skutku...

    Code: c
    Log in, to see the code
  • Computer Controls
  • #5
    michalko12
    MCUs specialist
    Kubbaz wrote:
    LPC_SC->PCLKSEL0 &=~(1<<24)|(1<<25); // włączenie sygnału zegarowego dla ADC, ADC_CLK = CCLK/4 = 25 MHz


    OK moje niedopatrzenie, przeoczyłem &=~ a o CLKDIV zapomniałem
  • #6
    User removed account
    User removed account  
  • #7
    Kubbaz
    Level 26  
    albertb wrote:
    Startujesz konwersję i w następnej linii sprawdzasz, czy gotowa.
    Ja Ci bez sprawdzania powiem, że nie.

    Ok, kumam (datasheet, 29.3):
    "Basic clocking for the A/D converters is provided by the APB clock. A programmable
    divider is included in each converter to scale this clock to the clock (maximum 13 MHz) needed by the successive approximation process. A fully accurate conversion requires 65 of these clocks."

    Mimo wstanienia opóźnienia 5 ms, dalej nic :/.
    Code: c
    Log in, to see the code
  • #8
    nsvinc
    Level 35  
    Ależ...

    LPC_SYSCON->PDRUNCFG co tam masz? ADC przez bit w tym rejestrze potrafi nie działać ;] wiem z doświadczenia.

    Po drugie, ty nie masz czekać [czas] od startu konwersji do odczytania wyniku, tylko masz czekać na flagę zakończonej konwersji, while-em.
  • #10
    wujcio24
    Level 13  
    Quote:
    A co to za rejestr? Gdzie go się ustawia. Ja nie mam takiego rejestru w żadnych ustawieniach... ;S.


    PDRUNCFG (Power-down configuration register) jest to rejestr który znajduję się pod adresem 0x40048238 (w LPC1114 i LPC1343 u ciebie pewnie też). W tym rejestrze konkretne bity odpowiadają konkretnym peryferiom. Wartość zero na konkretnym bicie w tym rejestrze oznacza że coś zostało podłączone do zasilania. Ten rejestr ponadto jest przydatny przy podkręcaniu mikrokontrolera ponieważ w tym rejestrze są pola odpowiedzialne za oscylator i PLL. Pola bitowe w tym rejestrze są chyba tak samo ułożone w rodzinach LPC111x i LPC13xx (przynajmniej z ADC tak jest bo kod napisany w asemblerze z LPC111x był kompatybilny na LPC13xx).

    Oto mój fragment kodu odpowiedzialny za podłączenie ADC napisany w asemblerze:


    
             //wlaczenie ADC w rejestrze PDRUNCFG
    	ldr r0, =0x40048238
    	ldr r1, [r0]
    	movs r2, #16
    	bics r1, r2
    	str r1, [r0]
    


    Jakby ktoś był zainteresowany to mogę wrzucić cały kod napisany w asemblerze do obsługi ADC (cykliczne sczytywanie skonwertowanej wartości napięcia i zapalanie diody od pewnego progu wartości) dla płytki z procesorem LPC1343.
  • #11
    User removed account
    User removed account  
  • #12
    nsvinc
    Level 35  
    albertb wrote:
    Drobny problem, że autor ma LPC17xx, a nie 11xx, ani 13xx.

    Racja. Mój błąd ;]
  • #13
    michalko12
    MCUs specialist
    Code: c
    Log in, to see the code


    Zamień te linie miejscami
  • #14
    Kubbaz
    Level 26  
    Przeanalizowałem kod z przykładu pobranego ze strony NXP "Sample Code ADC" (kod niestety nie działa... ;/) i z dokumentacją napisałem kod, który zatrzymuje się w funkcji int ADC_GetData (uint8_t ChannelNumber) przed linijką
    Code: c
    Log in, to see the code

    i nie wiem dlaczego tak to się zachowuje :?:.

    Code: c
    Log in, to see the code
  • #15
    michalko12
    MCUs specialist
    Jakiekolwiek operacje na rejestrach ADC można robić dopiero po włączeniu i podaniu zegara, a ty uparcie robisz to przed
    Code: c
    Log in, to see the code

    gdzie na 63 stronie user manuala masz napisane
    Quote:

    12 PCADC A/D converter (ADC) power/clock control bit.

    Note: Clear the PDN bit in the AD0CR before clearing this bit, and set this bit before setting PDN.


    W Stellarisach przy takich operacjach generowany jest wyjątek, dziwne że tu sobie tak łatwo to przechodzi.
  • #16
    Kubbaz
    Level 26  
    wrote:
    Jakiekolwiek operacje na rejestrach ADC można robić dopiero po włączeniu i podaniu zegara...

    Źle przeczytałem ten fragment (odwrotnie)...

    Zrobiłem poprawkę:
    Code: c
    Log in, to see the code

    zamiast ADC_Init (1000000); i
    Code: c
    Log in, to see the code

    zamiast "(3)". Sygnał mam podpięty do wyprowadzenia P0.25 (ADC0.2) .

    Program nie wchodzi do pętli (dioda się nie zapala):
    Code: c
    Log in, to see the code


    Kontroler ADC nie wystawia flagi gotowości danych. Co może być nie tak?
  • #17
    michalko12
    MCUs specialist
    Czy ty wiesz w ogóle co masz robić?

    Po co stosujesz takie kombinacje:
    Code: c
    Log in, to see the code

    wystarczy
    Code: c
    Log in, to see the code

    kolejna sprawa, najpierw włączasz próbkowanie potem w trakcji ustawiasz kanał z którego ma to ADC robić.

    Nie rób takich manewrów:
    Code: c
    Log in, to see the code


    zamiast tego rób tak:

    Code: c
    Log in, to see the code
  • #19
    michalko12
    MCUs specialist
    Juz ktoś tu Ci tu wspominał że nie czekasz na koniec konwersji po jej rozpoczeciu

    tak czy nie?
  • #21
    michalko12
    MCUs specialist
    Informuje, ale TY nie czekasz na jego ustawienie!
    Sprawdzasz czy jest ustawiony, a nie będzie bo dopiero co go włączyłeś i konwersja jest w trakcie.