5 sierpnia 2010

MSP430 i wyświetlacz

Przygód z płytką LaunchPad ciąg dalszy. Jako pierwszy program na nową poznaną platformę postanowiłem napisać obsługę wyświetlacza na jakże popularnym sterowniku od Hitachi HD44780.

Zestaw LaunchPad i wyświetlacz LCD 2x40 (CMC240-02)
Od strony technicznej, połączenie płytki do wyświetlacza nie przysporzyło wiele kłopotów. Do tego celu stworzyłem przewody połączeniowe, mające po jednej stronie gniazdo na dwa golpiny, a po drugiej stronie pojedyncze goldpiny zabezpieczone rurką termokurczliwą by zapobiec oderwaniu się przewodu pod wpływem ruchów.

Do komunikacji pomiędzy wyświetlaczem wystarczy sześć żył (cztery linie danych, sygnał zatwierdzenia i wybór rejestru). Ilość została zredukowana do minimum poprzez zastosowanie transmisji 4-bitowej, oraz zwarcie niewykorzystanej linii R/W do masy, co oznacza, że komunikacja odbywa się w jedną stronę - do wyświetlacza, co w zupełności wystarcza do podstawowej obsługi. Napięcie zasilające logikę i matrycę dostarczyłem z portu USB. Do ustawienia kontrastu zastosowałem potencjometr 10kΩ.

Od strony programowej również poszło całkiem gładko. Wyświetlacz 2x40 ma to do siebie, że nie trzeba się  martwić o przechodzenie pomiędzy liniami, adresowanie komórek jest ciągłe na całej długości wierszy. Specyficzne dla tego mikroprocesora fragmenty kodu, to konieczność wyłączenia watchdoga oraz programowa inicjalizacja wewnętrznego oscylatora.
Obsługa wyświetlacza została zrealizowana zgodnie z dokumentacją techniczną. Wysłanie każdego rozkazu odbywa się w dwóch etapach ze względu na wcześniej wspominany sposób transmisji danych. Za wysłanie pojedynczego znaku odpowiada procedura PutChar, która w pierwszej kolejności wysyła 4 najstarsze bity, a następnie cztery najmłodsze bity z bajta znaku. Po wysłaniu ciągu znaków w, program przechodzi do nieskończonej pętli, która pełni rolę sygnalizacyjną, informując o aktywności mikroprocesora.

Dla zainteresowanych, załączam kod źródłowy:

#include  "msp430x20x2.h" #include <string.h> #define   LCD     P1OUT #define   DB4     BIT0 #define   DB5     BIT1 #define   DB6     BIT2 #define   DB7     BIT3 #define   E       BIT4 #define   RS      BIT5 void InitializeClocks(void); void LCDInit(void); void PutChar(char ch); void Enable(void); int main(void) {   unsigned char i;   char * text = "TI MSP430 LaunchPad";      // Stop watchdog timer to prevent time out reset   WDTCTL = WDTPW + WDTHOLD;   P1DIR |= 0x7F;      InitializeClocks();   LCDInit();      LCD = 0x00;      for (i = 0; i < strlen(text); i++)     PutChar(text[i]);      while (1)   {     LCD ^= BIT6;     for (i = 0; i < 255; i++)       __delay_cycles(1000);   } } void InitializeClocks(void) {   BCSCTL1 = CALBC1_1MHZ;                    // Set range   DCOCTL = CALDCO_1MHZ;   BCSCTL2 &= ~(DIVS_3);                     // SMCLK = DCO / 8 = 1MHz   } void LCDInit(void) {   LCD = DB5; Enable();                      // 4-bit operation mode   __delay_cycles(1000);   LCD = DB5; Enable();                      // Function set   LCD = DB7; Enable();   __delay_cycles(1000);   LCD = 0x00; Enable();                     // Display on/off control   LCD = DB6 + DB5 + DB7; Enable();   __delay_cycles(1000);   LCD = 0x00; Enable();                     // Entry mode set   LCD = DB5 + DB6; Enable();   __delay_cycles(1000);   LCD = 0x00; Enable();                     // Clear display   LCD = DB4; Enable();   __delay_cycles(1000); } void PutChar(char ch) {   char l = ch;        LCD = (l >> 4) + RS; Enable();   LCD = (l & 0x0F) + RS; Enable(); } void Enable(void) {   LCD &= ~E;   LCD ^= E;   LCD ^= E; }