Skocz do zawartości

[Kurs] Kurs programowania ARM cz.05 - zegary i przerwania


Pomocna odpowiedź

Napisano

Poprzednia lekcja

Lekcja 5 - Zegary i przerwania

Następna lekcja

Poznaliśmy już podstawy sterowania liniami I/O, czas zapoznać się z zegarami oraz obsługą przerwań.

Procesory LPC211x mają bardzo rozbudowany układ zegarowy oraz układ przerwań. W kursie poznamy jedynie fragment, najpotrzebniejszy w praktyce.

W przypadku procesorów AVR działanie było bardzo proste - zewnętrzny kwarc, albo wbudowany układ RC generował częstotliwość z którą pracował układ.

Procesory ARM mają znacznie bardziej skomplikowane działanie zegara.

Zewnętrzny rezonator ma częstotliwość 12MHz (w przypadku naszej płytki). Częstotliwość ta jest następnie zwiększana w pętli PLL. Dopiero taki sygnał jest podawany na procesor (zegar główny CCLK).

Układy peryferyjne (np. porty I/O, timery itd) są taktowane za pomocą innego sygnału, oznaczanego PCLK. Jest to częstotliwość CCLK podzielona przez pewną wartość - po resecie wynosi ona 4.

Na razie nie używamy pętli PLL, więc procesor pracuje z następującymi ustawieniami:

• Fosc = 12MHz

• CCLK = 12MHz

• PCLK = 3MHz

Znając częstotliwość taktowania wykorzystamy Timer0 do cyklicznego wywoływania procedury.

Ustawimy zegar tak, aby co 1s wywoływał procedurę obsługi przerwania. W niej będziemy naprzemiennie zapalać diody D0 oraz D1.

Najpierw napiszemy procedurę obsługi przerwania:

void timer0(void) __attribute__ ((interrupt ("IRQ")));
void timer0(void)
{
if (T0_IR&0x01) {
	led_swap();
}

 T0_IR = 0xff;
 VICVectAddr = 0;
}

Instrukcja if sprawdza, przyczynę wywołania przerwania.

Ostatnie dwie instrukcje zerują flagi przerwań.

Procesory ARM7 mają kilka rodzajów przerwań. Warte uwagi jest jeszcze przerwanie "szybkie" FIQ - jest tylko jedno, za to jego obsługa następuje o kilka taktów zegara szybciej.

Nam, aż tak bardzo na czasie nie zależy, więc wystarczą nam przerwania IRQ.

Układ timera można skonfigurować na bardzo wiele sposobów. Wykorzystamy bardzo prosty: ustalimy licznik główny na czas odpowiadający 1s, po osiągnięciu przez licznik tej wartości będzie wywoływana nasza procedura przerwania.

Zegar konfigurujemy następująco:

 T0_TCR = 2;
 T0_PR = 0;
 T0_MR0 = 12000000/4;
 T0_MCR = 3;
 T0_TCR = 1;

T0_TCR - rejestr kontrolny timera. 2 resetuje zegar, 1 uruchamia

T0_PR - ustala presklaler. Zero oznacza brak, czyli timer działa z częstotliwością PCLK.

T0_MR0 - jest to wartość do której liczy timer. Wpisujemy równą częstotliwości PCLK, czyli przerwanie wystąpi po dokładnie 1s.

T0_MCR - rejestr ustala działanie timera. 3 oznacza, że po osiągnięciu wartości wpisanej do T0_MR0 wywołane zostanie przerwanie, a timer zacznie liczyć od początku

Więcej informacji o rejestrach i ich wartościach znajdziemy w dokumentacji procesora.

Cała procedura inicjalizująca timer wygląda następująco:

void timer0_init(void)
{
 VICIntSelect &= ~0x10;
 VICIntEnable = 0x10;
 VICVectCntl0 = 0x24;
 VICVectAddr0 = (unsigned long)timer0;

 T0_TCR = 2;
 T0_PR = 0;
 T0_MR0 = 12000000/4;
 T0_MCR = 3;
 T0_TCR = 1;

asm volatile ( 
	"STMDB	SP!, {R0}		\n"
	"MRS	R0, CPSR		\n"	
	"BIC	R0, R0, #0xC0	\n"	
	"MSR	CPSR, R0		\n"	
	"LDMIA	SP!, {R0}" );			
}

Początek konfiguruje wektor przerwań. Układy LPC z rodziny ARM7 mają bardzo skomplikowane przerwania. Na szczęście w nowszych układach (Cortex) zostało to już uproszczone. Tutaj pozostaje przeczytać dokumentację procesora, albo wykorzystać kod na razie nie wnikając jak działa.

Fragment w asemblerze uruchamia przerwania, jest to odpowiednik sei() w AVR. Większość komercyjnych środowisk ma do tego gotowe procedury, niestety darmowy gcc wymaga sięgnięcia do asemblera.

W pliku program08.zip znajdziemy pełny program. Efekt działania to dwie migające na przemian diody.

Uruchamiamy pętlę PLL

Praca z częstotliwością 12MHz nie jest niczym nadzwyczajnym, zwykła ATMega bywa szybsza. Czas więc nieco przyspieszyć.

Ustawimy PLL, tak aby mnożył częstotliwość rezonatora przez 5. Otrzymamy wtedy parametry pracy:

• Fosc = 12MHz

• CCLK = 60MHz

• PCLK = 15MHz

Procedura konfiguracji pętli PLL:


void pll_init()
{
 MAM_MAMTIM = 3;
 MAM_MAMCR = 2;

 SCB_PLLCFG = 0x24;
 SCB_PLLCON = 0x1;
 SCB_PLLFEED = 0xAA;
 SCB_PLLFEED = 0x55;
 while (!(SCB_PLLSTAT&0x0400));
 SCB_PLLCON = 0x3;
 SCB_PLLFEED = 0xAA;
 SCB_PLLFEED = 0x55;
}

Pierwsze dwie instrukcje konfigurują pamięć Flash procesora - jest ona wolniejsza niż rdzeń, więc musimy ustawić podzielnik jej zegara na 3.

Dalszy ciąg procedury konfiguruje i uruchamia pętlę PLL.

Najważniejsza jest linia:

 SCB_PLLCFG = 0x24;

Wartość 0x24 ustala mnożnik M=5, P=3. Jeśli chcemy uzyskać inną częstotliwość pracy możemy te wartości zmienić. Informacja o sposobie obliczania jest dostępna w dokumentacji procesora.

Warto zapamiętać, że częstotliwość pracy wybiera program. Bywa to bardzo wygodne, ponieważ im wyższa prędkość pracy, tym wyższy pobór prądu. Procesory ARM mogą w trakcie działania zmieniać swoją prędkość działania.

Pozostaje zmienić ustawienia naszego timera - zgodnie z nową częstotliwością taktowania:

 T0_MR0 = 60000000/4;

Pełny program znajdziemy w archiwum program09.zip. Działa jak poprzedni, jednak procesor pracuje już z pełną prędkością.

Autor kursu:

Elvis

Pomoc przy edycji materiałów wideo, formatowaniu i publikacji:

Treker

Program09.zip

Program08.zip

  • Lubię! 1

Mam pytanie odnośnie źródeł, innych tutoriali, książek: znacie jakieś źródła z opisanymi rejestrami, ale dokładnie opisanymi (coś na wzór tego co jest w dokumentacjach AVRów). Mam dokumentację uC: rejestry są wymienione, w skrócie opisane, ale nie wiadomo co trzeba wpisać aby osiągnąć określony efekt. Mam też lpc-ARM-book_srn.pdf - są przykłady kodu, ale nie ma żadnej informacji co za co odpowiada.

Ja bym radził wczytać się w dokumentację procesora - User's Manual (http://ics.nxp.com/support/documents/microcontrollers/pdf/user.manual.lpc2109.lpc2114.lpc2119.lpc2124.lpc2129.lpc2194.lpc2210.lpc2212.lpc2214.lpc2220.lpc2290.lpc2292.lpc2294.pdf). Co prawda tylko 390 stron (nowsze procesory mają po 600), ale jest tam wszystko. Na początek może nie jest to łatwe do czytania, ale można się przyzwyczaić.

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...