XMOS - POCZĄTEK
Krótka charakterystyka procesora.
Jest to 8-rdzeniowy 32-bitowy procesor programowalny o wydajności 500 MIPS.
I większości ludzi to wystarcza aby “rzucić się na niego” jak w dawniejszych czasach ludzie rzucali się na papier toaletowy.
Mało kto, albo i nikt nie zwraca na początku uwagi na to, czego brakuje dla tego małego potworka. Otóż – co chyba najważniejsze – brakuje temu prockowi pamięci flash …. czyli dobrze znanej większości, nieulotnej pamięci programu, w której znajduje się nasz własnoręcznie napisany, często po wielkich przejściach program. Z wbudowanych w procesor funkcji, jakie możemy znać z PIC’a, Megi itp, posiada on tylko ADC. Jego rdzenie nie są rdzeniami jako takimi a tylko programową możliwością pracy w 8 wątkach jednocześnie. Zresztą, cały “procek” to układ typu CPLD - czyli emulator procesora … (krótko mówiąc i nie zagłębiając się w szczegóły)
Jeśli to jeszcze Was nie zniechęciło to możemy lecieć dalej…
Płytka StartKIT wyposażona jest w :
- procek XMOS Analog 8 - 64 – czyli ośmio rdzeniowy procesor CPLD bez pamięci flash z 64kb RAM
- Zewnętrzny flash - 256kb
- dwa ( X i Y ) slidery dotykowe - pojemnościowe
- jeden przycisk użytkownika
- 9 diod w matrycy 3x3 i 2 diody użytkownika
- złącze zgodne “pinologią” z Rassbery PI
- złącze pod karty SliceCards
- oraz resztę wyjść procesorka
- złącze MicroUSB służące do zasilania układu oraz debugera
ŚRODOWISKO
Tu pobieramy:
https://www.xmos.com/support/tools
Do pobrania jak i używania tego środowiska konieczne jest założenie konta.
Trochę to jest na początku niezbyt wygodne, ale po pierwszym uruchomieniu program zapamiętuje dane logowania i nie drażni już więcej.
Więc tak …. jest to po prostu brandowany przez XMOS Eclipse … I tyle. Wszystkim znającym Eclipsa nie trzeba mówić, że kiedy trzeba potrafi być szybki, przyjazny i bezproblemowy … chociaż zdarza się, jak chyba każdemu, odmówić współpracy i to bez podania przyczyn …. taki mały foch … ale z reguły wystarcza zrestartować Workspace lub, czasem, całe środowisko i wraca to to do normy i możemy pracować dalej.
Podstawowymi tutaj perspektywami są XMOS Edit, XMOS xSOFTip oraz DEBUG i TIME AS.
XMOS Edit to po prostu edytor kodu źródłowego w którym będziemy spędzać najwięcej czasu. Nie ma tu zbyt wiele do omawiania, dlatego że zakładam iż Eclipsa znają wszyscy …
XMOS xSOFT jest elementem który sam automatycznie łączy się z siecią i pozwala na proste ściąganie gotowych przykładów ze strony producenta oraz bibliotek, dzięki którym łatwiej nam się będzie pisało nasze programy.
XMOS - POCZĄTEK + HD44780 + TIMER
- acid3
- User
- Posty: 466
- Rejestracja: czwartek 03 wrz 2015, 22:42
- Lokalizacja: Kłopoty-Stanisławy
- Kontaktowanie:
Re: XMOS - POCZĄTEK
DOSTĘP DO PORTÓW.
Dostęp do portów w rodzinie XMOS to chyba jeden z większych problemów. Dla ludzi, którzy do tej pory mieli do czynienia z AVR’kami przerażający jest fakt, że nie można dostać się do portu w znany sposób przesunięć bitowych - (1<<PXx) oraz zastosowanie operacji bitowych | i &, które to pozwalały w bardzo miły sposób zarząć pinami na danym porcie. Zestaw XMOS StartKIT oferuje nam dostęp 1-no , 4-ro, 8-mio, oraz 32-bitowy. Większe zestawy posiadają również dostęp 16 - bitowy.
Cóż to oznacza ?
Otóż aby odczytać np 1 tylko pin przy dostępie 32 - bitowym musimy odczytać wszystkie 32 bity (piny) portu.
Jeśli chodzi o zmienne to nie jest problem, dlatego że procesorek jest 32-bitowy więc i zmienne typu int również są 32 bitowe.
Więc od początku. Najprościej jest dobrać sobie odpowiedni dostęp do portu do swoich potrzeb. I tak na przykład przy obsłudze LCD (2x16) linie RS i E przypisałem do portów 1-bitowych, RW do GND ( żeby nie motać się z kodem, a tylko sprawdzić jak to wszystko działa) a linie danych do portu o dostępie 4-bitowym. I tak oto w ten sposób dowolnie mogłem “wachlować” pinami sterującymi i w bardzo prosty sposób wysyłanie 4 bitów danych na port.
Podstawy.
definiuje dostęp do pinu X0D00 w sposób jedno-bitowy. To znaczy, że możemy teraz na pinie wystawić 0 lub 1 za pomocą operatora <:
i to jest podstawowy sposób wystawienia stanu wysokiego i niskiego na porcie uC XMOS.
Kolejną rzeczą jest możliwość definicji portu jako wejściowy lub wyjściowy.
C.D.N.
Dostęp do portów w rodzinie XMOS to chyba jeden z większych problemów. Dla ludzi, którzy do tej pory mieli do czynienia z AVR’kami przerażający jest fakt, że nie można dostać się do portu w znany sposób przesunięć bitowych - (1<<PXx) oraz zastosowanie operacji bitowych | i &, które to pozwalały w bardzo miły sposób zarząć pinami na danym porcie. Zestaw XMOS StartKIT oferuje nam dostęp 1-no , 4-ro, 8-mio, oraz 32-bitowy. Większe zestawy posiadają również dostęp 16 - bitowy.
Cóż to oznacza ?
Otóż aby odczytać np 1 tylko pin przy dostępie 32 - bitowym musimy odczytać wszystkie 32 bity (piny) portu.
Jeśli chodzi o zmienne to nie jest problem, dlatego że procesorek jest 32-bitowy więc i zmienne typu int również są 32 bitowe.
Więc od początku. Najprościej jest dobrać sobie odpowiedni dostęp do portu do swoich potrzeb. I tak na przykład przy obsłudze LCD (2x16) linie RS i E przypisałem do portów 1-bitowych, RW do GND ( żeby nie motać się z kodem, a tylko sprawdzić jak to wszystko działa) a linie danych do portu o dostępie 4-bitowym. I tak oto w ten sposób dowolnie mogłem “wachlować” pinami sterującymi i w bardzo prosty sposób wysyłanie 4 bitów danych na port.
Podstawy.
Kod: Zaznacz cały
port p = XS1_PORT_1A;
definiuje dostęp do pinu X0D00 w sposób jedno-bitowy. To znaczy, że możemy teraz na pinie wystawić 0 lub 1 za pomocą operatora <:
Kod: Zaznacz cały
p <: 1;
p <: 0;
i to jest podstawowy sposób wystawienia stanu wysokiego i niskiego na porcie uC XMOS.
Kolejną rzeczą jest możliwość definicji portu jako wejściowy lub wyjściowy.
Kod: Zaznacz cały
out port p = XS1_PORT_1A;
in port p = XS1_PORT_1A;
C.D.N.
- acid3
- User
- Posty: 466
- Rejestracja: czwartek 03 wrz 2015, 22:42
- Lokalizacja: Kłopoty-Stanisławy
- Kontaktowanie:
Re: XMOS - POCZĄTEK + HD44780 + TIMER
Więc zajmiemy się tym razem wyświetleniem tekstu na wyświetlaczu LCD 2x16.
Na początek krótkie wyjaśnienie. W większości, tanie, popularne wyświetlacze pracują w standardzie +5V – zarówno podświetlenie, zasilanie, linie sterujące oraz linie danych. Nasza płytka XMOS pracuje natomiast w standardzie 3.3V ale to nie przeszkadza aby zasilić ekranik z 5V a na linie sterownika podawać 3.3V. Sterownik będzie działał bez problemu.
Konfiguracja - pinologia.
Zasilanie i podświetlenie podłączamy dowolnie we własnym zakresie. Ja do zasilenia wykorzystałem zestaw uruchomieniowy MicroSense.
Na płytce z XMOS’em natomiast podłączamy następująco:
Szynę danych 4-bity podłączamy do jednego z 4-bitowych portów XMOS. Ja do tego celu wybrałem port 4E. Jego wyprowadzenia znajdują sie na złączu J7 na pinach 22, 24, 16, 18.
Zasadniczo to nie ma znaczenia który port wybierzemy i za pomocą jakiego dostępu. Po prostu zawsze staram się upraszczać sobie życie, chociaż jak to w życiu nie zawsze wychodzi.
Linia RS to Port 1E, pin X0D12 - czyli 4 pin złącza J7
Linia EN to Port 1F, pin X0D13 - czyli 1 pin złącza J7
Następnym krokiem jest uproszczenie sobie dalszego pisania poprzez zdefiniowanie makrodefinicji upraszczających dostęp i sterowanie portami linii sterujących.
Pierwsza definicja dla linii RS:
Definicja dla linii EN:
Następnym krokiem będzie napisanie podstawowych funkcji. Pierwszą z nich niech będzie send_4bits(). Będzie ona (jak mam nadzieję) wskazuje nazwa wysyłała pół bajtu.
Jak widzimy wyżej, ta funkcja już chyba nie może być prostsza ….
W pierwszej linii najzwyczajniej na świecie wysyłamy hurtem “na piny” to co otrzymaliśmy w argumencie funkcji. Musiałem jednak dodać tu opóźnienie 1 us, ze względu na to, że sterownik nie chciał prawidłowo wyświetlać danych. Po tym mikro-opóźnieniu wszystko działa jak należy.
A więc jaka będzie następna ? …….
Następna funkcja będzie wysyłała cały bajt do sterownika.
Tutaj również nic nie powinno budzić naszych wąptliwości … Ażeby wysłać cały bajt musimy dwukrotnie powtórzyć funkcję wyślij_pół z odpowiednim przesunięciem i pamiętać o właściwym wysterowaniu linii komend. Opóźnienie na końcu wynika ze specyfikacji sterownika i jego wymogów w czasie gdy nie sterujemy linią RW.
Kolejną funkcją “niskiego poziomu” będzie funkcja wysyłająca komendę do sterownika
……. i do pary ……
….. funkcja wysyłająca dane.
Hmmm. Skoro umiemy już wysłać i komendę i dane to chyba czas najwyższy wyłać jakiś znak.
i string .... wyślecie sami ... w ramach zadania domowego.
To jeszcze jedna "funkcyjka" na rozluźnienie przed rzeczami bardziej skomplikowanymi .... Czyszczenie ekranu.
Tu jedynym co się rzuca w oczy jest czas oczekiwania .... 4.9 ms należy odczekać ażeby ekran mógł zostać wyczyszczony - tak mówi DS w wypadku kiedy nie używa się linii RW.
I powoli zaczynamy zbliżać się ku końcowi. Rzecz najważniejsza. Inicjalizacja wyświetlacza.
Powyższe dane wynikają z DS. O ile wachlowanie inicjalizacyjne nie jest dla nas bardzo istotne - tak mówi DS i tak ma być, o tyle tryby pracy pozwalają na kilka sztuczek i można się nimi pobawić. Po szczegóły zapraszam na 24 stronę DS sterownika HD44780.
Pętla główna to już tylko formalność.
Na początek krótkie wyjaśnienie. W większości, tanie, popularne wyświetlacze pracują w standardzie +5V – zarówno podświetlenie, zasilanie, linie sterujące oraz linie danych. Nasza płytka XMOS pracuje natomiast w standardzie 3.3V ale to nie przeszkadza aby zasilić ekranik z 5V a na linie sterownika podawać 3.3V. Sterownik będzie działał bez problemu.
Konfiguracja - pinologia.
Zasilanie i podświetlenie podłączamy dowolnie we własnym zakresie. Ja do zasilenia wykorzystałem zestaw uruchomieniowy MicroSense.
Na płytce z XMOS’em natomiast podłączamy następująco:
Szynę danych 4-bity podłączamy do jednego z 4-bitowych portów XMOS. Ja do tego celu wybrałem port 4E. Jego wyprowadzenia znajdują sie na złączu J7 na pinach 22, 24, 16, 18.
Kod: Zaznacz cały
out port LCD_DATA = XS1_PORT_4E;
Zasadniczo to nie ma znaczenia który port wybierzemy i za pomocą jakiego dostępu. Po prostu zawsze staram się upraszczać sobie życie, chociaż jak to w życiu nie zawsze wychodzi.
Linia RS to Port 1E, pin X0D12 - czyli 4 pin złącza J7
Linia EN to Port 1F, pin X0D13 - czyli 1 pin złącza J7
Następnym krokiem jest uproszczenie sobie dalszego pisania poprzez zdefiniowanie makrodefinicji upraszczających dostęp i sterowanie portami linii sterujących.
Pierwsza definicja dla linii RS:
Kod: Zaznacz cały
#define RS_HI LCD_RS <: 1
#define RS_LO LCD_RS <: 0
Definicja dla linii EN:
Kod: Zaznacz cały
#define EN_HI LCD_EN <: 1
#define EN_LO LCD_EN <: 0
Następnym krokiem będzie napisanie podstawowych funkcji. Pierwszą z nich niech będzie send_4bits(). Będzie ona (jak mam nadzieję) wskazuje nazwa wysyłała pół bajtu.
Kod: Zaznacz cały
static inline void send_4bits ( unsigned char data )
{
LCD_DATA <: data; // LCD_DATA - definicja portu 4E
delay_microseconds(1);
}
Jak widzimy wyżej, ta funkcja już chyba nie może być prostsza ….
W pierwszej linii najzwyczajniej na świecie wysyłamy hurtem “na piny” to co otrzymaliśmy w argumencie funkcji. Musiałem jednak dodać tu opóźnienie 1 us, ze względu na to, że sterownik nie chciał prawidłowo wyświetlać danych. Po tym mikro-opóźnieniu wszystko działa jak należy.
A więc jaka będzie następna ? …….
Następna funkcja będzie wysyłała cały bajt do sterownika.
Kod: Zaznacz cały
void send_8bits(unsigned char _data){
EN_HI;
send_4bits(_data >> 4);
EN_LO;
EN_HI;
send_4bits(_data);
EN_LO;
delay_microseconds(120);
}
Tutaj również nic nie powinno budzić naszych wąptliwości … Ażeby wysłać cały bajt musimy dwukrotnie powtórzyć funkcję wyślij_pół z odpowiednim przesunięciem i pamiętać o właściwym wysterowaniu linii komend. Opóźnienie na końcu wynika ze specyfikacji sterownika i jego wymogów w czasie gdy nie sterujemy linią RW.
Kolejną funkcją “niskiego poziomu” będzie funkcja wysyłająca komendę do sterownika
Kod: Zaznacz cały
void send_cmd(unsigned char cmd)
{
RS_LO; // Stan niski linii RS - wysyłamy komendę
send_8bits(cmd);
}
……. i do pary ……
Kod: Zaznacz cały
void lcd_write_data(unsigned char data)
{
RS_HI; // ...a wysoki stan - wysyłamy dane
send_8bits(data);
}
….. funkcja wysyłająca dane.
Hmmm. Skoro umiemy już wysłać i komendę i dane to chyba czas najwyższy wyłać jakiś znak.
Kod: Zaznacz cały
void lcd_char(char c)
{
lcd_write_data(c);
}
i string .... wyślecie sami ... w ramach zadania domowego.
To jeszcze jedna "funkcyjka" na rozluźnienie przed rzeczami bardziej skomplikowanymi .... Czyszczenie ekranu.
Kod: Zaznacz cały
void lcd_cls(void)
{
send_cmd( 0x01 );
delay_milliseconds(4.9);
}
Tu jedynym co się rzuca w oczy jest czas oczekiwania .... 4.9 ms należy odczekać ażeby ekran mógł zostać wyczyszczony - tak mówi DS w wypadku kiedy nie używa się linii RW.
I powoli zaczynamy zbliżać się ku końcowi. Rzecz najważniejsza. Inicjalizacja wyświetlacza.
Kod: Zaznacz cały
void lcd_init(void)
{
LCD_RS <: 1;
LCD_EN <: 1;
delay_milliseconds(15);
LCD_RS <: 0;
LCD_EN <: 0;
EN_HI; send_4bits(0x03); EN_LO;
delay_milliseconds(4.1);
EN_HI; send_4bits(0x03); EN_LO;
delay_microseconds(100);
EN_HI; send_4bits(0x03); EN_LO;
delay_microseconds(100);
EN_HI; send_4bits(0x02); EN_LO;
delay_microseconds(100);
send_cmd(0b00101000); // TRYB PRACY
send_cmd(0b00001100); // WŁ. Wyśw.
send_cmd(0b00000110); // Zachowanie kursora
lcd_cls();
}
Powyższe dane wynikają z DS. O ile wachlowanie inicjalizacyjne nie jest dla nas bardzo istotne - tak mówi DS i tak ma być, o tyle tryby pracy pozwalają na kilka sztuczek i można się nimi pobawić. Po szczegóły zapraszam na 24 stronę DS sterownika HD44780.
Kod: Zaznacz cały
int main (void){
lcd_init();
lcd_cls();
lcd_char('X');
lcd_char('M');
lcd_char('O');
lcd_char('S');
return 0;
}
Pętla główna to już tylko formalność.
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
- acid3
- User
- Posty: 466
- Rejestracja: czwartek 03 wrz 2015, 22:42
- Lokalizacja: Kłopoty-Stanisławy
- Kontaktowanie:
Re: XMOS - POCZĄTEK + HD44780 + TIMER
Timer xCore jest 32-bitowym licznikiem popędzanym z częstotliwością 100Mhz.
Podstawowa deklaracja timera to:
Timery mogą być deklarowane zarówno jako zmienne globalne jak i zmienne lokalne. Przekazanie wartości Timera do zmiennej odbywa się za pomocą operatora :> :
To wpisuje aktualną wartość timera do zmiennej time. ( Zmienna int w uC xCore jest 32-bitowa )
Aby zmierzyć czas pomiędzy dwoma zdarzeniami, wystarczy powołać dwie zmienne, np: start_time, end_time.
unsigned int start_time, end_time;
... oraz wyświetlić sobie różnicę :
Ze względu na "pojemność" 32-bitowej zmiennej 2e32 - 1, możemy mierzyć czas do ok. 42 sekund.
Wyświetlanie napisu oraz wartości zmiennej typu timer 100 razy co 1 sekundę:
Podstawowa deklaracja timera to:
Kod: Zaznacz cały
timer t;
Timery mogą być deklarowane zarówno jako zmienne globalne jak i zmienne lokalne. Przekazanie wartości Timera do zmiennej odbywa się za pomocą operatora :> :
Kod: Zaznacz cały
unsigned int time;
t :> time;
To wpisuje aktualną wartość timera do zmiennej time. ( Zmienna int w uC xCore jest 32-bitowa )
Aby zmierzyć czas pomiędzy dwoma zdarzeniami, wystarczy powołać dwie zmienne, np: start_time, end_time.
unsigned int start_time, end_time;
Kod: Zaznacz cały
// Początek pomiaru
t :> strat_time;
...
...
...
// Koniec pomiaru
t :> end_time;
... oraz wyświetlić sobie różnicę :
Kod: Zaznacz cały
printstr (" Liczba tick'ów timera : ");
printintln(end_time - start_time);
Ze względu na "pojemność" 32-bitowej zmiennej 2e32 - 1, możemy mierzyć czas do ok. 42 sekund.
Wyświetlanie napisu oraz wartości zmiennej typu timer 100 razy co 1 sekundę:
Kod: Zaznacz cały
for (unsigned int i = 0; i < 100; i++){
printstr("Once a second : ");
printintln(time);
time += XS1_TIMER_MHZ * 1000 * 1000;
t when timerafter(time) :> void;
}
Wróć do „Inne mikroklocki, również peryferyjne”
Kto jest online
Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 1 gość