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



Teraz jest 22 maja 2026, o 10:50


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 18 ] 
Autor Wiadomość
PostNapisane: 26 kwi 2016, o 14:57 
Offline
Nowy

Dołączył(a): 03 lip 2014
Posty: 7
Pomógł: 0

Witam,

Odnośnie tematu - Zapewne nie błąd kompilatora a moja niewiedza.

Atmel Studio 6.2 + mikrokontroler ATmega88PA (z ATmega8A to samo), takotwanie 1MHz.
Uruchomiłem timer, który co 1 msek zwiększa wrtość zmiennej millis - taki licznik:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Działa OK. Domniemam więc, że taki kod:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

powinien wprowadzić opóźnienie 0,5 sek, jednak tak się nie dzieje - powstaje pętla bez końca (co ma odzwierciedlenie w wygenerowanym kodzie assemblera). W trybie śledzenia widzę że zmeinna millis już dawno przekroczyła wartość 500 a pętla wciąż trwa. Gdzie popełniłem błąd?
Co ciekawe, jeśli w pętli wstawię jakąkolwiek funkcję:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

wtedy pętla zgodnie z oczekiwaniami kończy się po ustalonym czasie. Ale takie coś już nie działa:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Testowane w symulatorze i na żywym mikrokontrolerze - to samo. Czy ktoś mi może wytłumaczyć o co tu chodzi?

Pozdrawiam
Tygrysek



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 kwi 2016, o 16:27 
Offline
Użytkownik

Dołączył(a): 04 paź 2011
Posty: 8631
Pomógł: 338

Tygrysek napisał(a):
Czy ktoś mi może wytłumaczyć o co tu chodzi?


popatrz uważnie co chcesz od while z tym parametrem i zobacz co się jej dzieje :)
powstaje pętla bez końca gdyż ..... :) BB Pętla While ...



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 kwi 2016, o 16:35 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 lis 2015
Posty: 1448
Lokalizacja: okolice Warszawa
Pomógł: 149

Witam.
Tygrysek napisał(a):
Co ciekawe, jeśli w pętli wstawię jakąkolwiek funkcję:
Składnia: [ Pobierz ] [ Ukryj ]
język c
while (millis < 500) {moja_funkcja();}
GeSHi

wtedy pętla zgodnie z oczekiwaniami kończy się po ustalonym czasie.

I tak powinno być. :)

Tygrysek napisał(a):
Domniemam więc, że taki kod:
Składnia: [ Pobierz ] [ Ukryj ]
język c
millis = 0;
while (millis < 500);
GeSHi

powinien wprowadzić opóźnienie 0,5 sek, jednak tak się nie dzieje


Poprawione następnego dnia*
TERAZ MOJE DURNE PYTANIE wynikające z mojej niewiedzy. :oops:
zaoszczędzisz mi wstydu, jeżeli nie przeczytasz.

A takie pytanie do Ciebie.
Co według Ciebie powinno się wykonać w tej pętli? może brakuje oczekiwania w nicości?.. {} ..?


Chyba że coś źle zrozumiałem.



Ostatnio edytowano 27 kwi 2016, o 16:14 przez Daro69, łącznie edytowano 1 raz

Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 kwi 2016, o 19:42 
Offline
Nowy

Dołączył(a): 03 lip 2014
Posty: 7
Pomógł: 0

Spodziewam się że while (millis < 500); odczeka do czasu aż zmienna millis osiągnie wartość 500. Czyli taki mój własny wariant _delay_ms(500);.

OK, zapytam inaczej. Mam zmienną millis, która zwiększa wartość o 1 co msek. Jak powinno wyglądać opóźnienie np. 0,5 sek?

Pozdrawiam.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 kwi 2016, o 19:46 
Offline
Użytkownik

Dołączył(a): 04 paź 2011
Posty: 8631
Pomógł: 338

no czegoś takiego mozesz się spodziewać w IFie ...
dlatego odesłałem do referencji pętli While .



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 kwi 2016, o 19:50 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 lis 2015
Posty: 1448
Lokalizacja: okolice Warszawa
Pomógł: 149

OK

przyjrzyj się:

Poprawione następnego dnia.
A tu następne moje wczorajsze wypociny nie mające nic do rzeczywistości, którą parę postów dalej świetnie opisał kolega "QuadMan".
Proszę nie czytać. :oops:
while (millis < 500); /* nie robi nic - brak czasu wykonywania czegokolwiek .*/

while (millis < 500){} /* robi nic przez czas do osiągnięcia 500*/
{}
:)



Ostatnio edytowano 27 kwi 2016, o 16:34 przez Daro69, łącznie edytowano 1 raz

Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 kwi 2016, o 20:02 
Offline
Nowy

Dołączył(a): 03 lip 2014
Posty: 7
Pomógł: 0

"The while statement executes a statement or a block of statements until a specified expression evaluates to false."
Czyli mam rozumieć że while MUSI mieć jakąś instrukcję lub blok instrukcji i nie da się wstawić tam "pustej instrukcji"?
dlaczego w takim nie działa również to:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


PS.
Proszę o wyrozumiałość, sporo programowałem ale w innych językach (m.in. Pascal), w C dopiero się wdrażam.

------------------------ [ Dodano po: 1 minucie ]

Daro69 napisał(a):
while (millis < 500){} /* robi nic przez czas do osiągnięcia 500*/[/syntax]


To też nie działa! Efekt ten sam - pętla bez końca.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 kwi 2016, o 20:22 
Offline
Użytkownik

Dołączył(a): 04 paź 2011
Posty: 8631
Pomógł: 338

Tygrysek napisał(a):
Czyli mam rozumieć że while MUSI mieć jakąś instrukcję lub blok instrukcji

dokładnie tak



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 kwi 2016, o 20:27 
Offline
Nowy

Dołączył(a): 03 lip 2014
Posty: 7
Pomógł: 0

OK.
Sprawdziłem w międzyczasie: for(;millis<500;); - efekt ten sam.

Jak w takim razie powinna wyglądać najprostsza forma czekania na osiągnięcie ustalonej wartości millis?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 kwi 2016, o 20:50 
Offline
Użytkownik

Dołączył(a): 04 paź 2011
Posty: 8631
Pomógł: 338

a kolega wie jak działają pętle
While , For

a moze użyć iF ...



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 kwi 2016, o 20:58 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 lis 2015
Posty: 1448
Lokalizacja: okolice Warszawa
Pomógł: 149

Jeżeli chcesz żeby nic się nie wykonywało, to nie opisuj tego.
Zrób odwrotnie. jeżeli twoja zmienna jest większa od np. 500 to zrób coś.Wtedy poniżej 500 to coś się nie wykona.
Sun podpowiada funkcję if{}. Możesz dodać else{} -czyli to co ma się wykonać poniżej 500.
:)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 kwi 2016, o 20:59 
Offline
Nowy

Dołączył(a): 03 lip 2014
Posty: 7
Pomógł: 0

"If" tutaj kompletnie nie pasuje... Musi być pętla. No chyba że if z jakimś skokiem do etykiety, ale to nieeleganckie.

"while" właśnie próbuję ogarnąć, bo wydawało mi się że wiem jak działa (w Pascalu opisywana przeze mnie konstrukcja jest jak najbardziej poprawna!).
Bardzo proszę o konkretny przykład! Ten problem nie daje mi żyć :-)

PS.
Skoro konstrukcja "while (x<10);" jest niezgodna z zasadami języka C (bo tak zrozumiałem), dlaczego kompilator nie zgłasza błędu? I dlaczego nie działa while (x<10) {asm("nop");}? Wiem, czepiam się.

------------------------ [ Dodano po: 2 minutach ]

Chyba się nie rozumiemy...

Chcę zapalić diodę LED na 1 sek, potem program leci dalej:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


lub inaczej:
jak napisać własną funkcję _delay_ms(unsigned long int t) (bo wbudowana funkcja _millis_ms() nie pozwala na użycie zmiennej)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 kwi 2016, o 21:09 
Offline
Użytkownik

Dołączył(a): 04 paź 2011
Posty: 8631
Pomógł: 338

a nie możesz tak :

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


wiesz pierwsze słyszę by do własnego delaya nie pasował IF
zwykle korzystając z timera na Ifie robię swoje delaye i niema z nimi żadnego kłopotu ...
nie mówiąc o skakaniu do etykiet ...
czasem jak potrzebuję określonego czasu to wyliczam pętlę FOR

------------------------ [ Dodano po: 1 minucie ]

Tygrysek napisał(a):
w Pascalu opisywana przeze mnie konstrukcja jest jak najbardziej poprawna!


przykro mi ale to nie pascal ...
chcesz pisac w pascalu jest microPascal dla AVR :)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 kwi 2016, o 21:22 
Offline
Nowy

Dołączył(a): 03 lip 2014
Posty: 7
Pomógł: 0

SunRiver napisał(a):
a nie możesz tak :

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Jestem zawiedziony.
Rozwiązanie trochę drażniące, bo muszę bez sensu "bombardować" port dla LED w kółko danymi...
A jak będę chciał napisać własną funkcję delay() to na if-ie tego nie zrobię i będę musiał wrzucić jakieś coś - byle co w pętlę while, żeby kompilator był zadowolony. Tak to widzę :-)

Dzięki za trochę wiedzy.
Pozdrawiam



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 kwi 2016, o 22:33 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 14 lut 2014
Posty: 293
Lokalizacja: Jaskółowo k. Warszawy
Pomógł: 9

Tygrysek napisał(a):
SunRiver napisał(a):
a nie możesz tak :

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Jestem zawiedziony.
Rozwiązanie trochę drażniące, bo muszę bez sensu "bombardować" port dla LED w kółko danymi...
A jak będę chciał napisać własną funkcję delay() to na if-ie tego nie zrobię i będę musiał wrzucić jakieś coś - byle co w pętlę while, żeby kompilator był zadowolony. Tak to widzę :-)

Dzięki za trochę wiedzy.
Pozdrawiam


A może takie coś Ci pomoże bardziej zrozumieć:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Musisz pamiętać że millis musi mieć odpowiedni typ

_________________
POZDROWIONKA



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 kwi 2016, o 23:58 
Offline
Użytkownik

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

Witam.

Kolego Tygrysek, Twój tok rozumowania jest jak najbardziej poprawny. Taka konstrukcja jest jak najbardziej ok:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
- średnik jest tu pustą instrukcją, wcale nie musi tam być żadnego bloku instrukcji w {} z tym że musisz pamiętać o kilku sprawach: po pierwsze , zakładam, że Twoja zmienna milis została zadeklarowana jako volatile, a po drugie, że kompilator w swej radosnej twórczości nie zoptymalizował Twojego while do jednej instrukcji asemblera - bo wtedy przerwanie nie ma się jak wykonać - nie da się przerwać jednej instrukcji asm ( choć Bogiem, a prawdą, nie bardzo wiem jak miałby to uczynić, jeśli zmienna milis jest 16-to bitowa ). Takie cóś:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
to w sumie prawie to o co chodzi, ale kompilator jest "mądry" i na bank wywali tego nop-a, więc proponuję bezpiecznie :
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
. Z for-em też jest identyczna sytuacja, to tyle tak na szybko.

Dopisane: mikrosekundowy delay na timerze, co prawda uc inny, ale zasada ta sama - wycięty z kodu, nad którym teraz pracuję, na bank działa:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Warunek <= w tym while, bo chcę by opóźnienie było dokładnie delay.
Pozdrawiam, QuadMan.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 27 kwi 2016, o 06:48 
Offline
Nowy

Dołączył(a): 03 lip 2014
Posty: 7
Pomógł: 0

PITERK napisał(a):
A może takie coś Ci pomoże bardziej zrozumieć:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Układ ma błysnąć diodą na dzień dobry a potem przejść do wykonywania programu. No to wrzuć teraz w swój kod główną pętlę while(1), chodzi o coś takiego:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Ja wiem że to można napisać na milion innych sposobów, ale taka struktura wydaje się najprostsza i najbardziej logiczna.

------------------------ [ Dodano po: 14 minutach ]

QuadMan napisał(a):
[...]po pierwsze , zakładam, że Twoja zmienna milis została zadeklarowana jako volatile[...]

I tego mi brakowało :idea: . Po poprawieniu deklaracji:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

while() działa jak oczekiwałem.
Dzięki za wyczerpujący opis i cenną lekcję!



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 27 kwi 2016, o 08:59 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 lis 2015
Posty: 1448
Lokalizacja: okolice Warszawa
Pomógł: 149

Kolego QuadMan.
Dziękuję za naprostowanie mojego toku rozumowania.
Wieczorem co nieco dopiszę do moich postów, by następnych nie wprowadzać w maliny.



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: 18 ] 

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