Elektroda.pl
Elektroda.pl
X
Elektroda.pl
Computer Controls
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

XMega 128 - kilka portów pod jeden kanał zdarzeń?

drzasiek 11 Lip 2011 23:09 4161 31
  • #1 11 Lip 2011 23:09
    drzasiek
    Specjalista - Mikrokontrolery

    Witam. Problem mam, a właściwie to nie tyle problem co pytanie, czy można moje zamierzenie rozwiązać prościej.
    Otóż w urządzeniu które buduję do nawigacji użyty jest joystick z siemensa działający jak 5 klawiszy więc można przyjąć, że mam 5 klawiszy. Urządzenie cały czas coś wyświetla, liczy więc obsługa w pętli głównej odpada, bo można by przegapić krótkie wciśniecie klawisza. Zatem konieczne jest zrealizowanie tego w przerwaniach. Joy podłączony jest do 5 portów z pull-up'em. Porty te ustawione są jako kanały zdarzeń i aktywne zboczem opadającym. Docelowo ma być jeszcze jeden klawisz tego typu więc już mi ucieka 6 kanałów a szkoda, bo zostaje już tylko 2 a potrzeba mi jeszcze kilka. W obecnej sytuacji każdy klawisz ma swój wektor i swoje przerwanie, co z jednej strony jest wygodne bo nie trzeba rozpoznawać który klawisz został wciśnięty a z drugiej kłopotliwe, bo przy rozbudowanym menu będę musiał w każdym przerwaniu napisać sporo kodu. Tak więc mam 2 powody, aby wszystko wrzucić w jedno przerwanie i uprościć obsługę oraz zaoszczędzić kanały.
    Mam pomysł jak to bardzo prosto zrealizować sprzętowo ale jeśli można programowo, to po co dorzucać tych kilka elementów. Więc dochodzę do meritum i tu moje pytanie:
    Czy da się programowo ustawić kilka portów wejściowych na jeden kanał zdarzeń? Tak aby po wystąpieniu zadanego poziomu/zbocza na którymkolwiek ze kilku zdefiniowanych portów wystąpiło tylko jedno przerwanie?

    0 29
  • Computer Controls
  • Pomocny post
    #2 11 Lip 2011 23:21
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Możesz to przecież zrobić "sprzętowo" - każdy przycisk osobno do "dowolnego" portu, a dodatkowo wszystkie razem do portu "z przerwaniem", z tym, że od każdego przycisku do tego specjalnego portu dajesz diodę. Tym sposobem masz tylko jedno przerwanie, ale możesz wykrywać który przycisk został naciśnięty.

    Ponieważ i tak trzeba kombinować, to możesz zaoszczędzić i spróbować zrobić przyciski "analogowe". Od portu do masy (lub odwrotnie - wiadomo) masz jakiś tam rezystor. Każdy przycisk dołączony jest do tego portu, a od drugiej strony przez różne rezystory podłączone są do VCC. Tym sposobem, każdy przycisk tworzy inny dzielnik, a więc inne napięcie. Owe napięcie mierzysz i decydujesz, który przycisk został naciśnięty.

    No a tak naprawdę, to jak chcesz zrobić tyle przycisków, to zamiast faktycznie marnować przerwania zewnętrzne, to po prostu zrób timer (programowy albo sprzętowy) wyzwalany co kilkanaście-kilkadziesiąt ms i w procedurze odczytuj stan normalnych portów (albo zastosuj patent "analogowy").

    Jakbyś miał system operacyjny (np. FreeRTOS), to sprawa jest bardziej niż banalna. A tak naprawdę, to nawet bez systemu bardzo przydaje się możliwość "zakolejkowania" sobie wywołania jakichś funkcji "za ileśtam czasu" albo "co ileśtam czasu", czyli prosty scheduler (; Bez czegoś takiego to jak bez ręki [;

    4\/3!!

    0
  • #3 11 Lip 2011 23:43
    drzasiek
    Specjalista - Mikrokontrolery

    Freddie Chopin napisał:
    Możesz to przecież zrobić "sprzętowo" - każdy przycisk osobno do "dowolnego" portu, a dodatkowo wszystkie razem do portu "z przerwaniem", z tym, że od każdego przycisku do tego specjalnego portu dajesz diodę. Tym sposobem masz tylko jedno przerwanie, ale możesz wykrywać który przycisk został naciśnięty.

    Pisałem, że mam pomysł jak to rozwiązać sprzętowo i dokładnie ten sposób miałem na myśli :) Prosty i skuteczny ale wymaga na płytce dodatkowo tyle diod ile klawiszy więc pytam o możliwości programowe, bo skoro można zaoszczędzić pieniędzy i miejsca na płytce to czemu nie.
    Cytat:

    Ponieważ i tak trzeba kombinować, to możesz zaoszczędzić i spróbować zrobić przyciski "analogowe". Od portu do masy (lub odwrotnie - wiadomo) masz jakiś tam rezystor. Każdy przycisk dołączony jest do tego portu, a od drugiej strony przez różne rezystory podłączone są do VCC. Tym sposobem, każdy przycisk tworzy inny dzielnik, a więc inne napięcie. Owe napięcie mierzysz i decydujesz, który przycisk został naciśnięty.

    Całkowicie odpada, więcej elementu i programu niż dla rozwiązania 1. Poza tym ADC mam nie do ruszenia, ma już swoje zastosowanie w tym urządzeniu :)
    Cytat:

    No a tak naprawdę, to jak chcesz zrobić tyle przycisków, to zamiast faktycznie marnować przerwania zewnętrzne, to po prostu zrób timer (programowy albo sprzętowy) wyzwalany co kilkanaście-kilkadziesiąt ms i w procedurze odczytuj stan normalnych portów (albo zastosuj patent "analogowy").

    Strata czasu, bardzo cennego czasu który mogę przeznaczyć na obliczenia. Lepiej jak ktoś zatrąbi jak już przyjedzie, niż co chwilę zaglądać do okna, czy już jest :)
    Cytat:

    Jakbyś miał system operacyjny (np. FreeRTOS), to sprawa jest bardziej niż banalna. A tak naprawdę, to nawet bez systemu bardzo przydaje się możliwość "zakolejkowania" sobie wywołania jakichś funkcji "za ileśtam czasu" albo "co ileśtam czasu", czyli prosty scheduler (; Bez czegoś takiego to jak bez ręki [;

    Bez lutownicy to jak bez ręki, a bez systemu można żyć :)
    Generalnie dzięki za odpowiedź, podałeś sposoby jak to ominąć, a nie o to mi chodziło, bo taki sposób akurat mam. Bardziej chodziło mi o to, czy trzeba to omijać właśnie czy czegoś nie doczytałem w DS i można to prosto ustawić programowo.
    pozdrawiam

    0
  • #4 11 Lip 2011 23:47
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Jeśli odczyt 6-ciu pinów (w optymalnym przypadku JEDEN odczyt całego portu) co kilkanaście ms jest zbytnim obciążeniem dla mikrokontrolera, to ja wysiadam...

    4\/3!!

    0
  • Computer Controls
  • #5 11 Lip 2011 23:57
    drzasiek
    Specjalista - Mikrokontrolery

    Freddie Chopin napisał:
    Jeśli odczyt 6-ciu pinów (w optymalnym przypadku JEDEN odczyt całego portu) co kilkanaście ms jest zbytnim obciążeniem dla mikrokontrolera, to ja wysiadam...

    4\/3!!

    Generalnie chodzi o to, że sprawdzanie musiałoby być często. Dodatkowo dochodzi bardzo wiele innych liczników, przerwań i obliczeń w przerwaniach. Poza przerwaniami program ma jeszcze całą masę roboty, głównie "cyklo-żernych" operacji graficznych oraz inne obliczenia. Dochodzą do tego zewnętrzne triggery. Masa roboty, 32 MHz to to momentami mało. Dla mnie każda mała zmarnowana chwila się liczy, nie chcę powtórzyć niektórych błędów z wersji 3 oscyloskopu.
    Aha, i zapomniałem wcześniej dodać, że zależy mi, żeby klawisze reagowały na kliknięcia a dłuższe przytrzymanie nie traktowane było jako kolejne naciśnięcie. Sprawdzanie stanu portu co jakiś czas nie wykryje samo z siebie zbocza więc trzeba by to programowo robić.
    Uprzedzając twój następny post odpowiadam:
    Tak wiem, na ARMy przyjdzie czas, może już niedługo :)

    0
  • #6 12 Lip 2011 00:43
    gaskoin
    Poziom 38  

    A powinien już w tej chwili, bo IMHO XMEGI nie mają jakichś mega osiągów (jak za swoją cenę) a i cenowo i wydajnościowo ARM wychodzi dużo taniej (najtańszy to koszt koło 6 zł). Przesiadka jest na nie dość długa (jeżeli ktoś faktycznie chce wiedzieć co i jak a nie "byle żeby"), ale się opłaca.

    Acha i pewnie napiszecie o kosztujących fortunę JTAGach - są jakieś klony, które można zbudować za 20 zł, a najtańszy "programator" do ARMów kosztuje koło 1zł w sklepie za metr bieżący :)

    BTW przerwań nie powinno się za bardzo blokować wykonując w nich obliczenia, ale może ja tu czegoś nie zrozumialem z architektury programu

    0
  • Pomocny post
    #7 12 Lip 2011 01:05
    tomhandyman
    Poziom 13  

    Każdy klawisz joya masz podłaczony od osobnego portu czy osobnego pinu w jednym porcie?
    Jeżeli idzie o 32 MHz , spróbuj podkręcić go o ile warunki projektu pozwalają. Nie sprawdziłem zapisu eepromu ale timery, uart działały do 55Mhz (5 x 11.0592 Mhz) przy standardowym zasilaniu 3.3V. Jutro przetestuję eeprom po przetaktowaniu. Wracając do tematu, jeśli możesz mieć piny w jednym porcie to INT0 lub INT1 danego portu lub jesli masz piny rozmieszczone na kilku portach, to w każdym osobnym przerwaniu możesz wywoływać tą samą funkcję obsługi joya z parametrem jaki klawisz. Masz szybkie rozpoznanie i jeden program obsługi przerwania.
    Sądzę że w tym przypadku nie musisz korzystać z "system event" i wykorzystać kanały na inne częstsze przerwania krytyczne czasowo.

    0
  • #8 12 Lip 2011 01:13
    drzasiek
    Specjalista - Mikrokontrolery

    Oczywiście chodziło o jeden port a kilka pinów w porcie. Przepraszam za niefachowe określenie, tak sobie to jakoś nazywam ale trzeba się odzwyczaić. Podkręcał nie będę, bo z pewnych względów nie mogę sobie na to pozwolić. Ale testowałem, działa do 64MHz przy zasilaniu 3.3V ale to już takie resztki siły xmegi ale nie sprawdzałem eeprom.
    Chodzi o zaoszczędzenie kanałów zewnętrznych zdarzeń i czy da się podłączyć kilka pinów pod jeden kanał programowo czy muszę to zrobić sprzętowo. I tyle.

    0
  • #9 12 Lip 2011 01:39
    tomhandyman
    Poziom 13  

    Nie dasz rady podłączyć kilka pinów pod jeden kanał system events, jest tylko jeden CHnMUX na kanał. W formie protezy na przerwanie INT z kilku pinów możesz programowo włączać przerwanie events.

    0
  • #10 12 Lip 2011 01:44
    ktrot
    Poziom 19  

    Proponuję zmodyfikować nieco pomysł kolegi Freddiego:
    5 wyjść joysticka do 5 pinów a wspólny do 1 pinu z przerwaniem (bez diod).

    1. Stan sprawdzania przerwania - 5 jako wyjście i na 0, wspólny z podciąganiem, dowolne naciśnięcie powoduje przerwanie.

    Gdy przerwanie wystąpiło wykonujemy:
    2. Stan sprawdzania, który został naciśnięty - 5 pinów jako wejście z podciąganiem a wspólny jako wyjście i na 0. Sprawdzamy stan portu.

    0
  • #11 12 Lip 2011 08:33
    Freddie Chopin
    Specjalista - Mikrokontrolery

    drzasiek napisał:
    Generalnie chodzi o to, że sprawdzanie musiałoby być często.

    Jesteś w stanie naciskać przyciski szybciej niż co 20ms? Wątpię...

    Cytat:
    Dodatkowo dochodzi bardzo wiele innych liczników, przerwań i obliczeń w przerwaniach. Poza przerwaniami program ma jeszcze całą masę roboty, głównie "cyklo-żernych" operacji graficznych oraz inne obliczenia. Dochodzą do tego zewnętrzne triggery. Masa roboty, 32 MHz to to momentami mało. Dla mnie każda mała zmarnowana chwila się liczy, nie chcę powtórzyć niektórych błędów z wersji 3 oscyloskopu.

    Prawda jest taka, że tutaj debatujesz nad oszczędzeniem ułamków promila, a zaoszczędzić można więcej pisząc lepiej inny kod... Proste i brutalne. Policz sam:
    powiedzmy, że co 20ms przerwanie z takim sprawdzeniem zajmie 50cykli (wg mnie mniej, no ale niech będzie). 50Hz x 50cykli = 2500 cykli w ciągu sekundy. Przy 32MHz stanowi to zawrotne obciążenie 0,0078125%... Za dużo? Błagam...

    Cytat:
    Aha, i zapomniałem wcześniej dodać, że zależy mi, żeby klawisze reagowały na kliknięcia a dłuższe przytrzymanie nie traktowane było jako kolejne naciśnięcie. Sprawdzanie stanu portu co jakiś czas nie wykryje samo z siebie zbocza więc trzeba by to programowo robić.

    Ale to się da jak najbardziej zrobić wg mojego pomysłu i działa to perfekcyjnie, jest super proste itd. Wystarczy zapamiętać poprzedni stan i jako wynik funkcji traktować operację (~poprzedni) & (aktualny) (czy jakoś tak) - wtedy będziesz miał jedynki tylko tam gdzie stan się ZMIENIŁ. Doda to do całości kilka cykli (odczyt, zapis, negacja, and) i nic nie zmieni... Na forum jest przykład kodu mojego autorstwa który właśnie to robi, mogę Ci to znaleźć.

    Cytat:
    Uprzedzając twój następny post odpowiadam:
    Tak wiem, na ARMy przyjdzie czas, może już niedługo :)

    Spoko - za kilka miesięcy napiszesz "Robię ten projekt na ARM, bo nie chcę powtórzyć błędów z wersji N-1". Jak brakuje mocy, to nie optymalizuje się czegoś co zajmuje tysięczne części procenta, tylko to co naprawdę zajmuje moc. Ewentualnie bierze się szybszy układ.

    Takie przysłowie jest - Premature optimization is the root of all evil. W tym przypadku akurat niekoniecznie jest "premature", bardziej "misplaced", ale idea jet taka sama - optymalizujesz nie to co trzeba. Gwarantuję Ci, że zoptymalizowanie innych miejsc programu pozwoli Ci zaoszczędzić 100x tyle niż to o co kruszymy kopię w tym wątku.

    4\/3!!

    0
  • #12 12 Lip 2011 09:34
    drzasiek
    Specjalista - Mikrokontrolery

    tomhandyman napisał:
    Nie dasz rady podłączyć kilka pinów pod jeden kanał system events, jest tylko jeden CHnMUX na kanał. W formie protezy na przerwanie INT z kilku pinów możesz programowo włączać przerwanie events.

    Dziękuję. Tylko o taką odpowiedź mi chodziło, da się albo się nie da. Rozważanie jak zrobić to inaczej jest zbędne bo już mam pomysł.
    Dziękuję za zniechęcenia do optymalizacji, ale postanowiłem od początku że nie będę marnował czasu ( i nie ważne ile bym go zmarnował) ale podejdę profesjonalnie. Po to są przerwania (jeśli chodzi tutaj to zewnętrzne) żeby nie trzeba było sprawdzać co chwile więc ja chce to wykorzystać. I tyle. A ta cała dyskusja jak to zrobić inaczej i czemu chce akurat tak nie była potrzebna, bo nie o to pytałem. Jak to ominąć wiedziałem, chciałem tylko wiedzieć czy muszę omijać czy nie. Tyle.
    Dziękuję za odpowiedzi

    0
  • #13 12 Lip 2011 09:51
    Freddie Chopin
    Specjalista - Mikrokontrolery

    drzasiek napisał:
    Dziękuję za zniechęcenia do optymalizacji, ale postanowiłem od początku że nie będę marnował czasu ( i nie ważne ile bym go zmarnował) ale podejdę profesjonalnie.

    Podejście które prezentujesz niestety nie ma nic wspólnego z profesjonalizmem, tylko ze źle ukierunkowanym wysiłkiem. Nie czytasz też ze zrozumieniem - nikt nie zniechęca Cię do optymalizacji, tylko zachęcamy Cię do optymalizacji tam gdzie to ma uzasadnienie! Wytłumacz mi jaki jest sens optymalizować coś co zajmuje 0.008% czasu jeśli można zoptymalizować w tym samym czasie coś co zajmuje tego czasu 8% (nie mówiąc już o czymś co zajmuje 80% czasu) - gdzie więcej zyskasz wykonując tą samą pracę?

    4\/3!!

    0
  • Pomocny post
    #14 12 Lip 2011 10:04
    tmf
    Moderator Mikrokontrolery Projektowanie

    Niestety Freddie Chopin w całej rozciągłości ma rację. Tracisz czas na coś co nic, w sensie wydajności, ci nie da. Umieszczanie odczytu klawiszy w pętli głównej programu wcale nie jest jakimś błędem, nie w każdej sytuacji trzeba wszystko pakować w przerwanie. W dodatku wejście i wyjście z przerwania trwa trochę, pomijam ok. 4 cykle na wejście, to jeszcze jak piszesz w avr-gcc to masz kosmiczny prolog i epilog, w efekcie najprostsza obsługa przerwania trwa co najmniej 60 cykli. W tym czasie zrealizujesz całą obsługę klawiszy w pętli głównej.
    Druga rzecz - pamiętaj, że masz DMA, odświeżanie LCD możesz zrealizować na DMA z małym buforem w SRAM, na czym powinieneś zyskać co najmniej 50% oszczędności.

    0
  • #15 12 Lip 2011 11:26
    drzasiek
    Specjalista - Mikrokontrolery

    Nie rozumiemy się. W żadnym momencie nie powiedziałem, że optymalizował będę tu a gdzie indziej nie. Z całością muszę powalczyć, przemyśleć i nieźle pogłówkować. I nie twierdzę że jestem profesjonalistą, ledwo na początkującego się załapuję ale jeśli mam do wyboru zrobić coś szybciej wykorzystując możliwości jakie daje uC a zrobić to nieco wolniej realizując pewne rzeczy programowo to ja akurat wybieram to pierwsze. I każdy tutaj może mieć swoje zdanie, ja nie zamierzam się kłócić ani przekonywać do swoich racji. Jeśli podejdę raz do tego w ten sposób, nic się nie dzieje. Ale obsługa klawiszy to nie jedyne co będzie robiło to urządzenie, sumując zmarnowane czasy i tak niewiele wyjdzie ale realizując programowo to, co może zrobić kanał przerwania kod się niepotrzebnie rozrasta. I teraz tutaj znowu można dyskutować i porównywać o ile się kod rozrasta, ale czy o to chodzi?

    Postawiłem sobie pewne założenia i chciałbym się ich trzymać.

    tmf napisał:
    Niestety Freddie Chopin w całej rozciągłości ma rację. Tracisz czas na coś co nic, w sensie wydajności, ci nie da. Umieszczanie odczytu klawiszy w pętli głównej programu wcale nie jest jakimś błędem, nie w każdej sytuacji trzeba wszystko pakować w przerwanie. W dodatku wejście i wyjście z przerwania trwa trochę, pomijam ok. 4 cykle na wejście, to jeszcze jak piszesz w avr-gcc to masz kosmiczny prolog i epilog, w efekcie najprostsza obsługa przerwania trwa co najmniej 60 cykli. W tym czasie zrealizujesz całą obsługę klawiszy w pętli głównej.
    Druga rzecz - pamiętaj, że masz DMA, odświeżanie LCD możesz zrealizować na DMA z małym buforem w SRAM, na czym powinieneś zyskać co najmniej 50% oszczędności.

    I tu się mylisz niestety. Tak zrealizowane to było w wersji 3 i uniemożliwiło mi to realizację interpolacji ciągłej, nagrywania przebiegów albo dodanie bardzo wolnych podstaw czasu. Oczywiście można to zrealizować inaczej, ale będę co wyświetlenie ileś tam pikseli sprawdzał, czy nie został naciśnięty jakiś klawisz? Albo w funkcji interpolacyjnej co wymnożenie jednej próbki będę sprawdzał stan klawiszy? Przy zwykłym pomiarze nic się nie dzieje, sprawdzanie może się odbywać co jeden obieg pętli ale przy bardziej skomplikowanych funkcjach i obliczeniach obieg pętli głównej trwa dłużej i łatwo można przegapić naciśniecie klawiszy a i samo poruszanie się po menu staje się ospałe.
    Mam DMA ale niestety tylko 4 kanały :) 2 kanały na ADC, jeden kanał na DAC i zostaje mi już tylko jeden który w zasadzie już mam zarezerwowany.

    0
  • Pomocny post
    #16 12 Lip 2011 11:36
    tmf
    Moderator Mikrokontrolery Projektowanie

    Tak jak pisałem, obsługa przerwania ze względu na uwarunkowania kompilatora jest piekielnie długa i naprawdę na tym nic nie zyskujesz. Zobacz jak wygląda wygenerowany kod asemblerowy nawet dla prostej funkcji.
    Piszesz o sprawdzeniu stanu klawisza co chwile, a czym to się różni od sprawdzania co chwilę flagi, którą zmienisz w przerwaniu? Chyba, że masz coś w stylu RTOS, a nie sądzę aby tak było.
    Co do DMA to kanałów nie musisz mieć przyporządkowanych na sztywno do jakiejś funkcji. O ile dla ADC i DAC warto, to czwarty można wykorzystać już do kilku, np. obsługi SPI.

    0
  • #17 12 Lip 2011 11:56
    drzasiek
    Specjalista - Mikrokontrolery

    tmf napisał:
    Tak jak pisałem, obsługa przerwania ze względu na uwarunkowania kompilatora jest piekielnie długa i naprawdę na tym nic nie zyskujesz. Zobacz jak wygląda wygenerowany kod asemblerowy nawet dla prostej funkcji.
    Piszesz o sprawdzeniu stanu klawisza co chwile, a czym to się różni od sprawdzania co chwilę flagi, którą zmienisz w przerwaniu?

    Tym, że w każdą dłużej wykonującą się funkcję nie muszę wklepywać tego samego kodu sprawdzającego stan przycisków? A potem zapisywać gdzie akurat był program, skoczyć do funkcji obsługującej przyciski i wrócić skąd przyszedłem. No chyba, że w każdej funkcji w instrukcji warunkowej wklepywać całą obsługę przycisków, ale to ma być optymalne?
    Cytat:

    Co do DMA to kanałów nie musisz mieć przyporządkowanych na sztywno do jakiejś funkcji. O ile dla ADC i DAC warto, to czwarty można wykorzystać już do kilku, np. obsługi SPI.

    DO SPI nie potrzebuję DMA, bo jeśli odczytuję lub zapisuję przebiegi to wtedy nic innego się nie wykonuje, bo nie ma po co. Jak zapisuję bitmapę to robię zrzut ekranu a więc odczyt z pamięci GRAM więc nie potrzebuję, żeby mi w tym czasie się coś na LCD zmieniało bo to bez sensu. Można by to połączyć, jakaś funkcji odczytuje, DMA zapisuje ale nie wiem czy gra warta świeczki. Moje rozwiązanie zapisuje bitmapę w czasie porównywalnym albo nawet szybszym niż robią to profesjonalne oscyloskopy np tektronix na których miałem przyjemność pracować na laboratorium. Z tym, że one robią to w większej rozdzielczości i zapisują (ale tu już nie pamiętam) do *.JPG.

    0
  • Pomocny post
    #18 12 Lip 2011 12:04
    dondu
    Moderator Mikrokontrolery Projektowanie

    drzasiek napisał:
    Całkowicie odpada, więcej elementu i programu niż dla rozwiązania 1.

    Poza tym ADC mam nie do ruszenia, ma już swoje zastosowanie w tym urządzeniu :)

    Strata czasu, bardzo cennego czasu który mogę przeznaczyć na obliczenia. Lepiej jak ktoś zatrąbi jak już przyjedzie, niż co chwilę zaglądać do okna, czy już jest :)

    Jeżeli tak, to zrób to na osobnym malutkim mikrokontrolerku, a potem SPI na przerwaniu. Będzie komunikował się tylko gdy to będzie niezbędne. I drgania styków wyeliminuje, ...

    0
  • #19 12 Lip 2011 12:10
    drzasiek
    Specjalista - Mikrokontrolery

    No ale po co, skoro rozwiązanie z podłączeniem diodami jest tańsze, prostsze i zajmuje mniej miejsca? Miałem wogóle o to nie pytać tylko od razu zrobić to tak jak sobie wymyśliłem na diodach, ale zapytałem tylko dla świętego spokoju, bo potem bym się zastanawiał, czy te diody na pewno konieczne? A może "wewnętrznie" to można podłączyć? Teraz wiem, i będę spokojny lutując diody do płytki :)
    Rozwiązanie to jest najlepsze, jedno przerwanie więc cała obsługa nie rozsiana po wszystkich funkcjach ale wszystko w jednym miejscy. W dodatku nie sprawdzam, nie przejmuję się, że coś mi się wykonuje dłużej czy krócej. Klikam i od razu mam efekt na ekranie (ważne dla użytkownika) a program wraca do tego co robił i po zakończeniu stosuje się do zmian i wszystko jest w jak najlepszym porządku.

    0
  • #20 12 Lip 2011 12:15
    Freddie Chopin
    Specjalista - Mikrokontrolery
  • #21 12 Lip 2011 12:16
    dondu
    Moderator Mikrokontrolery Projektowanie

    drzasiek napisał:
    No ale po co, skoro rozwiązanie z podłączeniem diodami jest tańsze, prostsze i zajmuje mniej miejsca?

    Wymieniłeś tyle gardłowych argumentów, między innymi stratę czasu - zacytowałem.
    Czy mniejszy? To zależy co i w jakiej technologii zastosujesz.

    0
  • Pomocny post
    #22 12 Lip 2011 12:16
    tmf
    Moderator Mikrokontrolery Projektowanie

    Sam wiesz lepiej jak masz zbudowany program, więc nie będę się sprzeczał. Ale ciągle nie rozumiem czym się różni wywoływanie obsługi przycisków w celu sprawdzenia ich stanu, od sprawdzenia flag, które masz ustawione w przerwaniu. Czy twoje GUI jest reentrant i wielozadaniowe, tak, że jeszcze w przerwaniu masz reakcję na przyciski? To by uzasadniało maniakalne trzymanie się przerwań:) W przeciwnym przypadku - nie rozumiem.
    Co do SPI to DMA dużo daje - zauważ, że SPI nie ma buforu, w efekcie przed zapisem kolejnego bajtu poprzedni musi być wysłany. Jeśli pomiędzy kolejnymi zapisami mija więcej niż wynosi czas wysłania bajtu to ok, a jeśli nie to tracisz czas na oczekiwanie. W dodatku dosyć często jak sądzę wysyłasz pojedyncze pixele, co się przekłada na całą sekwencję komend dla LCD. Mając taką sekwencję w pamięci, wystarczy uaktualnić argumenty, ustawić DMA i już zająć się czymś innym.
    Ale tak jak pisałem, to ty wiesz jak działa ten program i zrobisz jak zechcesz.

    0
  • #23 12 Lip 2011 12:36
    drzasiek
    Specjalista - Mikrokontrolery

    tmf napisał:
    Sam wiesz lepiej jak masz zbudowany program, więc nie będę się sprzeczał. Ale ciągle nie rozumiem czym się różni wywoływanie obsługi przycisków w celu sprawdzenia ich stanu, od sprawdzenia flag, które masz ustawione w przerwaniu. Czy twoje GUI jest reentrant i wielozadaniowe, tak, że jeszcze w przerwaniu masz reakcję na przyciski? To by uzasadniało maniakalne trzymanie się przerwań:) W przeciwnym przypadku - nie rozumiem.

    Nie wiem, czy ja Cię źle rozumiem, albo czy Ty mnie źle rozumiesz.
    Ja żadnej flagi nie sprawdzam, robi to timer. Sprawdzenie flagi jest szybsze niż sprawdzenie stanu kilku pinów w porcie.(chyba? ) W petli głównej musiałbym robić to sam, i to w każdej długo wykonującej się funkcji. Dla przykładu, funkcja interpolująca wykonuje się dla obydwu kanałów we wcześniejszej wersji ok 1s. Tutaj co prawda mam zamiar skrócić filtr bo trochę przesadnie duży tam dałem. Ale nawet 500ms to jest wystarczająco na przegapienie wciśnięcia klawisza. Operacji filtracji Cyfrowej nie muszę Ci chyba wyjaśniać bo jesteś wyżej ode mnie więc algorytm z pewnością znasz. No więc liczenia jest tam sporo, wciskanie tam sprawdzania portu nie jest problemem, ale jak już wyskoczę ze splotu np to musiałbym zapisywać do osobnych zmiennych które mnożenie było, które dodawanie, to trochę kłopotliwe. Czemu miałbym sobie tak utrudniać, skoro jedno przerwanie mnie zawoła, nie muszę się o nic martwić bo potem program wróci skąd przyszedł.
    Cytat:

    Co do SPI to DMA dużo daje - zauważ, że SPI nie ma buforu, w efekcie przed zapisem kolejnego bajtu poprzedni musi być wysłany. Jeśli pomiędzy kolejnymi zapisami mija więcej niż wynosi czas wysłania bajtu to ok, a jeśli nie to tracisz czas na oczekiwanie. W dodatku dosyć często jak sądzę wysyłasz pojedyncze pixele, co się przekłada na całą sekwencję komend dla LCD. Mając taką sekwencję w pamięci, wystarczy uaktualnić argumenty, ustawić DMA i już zająć się czymś innym.
    Ale tak jak pisałem, to ty wiesz jak działa ten program i zrobisz jak zechcesz.

    Ale żeby zająć się czym innym musiałbym stworzyć Bufor dla DMA bo samo DMA sobie nie obliczy co ma wysłać i kiedy. A do tak dużego LCD nie wyrobię się z pamięcią żeby zrobić bufor. A jeśli ja mam obliczać, zapisywać do bufora to ja obliczę i wystawie na port od razu. Wolniej ale pamięci zostaje, tej tak bardzo potrzebnej w oscyloskopie.

    0
  • #24 12 Lip 2011 12:58
    tmf
    Moderator Mikrokontrolery Projektowanie

    Skoro optymalne rozwiązanie już znalazłeś to dyskusja jest czysto akademicka :)
    Ale ja chyba mimo wszystko czegoś nie rozumiem. Nawet jeśli w przerwaniu od klawiatury pozmieniasz flagi, to reakcja na ekranie pojawi się dopiero po zakończeniu obliczeń, inaczej w trakcie obliczeń i tak musisz tą flagę sprawdzić? I tu dochodzimy do sedna. Przy czym tak jak napisał Freddie Chopin, rozważamy 0,00007% co już z założenia jest bez sensu :)
    Pytanie brzmi - co jest bardziej kosztowne - samo sprawdzanie flagi + obsługa przerwań, czy wywoływanie kodu obsługi klawiatury explicite z kodu programu. Nie znając funkcji trudno na to jednoznacznie odpowiedzieć, ale myślę, że odpowiedź mogłaby nas zaskoczyć :)
    Co do DMA - nie myślę o buforowaniu całej pamięci. Ale o ile pamięć mnie nie myli, to zmiana pixela to 6 lub 8 bajtów wysłanych do sterownika. Dla najszybszego SPI jest to 96-128 taktów CPU. Jeśli w pamięci masz szablon komendy, to zmieniasz tylko jej argument (np. wsp. pixela) i programujesz DMA na wysłanie całości do LCD. Od tego czasu CPU masz wolny i może zająć się kolejną rzeczą. To oczywiście może, ale nie musi przyśpieszyć programu, wszystko zależy od jego budowy. Ale wyobrażam sobie, że np. narysowanie w ten sposób linii może być wielokrotnie szybsze przy użyciu DMA.

    0
  • #25 12 Lip 2011 12:59
    dondu
    Moderator Mikrokontrolery Projektowanie

    Przeczytałem całość i sądzę, że powinieneś wymienić dokładnie wszystkie zadania jakie ma realizować ten projekt, czyli pełne założenia techniczne. Dopiero na tej podstawie możemy zastanawiać się jak każdy z nas by to zrobił.

    Piszę o tym dlatego, że Ty dokładnie wiesz do czego dążysz, a my nie.

    0
  • #26 12 Lip 2011 13:20
    drzasiek
    Specjalista - Mikrokontrolery

    A no właśnie w przerwaniu nie pozmieniam flag ale obsługuje menu. Menu jest malutkie w porównaniu z resztą ekranu, jego aktualizowanie (a właściwie to jego reprezentacji na ekranie) jest bardzo szybkie w efekcie czego użytkownik klikając klawisz np prawo od razu widzi, że menu przeskoczyło w prawo albo zmieniając jakąś wartość. Ale np jak chcę szybko przeskoczyć o 2 pozycje? klikam szybko 2 razy a jak akurat program wykonuje jakąś ciężką robotę to obsługa w pętli głównej wymagałaby więcej czasu czyli tutaj akurat 2 obiegi pętli. A tak to zakładając, że procesor robi coś 1s (jakąś skoplikowaną operację, potem odświeża ekran i wyniki) i ja chcę przeskoczyć o 3 pozycje w menu, w ciągu sekundy 3 pozycje to wcale nie szybko, klikam 3 razy, program 3 razy wskakuje w przerwanie w ciągu tej jednej operacji i inkrementuje/dekrementuje licznik a jak już program skończy wykonywaną "ciężką robotę" to widzi, aha, licznik zmienił się o 3 i wykonuje stosowne zmiany do tego (oczywiście już na zmiennych lub w obliczeniach bo na ekranie efekt widać już dawno).
    Żebyście mnie zrozumieli, musiałbym pokazać kod a tego z oczywistych powodów zrobić nie mogę :) Tak czy siak ja wiem jak chcę to zrobić, wiem co działało dobrze w poprzednich wersjach a co trzeba poprawić. Temat założyłem jedynie po to, żeby się dowiedzieć czy można wewnętrznie podciągnąć pod jeden kanał kilka wejść czy nie można i oczekiwałem raczej odpowiedzi, Tak można albo Nie, nie można :)
    Dyskusja się trochę rozwinęła, mnie to wcale nie przeszkadza, choć ja i tak zrobię pewne rzeczy po swojemu :)
    tmfAle ja piszą o SPI miałem na myśli zapis na kartę pamięci. LCD nie jest obsługiwany przez SPI ale w trybie równoległym 16 Bitowym.

    0
  • #27 12 Lip 2011 15:09
    tmf
    Moderator Mikrokontrolery Projektowanie

    Ok, myślałem, że podobnie jak w poprzednich wersjach masz LCD z S65. Jeśli masz LCD z interfejsem równoległym, podłączonym jako XMEM to nie ma problemu. DMA tu przyśpieszy tylk ow operacjach bitblokowych.

    0
  • #28 12 Lip 2011 15:58
    Fajfer2
    Poziom 20  

    A nie da sie wykorzystać sprzętowego przerzutnika podłączonego do każdego pina? Można by wtedy rzadziej odczytywać port.

    0
  • #29 16 Lip 2011 16:03
    K_800
    Poziom 10  

    To mój pierwszy post na tym forum dlatego witam wszystkich serdecznie.
    Piszę trochę w assemblerze na 8051 i AVR-y a ostatnio zainteresowałem się rodziną Xmega.

    drzasiek napisał:
    Więc dochodzę do meritum i tu moje pytanie:
    Czy da się programowo ustawić kilka portów wejściowych na jeden kanał zdarzeń? Tak aby po wystąpieniu zadanego poziomu/zbocza na którymkolwiek ze kilku zdefiniowanych portów wystąpiło tylko jedno przerwanie?


    Większość odpowiedzi jest w DS-ach, ta również.
    W xmega podczas wyboru pinu generującego przerwanie podajemy maskę czyli kilka pinów może generować przerwanie.
    Code:

    /*! \brief Configures interrupt 0.
     *  This function configures interrupt 0 to be associated with a set of pins and
     *  sets the desired interrupt level.
     *  \param port       The port to configure.
     *  \param intLevel   The desired interrupt level for port interrupt 0.
     *  \param pinMask    A mask that selects the pins to associate with port interrupt 0.
     */
    void PORT_ConfigureInterrupt0( PORT_t * port,
                                   PORT_INT0LVL_t intLevel,
                                   uint8_t pinMask )
    {
       port->INTCTRL = ( port->INTCTRL & ~PORT_INT0LVL_gm ) | intLevel;
       port->INT0MASK = pinMask;
    }


    Ważny jest ten opis: "pinMask - A mask that selects the pins to associate with port interrupt 0". Wyrażnie mowa jest o pinach a nie jednym pinie.

    0
  • #30 17 Lip 2011 09:57
    Fajfer2
    Poziom 20  

    No o pinach, ale jednego portu. Jak rozumiem chodziło wcześniej o skierowanie obsługi przerwania z różnych portów pod jeden adres.
    Chociaż można by po prostu w przerwaniach od innych portów wywoływać tę samą funkcję obsługi.

    0