Aplikacje zestawu KwikStik: obsługa GPIO
Konfiguracja mikrokontrolera
Pisanie programu rozpoczniemy od dołączenia pliku nagłówkowego MK40N512MD100.h:
#include „MK40N512MD100.h”
Kod rozruchowy wymaga, abyśmy utworzyli funkcję SystemInit, która skonfiguruje mikrokontroler, która zwykle będzie zawierać konfigurację zegarów, ale w naszym przypadku ograniczymy się do wyłączenia watchdoga, który uniemożliwiałby debugowanie programu.
void SystemInit() { // Wyłączenie watchdoga WDOG->UNLOCK = (uint16_t)0xC520u; /* Key 1 */ WDOG->UNLOCK = (uint16_t)0xD928u; /* Key 2 */ WDOG->STCTRLH = (uint16_t)0x01D2u; }
Konfiguracja linii GPIO
Konfiguracja linii GPIO składa się z trzech kroków:
1. Odblokowanie zegara portu
Aby wykorzystać linie mikrokontrolera jako GPIO należy najpierw odblokować zegar portu, w naszym przypadku będzie to port E. Zegary peryferii mikrokontrolera Kinetis odblokowuje się ustawiając wartości odpowiednich bitów rejestrów SIM_SCGCx (System Lock Gating Control) na wartość 1, w tym przypadku musimy ustawić bit o nazwie PORTE w rejestrze SIM_SCGC5.
2. Konfiguracja linii
Do konfiguracji linii portów służą rejestry PORTx_PCRn (Pin Control Register), gdzie x to nazwa portu, np. E, n to numer linii, przykładowo aby skonfigurować linię PTE0 należy dokonać zapisu do rejestru PORTE_PCR0.
Funkcje interesujących nas bitów rejestru PCR są następujące:
- PS (Pull Select) – jeśli bit PE ma wartość 1, to bit PS służy do wyboru, czy linia ma być podciągnięta do masy (kiedy PS=0) czy do napięcia zasilania (kiedy PS=1),
- PE (Pull Enable) – dołączenie do linii rezystora podciągającego,
- SRE (Slew Rate Enable) – wybór czasu narastania sygnału, krótki dla wartości 0, długi dla wartości 1,
- ODE (Open Drain Enable) – jeśli ODE=1, to linia jest wyjściem typu otwarty dren,
- MUX (Pin Mux Control) – wybór funkcji linii. Rzeczą, która może zaskoczyć konstruktorów korzystających wcześniej z innych mikrokontrolerów może być fakt, że domyślnie linie I/O są skonfigurowane nie jako linie general-purpose, a są dołączone do różnych modułów peryferyjnych, przykładowo linia PTE0 (pierwsza linia portu E) domyślnie jest dołączona do przetwornika analogowo-cyfrowego. Aby wykorzystać linię jako GPIO musimy przełączyć ją w tryb ALT1 (pełna lista funkcji linii I/O znajduje się w rozdziale 10.3). Wartości bitów MUX i odpowiadające im funkcje linii I/O opisano w tabeli.
MUX[2:0] | Funkcja |
000 | Domyślna |
001 | ALT1 (GPIO) |
010 | ALT2 |
011 | ALT3 |
100 | ALT4 |
101 | ALT5 |
110 | ALT6 |
111 | ALT7 |
Aby skonfigurować linię jako cyfrowe wyjście typu push-pull (zwykłe wyjście podające 0 lub 3,3 V) należy więc wpisać do jej rejestru konfiguracyjnego następującą wartość:
PORTE->PCR[n] = 1 << PORT_PCR_MUX(1);
Warto zwrócić uwagę na definicję PORT_PCR_MUX w pliku MK40N512MD100.h, która zwalnia nas z konieczności przesuwania bitów i poprawia czytelność kodu.
3. Ustalenie kierunku linii I/O
Aby ustawić kierunek linii GPIO jako wyjście należy nadać bitowi o odpowiadającym jej numerze w rejestrze GPIOx_PDDR (Port Data Direction Register) wartość 1, na przykład dla linii PTE0 należy zapisać jedynkę do bitu zerowego rejestru GPIOE_PDDR.
Kompletna funkcja konfigurująca linie 0, 1, 8, 9, 10, 11, 24, 25 portu E wygląda następująco:
void GPIOInit() { // Odblokowanie zegara portu E SIM->SCGC5 |= (1 << SIM_SCGC5_PORTE_SHIFT); // Ustawienie funkcji linii na GPIO PORTE->PCR[0] = PORT_PCR_MUX(1); PORTE->PCR[1] = PORT_PCR_MUX(1); PORTE->PCR[8] = PORT_PCR_MUX(1); PORTE->PCR[9] = PORT_PCR_MUX(1); PORTE->PCR[10] = PORT_PCR_MUX(1); PORTE->PCR[11] = PORT_PCR_MUX(1); PORTE->PCR[24] = PORT_PCR_MUX(1); PORTE->PCR[25] = PORT_PCR_MUX(1); // Ustawienie linii jako wyjścia PTE->PDDR |= 1 | (1 << 1) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 24) | (1 << 25); }