Digilent Pmod i STM32 (cz. 5) – PmodCLS, PmodDPG1 i PmodISNS20
W kolejnej części cyklu poświęconego modułom peryferyjnym Pmod przedstawione zostaną trzy moduły z interfejsem SPI: PmodCLS z alfanumerycznym wyświetlaczem LCD, PmodDPG1 z różnicowym czujnikiem ciśnienia, a także PmodISNS20 zawierający czujnik Halla do pomiaru natężenia prądu. Przykłady dla wymienionych modułów przygotowano dla środowiska Atollic TrueSTUDIO i zestawu uruchomieniowego KAmeleon (www.kameleonboard.org) z wykorzystaniem biblioteki STM32Cube_FW_L4.
PmodCLS
Na module PmodCLS znajduje się wyświetlacz znakowy LCD zawierający dwie linie po 16 znaków. Do jego obsługi służy znajdujący się na płytce, zaprogramowany mikrokontroler ATmega48 przyjmujący komendy za pośrednictwem jednego z interfejsów: SPI, I2C lub UART. Aktywny interfejs do komunikacji z modułem PmodCLS wybiera się za pomocą zworek na złączu JP2 (MD0, MD1, MD2). Przykład wykorzystuje interfejs SPI, dlatego zworka MD0 powinna być zamknięta, natomiast MD1 i MD2 należy zostawić otwarte. Trzeba również pamiętać o odpowiednim ustawieniu zworki na złączu JP1 tak, aby sygnał SS (Slave Select) złącza J1 doprowadzić do mikrokontrolera sterującego wyświetlaczem – piny 1 (SS) i 2 (środkowy) złącza JP1 powinny być zwarte. Po takiej konfiguracji modułu, złącze J1 odpowiadające złączu Pmod SPI typu 2. może zostać podłączone do gniazda Pmod-SPI zestawu KAmeleon. Opis połączeń z pinami mikrokontrolera STM32L496ZG znajduje się w tabeli 1.
Tabela 1. Podłączenie modułu PmodCLS do złącza Pmod-SPI zestawu KAmeleon
Sygnał | Numer pinu złącza Pmod | Pin mikrokontrolera |
CS | 1 | PB0 |
MOSI | 2 | PA7 |
MISO | 3 | PE14 |
SCK | 4 | PA1 |
GND | 5 | – |
VCC | 6 | – |
Komendy sterujące wyświetlaczem
Moduł PmodCLS jest kontrolowany za pomocą komend wysyłanych przez wybrany interfejs. Każda komenda rozpoczyna się sekwencją znaków 0x1b i 0x5b (w kodzie ASCII ESC i ‘[’), po której następują argumenty, a także kod komendy. Część z dostępnych komend, wykorzystanych w przykładzie znajduje się w tabeli 2. Komendy poprzedzono sekwencją ‘\x1b[‘. Pełną listę komend można znaleźć na stronie z dokumentacją modułu: https://reference.digilentinc.com/pmod/pmod/cls/user_guide.
Tabela 2. Przykładowe komendy modułu PmodCLS
Komenda | Opis |
\x1b[j | Wyczyszczenie wyświetlacza i ustawienie kursora w pozycji zerowej |
\x1b[0h | Ustawienie trybu wyświetlacza (0 – 16 znaków na linię, 1 – 40 znaków na linię) |
\x1b[0c | Ustawienie trybu kursora (0 – niewidoczny, 1 – widoczny, 2 – mrugający) |
\x1b[0;0H | Ustawienie pozycji kursora w pozycji 0;0 (<wiersz>;<kolumna>) |
Po ustawieniu żądanej konfiguracji i ustawieniu kursora można umieścić na wyświetlaczu napis. Łańcuch znaków należy wysłać bezpośrednio na wybrany interfejs, bez sekwencji poprzedzającej jak w przypadku komend. Kontroler rozpoznaje znaki w kodzie ASCII i umieszcza je na wyświetlaczu.
Kod przykładowego projektu
Obsługę wyświetlacza zaimplementowano w plikach src/PmodCLS.h i src/PmodCLS.c w postaci dwóch funkcji: konfiguracyjnej – PmodCLS_Config i wypisującej tekst na wyświetlacz – PmodCLS_Write. Pierwsza z nich odpowiada za inicjalizację peryferiów i modułu PmodCLS. Do komunikacji z modułem wyświetlacza konfigurowany jest interfejs SPI w trybie 0 (polaryzacja i faza zegara równe 0) ze sprzętową obsługą pinu CS. Pełną konfigurację przedstawiono na listingu 1.
Listing 1. Konfiguracja interfejsu SPI do komunikacji z modułem PmodCLS
// Enable clock for all GPIO ports required for Pmod connector configuration. __HAL_RCC_SPI1_CLK_ENABLE(); // Configure the SPI peripheral for 2 data lines and Chip Select pin managed by hardware. pmodClsSpi.Instance = SPI1; pmodClsSpi.Init.Mode = SPI_MODE_MASTER; pmodClsSpi.Init.Direction = SPI_DIRECTION_2LINES; pmodClsSpi.Init.DataSize = SPI_DATASIZE_8BIT; pmodClsSpi.Init.CLKPolarity = SPI_POLARITY_LOW; pmodClsSpi.Init.CLKPhase = SPI_PHASE_1EDGE; pmodClsSpi.Init.NSS = SPI_NSS_HARD_OUTPUT; pmodClsSpi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128; pmodClsSpi.Init.FirstBit = SPI_FIRSTBIT_MSB; pmodClsSpi.Init.TIMode = SPI_TIMODE_DISABLE; pmodClsSpi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; pmodClsSpi.Init.NSSPMode = SPI_NSS_PULSE_ENABLE; HAL_SPI_Init(&pmodClsSpi);
Konfiguracja GPIO
Piny GPIO są konfigurowane w funkcji HAL_SPI_MspInit, która jest wywoływana, zgodnie z konwencją biblioteki STM32Cube, podczas konfiguracji interfejsu SPI w funkcji HAL_SPI_Init. Wszystkie potrzebne piny mikrokontrolera obsługiwane są sprzętowo, zgodnie z konfiguracją przedstawioną na listingu 2.
Listing 2. Konfiguracja pinów GPIO do komunikacji SPI z modułem PmodCLS
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLDOWN; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF5_SPI1; GPIO_InitStruct.Pin = GPIO_PIN_1 | GPIO_PIN_7; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_14; HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Pin = GPIO_PIN_0; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
Komendy inicjalizujące
Na końcu funkcji PmodCLS_Config wysyłana jest sekwencja komend do kontrolera wyświetlacza odpowiedzialna za początkową inicjalizację modułu: wyczyszczenie wyświetlacza i ustawienie trybu kursora. Sekwencja ta znajduje się na listingu 3.
Listing 3. Komendy odpowiedzialne na inicjalizację wyświetlacza
write("\x1b[j", 3); // Clear the display and home cursor. write("\x1b[0h", 4); // Set the display mode (16 characters wrap) write("\x1b[0c", 4); // Set cursor mode (cursor off). write("\x1b[0;0H", 6); // Set the cursor position to 0,0.
Użyta funkcja write jest wyłącznie wrapperem na biblioteczną funkcję HAL_SPI_Transmit realizującą blokującą transmisję SPI. Wykorzystano ją także w funkcji PmodCLS_Write, przedstawionej na listingu 4. Przyjmuje ona numer linii (0 lub 1), łańcuch znaków i jego długość, ustawia kursor na początku wybranej linii oraz wysyła żądany napis do kontrolera wyświetlacza.
Listing 4. Funkcja wypisująca znaki na wyświetlaczu
void PmodCLS_Write(uint8_t line, char* text, uint32_t len) { // Verify the arguments according to the defined limits. if(line >= MAX_LINES || len > MAX_LINE_CHARACTERS) return; // Set the cursor position to the beginning of the selected line.. if(line == 0) write("\x1b[0;0H", 6); else write("\x1b[1;0H", 6); write(text, len); }
Wypisywanie znaków na wyświetlacz
Główna funkcja programu – main, wywołuje funkcję konfigurującą wyświetlacz, a następnie wyświetla na nim napisy:
Hello PmodCLS KAmeleon board
Efekt działania programu znajduje się na fotografii 2.
Fotografia 2. Moduł PmodCLS podłączony do zestawu KAmeleon