Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 29 mar 2024, o 13:36


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 11 ] 
Autor Wiadomość
PostNapisane: 28 sie 2017, o 15:07 
Offline
Użytkownik

Dołączył(a): 27 sty 2015
Posty: 61
Pomógł: 0

Witam

Mam do was takie pytanie czy taką pętlę opóźniającą:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Można zastąpić czymś bardziej "profesjonalnym"?
Potrzebuję wysłać dalej jeden z programów, które opracowałem do projektu. No i w tym programie ogólnie bawiłem się częstotliwością taktowania, sprawdzając przy tym ile prądu zużywa procesor (sterowanie wyświetlaczem 2x16 ze sterownikiem HD44780). Oczywiście żeby było jak najbardziej energooszczędnie starałem się wykorzystać jak najmniej bloków funkcjonalnych (timer2), wykorzystanie linii jedynie z szyny A i tak dalej. Ogólnie rozchodzi mi się o to czy da się opracować taką pętle, która będzie może bardziej dokładna (chodzi o czas wykonania), czy ta jest jednak ok i ja wydziwiam? :D Wiem, że przy wykorzystaniu HSI to o dokładności mogę pomarzyć, ale może da się coś ulepszyć w tym rozwiązaniu.

Pozdrawiam



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 sie 2017, o 18:56 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 15 wrz 2013
Posty: 74
Lokalizacja: Sierakowice/Gdańsk
Pomógł: 9

Zobacz mój post w którym przedstawiłem pętlę opóźniającą: http://forum.atnel.pl/topic17576.html
Opóźnienie jest realizowane też przez wykonywanie pętli, ale napisanej w języku asemblera. Czas wykonywania jednego obiegu jest dokładnie obliczony. Jeżeli twoja częstotliwość taktowania rdzenia jest inna niż 32MHz to musiałbyś zmodyfikować podaną tam wstawkę ASM.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 sie 2017, o 19:42 
Offline
Użytkownik

Dołączył(a): 27 sty 2015
Posty: 61
Pomógł: 0

Za pomocą timera2 mam zrobione opóźnienie w obsłudze przerwania od przycisku (dokładnie opóźnienie dla eliminacji drgań styków). Mam jeszcze takie pytanie, jeżeli taktowanie rdzenia wynosi 64MHz czy okres wynosi ok. 15,6 ns, powiedzmy jak do tej mojej funkcji, jako argument przekażę 100 000 to w teorii to powinno się wykonywać ok 1,6ms, dobrze myślę ?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 sie 2017, o 21:11 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 15 wrz 2013
Posty: 74
Lokalizacja: Sierakowice/Gdańsk
Pomógł: 9

bastik napisał(a):
Mam jeszcze takie pytanie, jeżeli taktowanie rdzenia wynosi 64MHz czy okres wynosi ok. 15,6 ns, powiedzmy jak do tej mojej funkcji, jako argument przekażę 100 000 to w teorii to powinno się wykonywać ok 1,6ms, dobrze myślę ?

W teorii czas wykonywania twojej funkcji zależy od tego jak zostanie ona skompilowana. (Czy wiesz co to są instrukcje kodu maszynowego procesora?) Ty założyłeś że jeden obieg pętli for() będzie się wykonywał przez 1 cykl zegara taktującego. I przy takim założeniu twoje obliczenia się zgadzają, ale w rzeczywistości pętla for() wykonuje się pewnie przez kilka cykli zegara (np. mogą to być 2 instrukcje procesora: dekrementacja zmiennej i skok warunkowy, gdzie każda z tych instrukcji wykonuje się określoną w dokumentacji ilość cykli zegara).

Nie wiemy tak bezpośrednio jak kompilator przetłumaczy sobie język C na język maszynowy (assembler). Warto dlatego użyć w naszym kodzie pisanym w języku C, wstawki napisanej w języku Asemblera. Dzięki temu wiemy dokładnie ile cykli będzie wykonywać się pętla opóźniająca. Przetestuj sobie działanie funkcji zawierającej wstawkę ASM którą podaje poniżej:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Może mrugaj czymś z częstotliwością 1s: delay_us_ASM(1000000), i daj znać jak działa. :)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 29 sie 2017, o 12:47 
Offline
Użytkownik

Dołączył(a): 27 sty 2015
Posty: 61
Pomógł: 0

Fakt o tym zapomniałem że jeden obieg pętli, nie musi trwać jednego cyklu, mam parę pytań, znalazłem w necie poradniki podstaw asm ale widać słabo szukałem i nie znalazłem wyjaśnienia tego:
Składnia: [ Pobierz ] [ Ukryj ]
język asm
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Czyli wartość zmiennej loops jest przekazywana do R0, dobrze rozumiem? A co daje tam wstawienie % ?

I ogólnie mam problem ze swoim testowym programem od diod
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

No i wyskakuje mi błąd podczas kompilacji
Kod:
main.c(33): error:  #18: expected a ")" "BNE 1b   \n\t" : : [loops] "r" (8*us) : "memory"

Sprawdzałem średniki, nawiasy i niby wygląda wszystko że jest dobrze.

Zamiast asm volatile dałem samo asm bo wcześniej miałem dodatkowy błąd:
Kod:
main.c(26): error:  #20: identifier "asm" is undefined


Wygląda na to że nawet diodami nie potrafię mrygać :P



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 31 sie 2017, o 13:20 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 15 wrz 2013
Posty: 74
Lokalizacja: Sierakowice/Gdańsk
Pomógł: 9

bastik napisał(a):
Czyli wartość zmiennej loops jest przekazywana do R0, dobrze rozumiem? A co daje tam wstawienie % ?

Nie wiem jak w assemblerze wyglądają działania na zdefiniowanych zmiennych. Wydaję mi się, że znak %nazwa_zmiennej jest czymś takim jak w języku C *adres_zmiennej. Ten kod który podałem nie jest mojego autorstwa.

Te błędy pewnie wynikają z nieprawidłowego dla twojego środowiska i kompilatora pisania wstawek. Spotkałem też gdzieś wstawki rozpoczynające następująco: __asm__ volatile.


bastik napisał(a):
Za pomocą timera2 mam zrobione opóźnienie w obsłudze przerwania od przycisku (dokładnie opóźnienie dla eliminacji drgań styków).

Ciekaw jestem w jaki sposób wykorzystujesz ten timer. Czy wewnątrz obsługi przerwania wywołanego naciśnięciem przycisku, oczekujesz na zakończenie drgań styków? Chodzi mi o to czy w casie oczekiwania blokujesz chwilowo działanie programu?

Jeżeli funkcję delay(czas) chciałbyś jednak zbudować w oparciu o timer, to dałoby radę za pomocą jednego timera obsłużyć przyciski jak i delay().



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 31 sie 2017, o 14:23 
Offline
Użytkownik

Dołączył(a): 27 sty 2015
Posty: 61
Pomógł: 0

Po wstawieniu
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
jeden błąd zniknął, pojawiło się za to ostrzeżenie
Kod:
warning: implicit declaration of function "_asm_volatile" is invalid in C99

Niestety pozostał jeszcze jeden błąd:
Kod:
 main.c(38): error:  #18: expected a ")"  "BNE 1b   \n\t" : [loops] "r" : (8*us) "memory"



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 31 sie 2017, o 15:51 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 15 wrz 2013
Posty: 74
Lokalizacja: Sierakowice/Gdańsk
Pomógł: 9

Chyba zabrakło spacji między __asm__ i volatile.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 31 sie 2017, o 17:11 
Offline
Użytkownik

Dołączył(a): 27 sty 2015
Posty: 61
Pomógł: 0

Próbowałem różnych wariantów i tylko ten bez spacji działa. :)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 wrz 2017, o 18:10 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 12 sie 2013
Posty: 230
Lokalizacja: Zabrze
Pomógł: 17

A jakiego używasz kompilatora? Łatwiej chyba będzie pomóc.

_________________
40-32:2=4!



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 wrz 2017, o 18:37 
Offline
Użytkownik

Dołączył(a): 29 lip 2014
Posty: 195
Pomógł: 44

Witam,

tak sobie czytam ten wątek i mam pewne spostrzeżenia ;-)
- zakładając, że korzystasz z gcc, musi być __asm volatile (...) - "__asm" - z dwoma "podłogami" na początku, a "volatile" po spacji - wiadomo, co znaczy, tu chodzi konkretnie o to, aby kompilator, w swej "nieograniczonej mądrości" nie próbował tego optymalizować,
- w przypadku rdzeni Cortex, nie do końca jest sensowne liczenie cykli procesora - upraszczając, ze względu na różne czasy dostępu do różnych pamięci, instrukcje niekoniecznie muszą się wykonywać "po kolei" ( kol. bastik - poczytaj o instrukcjach dmb, dsb, isb ), więc jeśli już ktoś koniecznie chce robić pętle opóźniające w *.asm, to "ma trochę pod górkę ;-),
- pobór prądu przez timer jest pomijalny do poboru prądu przez rdzeń jako taki, więc jeśli już potrzebne są precyzyjne opóźnienia, to tego 'delaya' należy zrobić na timerze, można tu wykorzystać SysTicka - to jest peryferium "rdzeniowe", więc jeśli chodzi o pobór prądu, jest praktycznie "za darmo",
- dla dłuższych opóźnień można skorzystać z RTC, co ma o tyle sens, że RTC pobiera prądu "tyle, co kot napłakał" - nawet razem z generatorem LSI,
- zastrzegam, że nie piszę niczego poważnego w *.asm na Cortex-y, nie po to zrezygnowałem z '51, żeby nadal się "w tym babrać" i koledze bastik też to polecam ;-),

Pozdrawiam serdecznie, QuadMan.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 11 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 2 gości


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO