Wyświetlacze oparte na poczciwym kontrolerze HD44780 bez problemu współpracują z mikrokontrolerem LPC1114 pomimo, że większość wyświetlaczy pracuję na napięci 5 V, są także specjalnie produkowane na na pięcie 3,3 V jednak są zwykle drozsze niz "standardowe" 5 V.
Ponieważ mikrokontroler LPC1114 ma porty wejścia/wyjścia tolerujące 5 V bez problemu obsługuje wyświetlacze oparte na HD44780 dla 5 V.
poniedziałek, 25 listopada 2013
wtorek, 24 września 2013
Interfejs SPI w LPC 1114
Mikrokontroler LPC 1114 posiada dwa sprzętowe kontrolery SPI nazwane następująco SSP0 i SSP1. Nazwa SSP to skrót od Synchronous Serial Port, czyli Szeregowy Synchroniczny Port. Posiada 8 bitowy bufor FIFO dla wysyłanych i odbieranych danych, rozmiar ramki danych można definiować od 4 do 16 bitów. Maksymalna częstotliwość taktowania zegara 25 MHz przy założeniu taktowania rdzenia 50 MHz. Należy pamiętać, że po resecie zegar taktujący kontroler jest włączony tylko dla SSP0, chcąc korzystać z SSP1 należy ustawić bit 18 w rejestrze SYSAHBCLKCTRL !
Procedura inicjalizacyjna i konfiguracyjna kontrolera SSP wygląda następująco:
1. Pierwszym etapem jest konfiguracja wyprowadzeń odpowiedzialnych za komunikację SPI, ponieważ standardowo te piny są zwykłymi portami wejścia / wyjścia. Należy ustawić odpowiednie wartości w rejestrze IOCON_LOC pamiętając, aby włączyć zegar dla tego bloku konfiguracyjnego:
- LPC_SYSCON->SYSAHBCLKCTRL |= (0x1<<16) ; // włącza zegar taktujący dla IOCON_LOC
- P0.8 - MISIO
- P0.9 - MOSI
- P0.2 - SSEL sprzętowy wybór urządzenia (CS), oczywiście można nie konfigurować tego pinu, wtedy wybieranie musi być obsługiwane programowo dowolnym pinem
- natomiast SCK, czyli zegar zależy od ustawień w rejestrze IOCON_SCK_LOC, domyślnie jest na P0.10, może być również na P0.6 i P2.11
- P2.2 - MISIO
- P2.3 - MOSI
- P2.0 - SSEL sprzętowy wybór urządzenia (CS), analogicznie jak SSP0 można obsługiwać programowo
- P2.1 - SCK
2. Jak wcześniej wspomniałem należy włączyć zegar taktujący kontrolery SSP:
- LPC_SYSCON->SYSAHBCLKCTRL |= (0x1<<11) ; // włącza zegar taktujący SSP0
- LPC_SYSCON->SYSAHBCLKCTRL |= (0x1<<18) ; // włącza zegar taktujący SSP1
Jak widać na obrazku Fig.8 sygnał taktujący main clock dociera m.in. do dzielnika zegara SPIO PERIPHERAL CLOCK DIVIDER oraz SPI1 PERIPHERAL CLOCK DIVIDER. Odpowiednią wartość wpisuje się do rejestru SSP0CLKDIV oraz SSP1CLKDIV. Wartościami poprawnymi są wartości od 0 do 255, przy czym wpisanie 0 (po resecie przyjmuję wartość 0) spowoduje wyłączenie taktowania kontrolera SPI.
LPC_SYSCON->SSP0CLKDIV = 0x1; // bez podzielnika zegara main clock
LPC_SYSCON->SSP0CLKDIV = 0xFF; // 255 podzielenie main clock
LPC_SYSCON->SSP0CLKDIV = 0; // zegar taktujący przestaje docierać do kontrolera SSP0
LPC_SYSCON->SSP0CLKDIV = 0xFF; // 255 podzielenie main clock
LPC_SYSCON->SSP0CLKDIV = 0; // zegar taktujący przestaje docierać do kontrolera SSP0
LPC_SYSCON->PRESETCTRL |= (0x1<<1); // wylaczenie resetu SPP1
5. Konfiuguracja kontrolera SSP
Rejestry odpowiedzialne za konfigurację parametrów pracy oraz przerwań związanych z kontrolerami SSP przedstawia poniższa tabelka:
Głównych ustawień dokonuje się w rejestrze SSP0CR0 lub SSP1CR0 w zależności, który kontroler SSP ustawiamy
Przedstawione w tabelce bity rejestru SSP0CR0 / SPP1CR0 odpowiadają kolejno
- DDS - bity 3:0 konfigurują rozmiar ramki (4-16 bit)
- FRF - bity 5:4 format ramki - domyślnie po resecie są wyzerowane więc format transmisja SPI
- CPOL - bit 6 odpowiada za polaryzację zegara
- CPHA - bit 7 wyjście fazy zegara
- SCR - bity 15:8 biorą udział przy taktowaniu zegara transmisji SPI
Należy pamiętać, że wartość zapisywana na bitach CPSDVSR w rejestrach SSP0CPSR lub SSP1CPRS musi być liczbą parzystą i zawierać się w przedziale 2 - 254.
Czyli maksymalna częstotliwość transmisji interfejsu SSP jaką można osiągnąć w LPC1114 wyraża się PCLK / 2 dla najmniejszych wartości jakie można zapisać w CPSDVSR=2 i SCR=0, ich zwiększanie odpowiednio będzie powodować zmniejszenie częstotliwości transmisji.
Czyli maksymalna częstotliwość transmisji interfejsu SSP jaką można osiągnąć w LPC1114 wyraża się PCLK / 2 dla najmniejszych wartości jakie można zapisać w CPSDVSR=2 i SCR=0, ich zwiększanie odpowiednio będzie powodować zmniejszenie częstotliwości transmisji.
6. Ostatnim etapem jest włączenie kontrolera SSP wraz z ustawieniem trybu MASTER / SLAVE zgodnie z poniższa tabelką
- LBM - bit 0 po resecie zerowany (zwykle powinien być wyzerowany), jego ustawienie włącza tryb Loop Back. Służy on do testowania oprogramowania, włączenie spowoduje że dane wysłane na MOSI pojawią się MISO
- SSE - bit 1także po resecie zerowany, ustawiając go załącza się kontroler SSP0/1 a tym samy można rozpocząć transmisje
- MS - bit 2, który po resecie ma wartość 0 co oznacza że interfejs pracuje w trybie MASTER, natomiast ustawienie bitu powoduje przejście w tryb SLAVE
#include "LPC11xx.h" // rozmiar bufora FIFO #define FIFOSIZE 8 // definicje na potrzeby badnia statusu SSP #define SSPSR_TFE (0x1<<0) #define SSPSR_TNF (0x1<<1) #define SSPSR_RNE (0x1<<2) #define SSPSR_RFF (0x1<<3) #define SSPSR_BSY (0x1<<4) // funkcja wysylajaca void Send_SSP(uint8_t data) { // czeka dopoki kontroler jest zajety i kolejko FIFO TX nie jest pelna while ( (LPC_SSP1->SR & (SSPSR_TNF|SSPSR_BSY)) != SSPSR_TNF ); LPC_SSP1->DR = data; // wysyla dane przez SSP1 } // funkcja odbierajaca void Recive_SSP(uint8_t *data) { while ( LPC_SSP0->SR & (1<<2) ) { // dopoki bufor odbiorczy nie jest pusty *data = LPC_SSP0->DR; // pobranie bajtu data++; } } int main(void) { uint8_t i, tmp; uint8_t bufor[]="Test SPI" ; // konfiguracja pinow odpowiedzialnych za komunikacjie SPI LPC_SYSCON->SYSAHBCLKCTRL |= 1<<16; //wlaczenie zegara dla bloku IOCON_LOC // LPC_IOCON->PIO2_0 |= 0x2; // P2.0 SEL1 - sprzetowy CS dla SSP1 LPC_IOCON->PIO2_1 |= 0x2; // P2.1 SCK - zegar LPC_IOCON->PIO2_2 |= 0x2; // P2.2 MISO dla SSP1 LPC_IOCON->PIO2_3 |= 0x2; // P2.3 MOSI dla SSP1 LPC_SYSCON->SYSAHBCLKCTRL |= 1<<18; // wlacza zegar taktujacy SSP1 LPC_SYSCON->SSP1CLKDIV = 0x1; // bez podzielnika zegara, do SSP1 dociera main clock LPC_SYSCON->PRESETCTRL |= 1<<2; // wylaczenie resetu SSP1 LPC_SSP1->CR0 = 0x0507; // dana 8 bitowa, ramka SPI, CPOL=0, CPHA=0, SCR=5 LPC_SSP1->CPSR = 2; // CPSDVSR=2, zatem taktowanie SSP0 jest rowne 4 MHz bo PCLK / (CPSDVSR*(SCR+1). 48 / (2*(5+1) = 4 for ( i = 0; i < FIFOSIZE; i++ ) tmp = LPC_SSP0->DR; // czytanie FIFO, a tym samym wyczyszczenie bufora FIFO ze smieci LPC_SSP1->CR1 = (1<<1) ; // wlaczenie kontolera SSP/SPI w trybie MASTER while(1) { i = 0; while( tmp = bufor[i++] ) Send_SSP( tmp ); // wysyla kolejny znak } return 0 ; }
czwartek, 15 sierpnia 2013
Szybkie przejście z 8 bit na 32 bit
Jeżeli brakuje Ci mocy obliczeniowej w Twoim projekcje, w którym dotychczas korzystałeś z 8 bitowych mikrokontrolerów warto zainteresować się szybszym 32 bitowym mikrokontrolerem LPC 1114.
Co prawda nie znajdziesz go w obudowie DIP tylko SMD, lecz SMD nie jest tak trudne w wykorzystaniu w "domowych" projektach.
Jeżeli nie możesz, nie potrafisz skonstruować projektu z użyciem SMD, zawsze możesz zakupić gotowy moduł na pokładzie z LPC 1114, np. takie jak:
Na początek nie potrzebujesz żadnego programatora, do programowania wykorzystasz interfejs RS-232 z odpowiednią transalacją poziomów logicznych do 3,3 V. Świetnie nadaje się układ MAX3232, a jeżeli nie posiadasz portu RS-232 tylko USB to układ FT232R lub podobny.
AVR'y mają trzy 8 bitowe rejestry służące do operacji na portach:
DDRx - rejestry kierunku
PORTx - rejestry wyjściowe
PINx - rejestry wejściowe
Podobnie jest w 32 bitowym LPC 1114:
LPC_GPIOx->DIR - rejestry kierunku
LPC_GPIOx->DATA - rejestry wyjściowe / wejściowe
Poniżej przykład w AVR ustawiający kierunek wyjścia pinu 1 portu A oraz ustawienie na nim stanu niskiego:
DDRA |= (1<<PA1); // kierunek pinu 1 portu PA na wyjściowy
PORTA &= ~(1<<PA1); // ustawienie stanu niskiego na pinie PA1
Analogicznie do w/w przykładu steruje się portami w LPC 1114:
LPC_GPIO0->DIR |= (1<<1); // kierunek pinu portu PORT0 na wyjściowy
LPC_GPIO0->DATA &|= ~(1<<1); // ustawienie stanu niskiego na pinie P0_1
Pora na przykład Witaj Świecie na LPC 1114, czyli mruganie diodą:
Co prawda nie znajdziesz go w obudowie DIP tylko SMD, lecz SMD nie jest tak trudne w wykorzystaniu w "domowych" projektach.
Jeżeli nie możesz, nie potrafisz skonstruować projektu z użyciem SMD, zawsze możesz zakupić gotowy moduł na pokładzie z LPC 1114, np. takie jak:
Na początek nie potrzebujesz żadnego programatora, do programowania wykorzystasz interfejs RS-232 z odpowiednią transalacją poziomów logicznych do 3,3 V. Świetnie nadaje się układ MAX3232, a jeżeli nie posiadasz portu RS-232 tylko USB to układ FT232R lub podobny.
AVR'y mają trzy 8 bitowe rejestry służące do operacji na portach:
DDRx - rejestry kierunku
PORTx - rejestry wyjściowe
PINx - rejestry wejściowe
Podobnie jest w 32 bitowym LPC 1114:
LPC_GPIOx->DIR - rejestry kierunku
LPC_GPIOx->DATA - rejestry wyjściowe / wejściowe
Poniżej przykład w AVR ustawiający kierunek wyjścia pinu 1 portu A oraz ustawienie na nim stanu niskiego:
DDRA |= (1<<PA1); // kierunek pinu 1 portu PA na wyjściowy
PORTA &= ~(1<<PA1); // ustawienie stanu niskiego na pinie PA1
Analogicznie do w/w przykładu steruje się portami w LPC 1114:
LPC_GPIO0->DIR |= (1<<1); // kierunek pinu portu PORT0 na wyjściowy
LPC_GPIO0->DATA &|= ~(1<<1); // ustawienie stanu niskiego na pinie P0_1
Pora na przykład Witaj Świecie na LPC 1114, czyli mruganie diodą:
#include "LPC11xx.h" #define PIN_LED (1<<2) int main(void) { uint32_t i, j; LPC_GPIO0->DIR |= PIN_LED; // ustawienie pinu P0_2 na wyjsciowy while (1) { LPC_GPIO0->DATA |= PIN_LED; // stan wysoki na pinie P0_2 for ( i = 0; i < 1000000; i++); // realizacja opoznienia (taki niby delay :) j++; LPC_GPIO0->DATA &= ~PIN_LED; // stan niski na pinie P0_2 for ( i = 0; i < 1000000; i++); // realizacja opoznienia (taki niby delay :) j++; } }
Subskrybuj:
Posty (Atom)