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

KURS HOME ASSISTANT

Chcesz zautomatyzować swój dom bez skomplikowanego kodowania?
Zastanawiasz się nad wyborem sprzętu, oprogramowania i aplikacji?
Od czego zacząć przygodę z HA w 2025? Co będzie najlepsze na start?

Nasz kurs Home Assistant nauczy Cię krok po kroku, jak łatwo zautomatyzować swój dom i oszczędzić na rachunkach za prąd i ogrzewanie. Bez chmur, bez zbędnych abonamentów. Twoja przygoda z Home Assistant zaczyna się tutaj!

↓↓↓

    Szanujemy Twoją prywatność. Możesz wypisać się w dowolnym momencie.




    Teraz jest 17 maja 2025, o 03:01


    Strefa czasowa: UTC + 1





    Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 6 ] 
    Autor Wiadomość
    PostNapisane: 21 lut 2015, o 00:27 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 23 paź 2014
    Posty: 1034
    Lokalizacja: Trójmiasto
    Pomógł: 190

    Witam

    Jestem w trakcie nauki (czytania BB). W ramach ćwiczeń napisałem program ale jego działanie odbiega od oczekiwań. I tu pytanie:
    Jak to jest ze zmiennymi globalnymi w funkcjach? Jeśli dostęp do tych zmiennych będzie w różnych funkcjach:
    (funkcje operują same na zmiennych globalnych, zmienne nie są im przekazywane)
    1 - bezpośrednio w main
    2 - funkcji wywołanej z głównej pętli programu
    3 - funkcji wywołanej z funkcji j.w.
    4 - i kolejnej funkcji wywołanej z funkcji z p.3
    Wiem że trochę zamieszałem i niechybnie zmierzam do niekontrolowanego rozrostu stosu, ale to w celach dydaktycznych...
    Czy aby właściwie była widziana wartość tych zmiennych to trzeba im nadać volatile tak jak przy przerwaniach?
    Bo z tego co ustaliłem czasem np zmienna zmodyfikowane w funkcji jak w p.2 jest widoczna w funkcji jak w p.3; z kolei innym razem już nie :cry:

    Natomiast drugie pytanie odnośnie volatile: czy na zmiennych opatrzonych tą właściwością można operować w funkcjach typu eeprom_write_block() bo w takim wypadku otrzymuję warningi:
    ../main.c:190:7: warning: passing argument 1 of '__eewr_block_m32a' discards 'volatile' qualifier from pointer target type [enabled by default]

    Pozdrawiam



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 21 lut 2015, o 00:59 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 22 cze 2013
    Posty: 988
    Lokalizacja: Byram, MS 39272
    Pomógł: 55

    W BB jest to bardzo ładnie i zrozumiale napisane ale jakby Ci było mało to spróbuj jeszcze zaglądnać tu
    http://www.algorytm.edu.pl/wstp-do-c/ty ... nnych.html
    http://pl.wikibooks.org/wiki/C/Zmienne

    _________________
    Pomysły na podpis - wyślij SMSa +1 769 243 0011



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 21 lut 2015, o 11:44 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 23 paź 2014
    Posty: 1034
    Lokalizacja: Trójmiasto
    Pomógł: 190

    W BB jest wszystko opisane to fakt i do wczoraj myślałem że to rozumiem...
    Napisałem programik coś na kształt zamka szyfrowego z możliwością zmiany kodu oraz resetu:

    Tak wiem zamiast obrzydliwych delayów powinienem użyć timera - ubiegnę i wyjaśniam: zamierzam takie posunięcie ale po ukończeniu powyższego programu - tak dla porównania gabarytów kodu 8-)
    Procesor Atmega32 na zestawie ATB taktowany z wewnętrznego oscylatora RC 1 MHz - (docelowo będzie to na attiny zasilane bateryjnie stąd masakryczne 1MHz)

    No więc jak to ma działać:
    sprzęt bardzo ubogi 1 dioda świecąca, jeden microswitch, serwo (w programie zamiast serwa na razie jest druga dioda led), na chwilę obecną podpięta biblioteka do obsługi multipleksowania LED (wzorowana na tej z BB) do celowo zniknie z projektu.
    Po uruchomieniu led 1 zamiga po czym program będzie tkwił w pętli do czasu naciśnięcia przycisku (docelowo tu będzie usypianie procka a przycisk w przerwaniu)
    Po naciśnięciu przycisku led 2 razy mrugnie po czym zaczyna powoli mrugać - każde mrugnięcie to inkrementacja wartości o 1 (zaczynając od zera - pierwsze mrugnięcie, 1 - drugie itd) po właściwej liczbie mrugnięć naciskamy ms , led 2 razy mrugnie i zaczyna od nowa - i tak dla 4 cyfr. Kod wskakuje do tablicy kodw[]. Kod porównywany jest z kodem w eeprom i jeśli identyczny wykonywana jest akcja czyli rusza serwo. No chyba że chcemy zmienić kod to po ostatniej cyfrze przytrzymujemy przycisk ok 5 sekund - wtedy rozpoczyna się procedura zmiany kodu czyli wprowadzamy cztery cyfry nowego po czym ponownie cztery cyfry dla sprawdzenia poprawności. Po operacji zmiany kodu akcja nie jest wykonywana.
    Ostatnia opcja to reset kodu. trzymając przycisk robimy reset procesora (albo off -> on urządzenia) trzymamy 10 sekund aż led 1 zamiga 2 razy, następnie trzeba jednorazowo wprowadzić kod fabryczny czyli cztery jedynki i przepisanie z pamięci programu do ramu, a następnie z ramu do eepromu.

    I teraz problemy: procedura pierwsza do wywołania akcji działa, druga do zmiany kodu też działa ale np z poziomu funkcji main wartość wprowadzona nie jest widziana - jak podpiąłem funkcje sprawdzającą aktualne wpisy w tablicy kodw[] to nadal są zera pomimo użycia funkcji pobierz_kod a przecież ta tablica nie jest później zerowana... chyba że o czymś nie wiem.
    Procedura resetu nie działa - po wywołaniu przez funkcję resetu funkcji pobierz_kod to po jej działaniu tablica kodw[] nadal zawiera same zera.

    Stąd moje pytanie o widoczność zmiennych. W BB jest napisane że po uruchomieniu funkcji main zmienne globalne umieszczane są w rejestrach, i teraz jeśli zostanie wywołana kolejna funkcja to operuje ona na tych samych rejestrach, czy bezpośrednio na ramie czy może znowu z ramu zmienne pakowane są do innych rejestrów...?
    squeez napisał(a):
    Zmienne globalne jak sama nazwa wskazuje są globalnie widoczne, wszędzie w całym programie.

    no właśnie z działania powyższego programu nie do końca tak jest.

    Z kolei użycie volatile dla tablic kodw[] i kodt[] wywala warningi przy operacjach kopiowania pamięci eeprom i progmem.

    Zastanawiam się czy tablic nie powinno się przekazywać do funkcji jako argument... Tylko czemu to nie działa w takiej formie skoro to zmienne globalne!?



    Ostatnio edytowano 17 mar 2015, o 21:31 przez xentis, łącznie edytowano 1 raz

    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 21 lut 2015, o 11:56 
    Offline
    Moderator
    Avatar użytkownika

    Dołączył(a): 03 paź 2011
    Posty: 27396
    Lokalizacja: Szczecin
    Pomógł: 1043

    xentis napisał(a):
    W BB jest napisane że po uruchomieniu funkcji main zmienne globalne umieszczane są w rejestrach, i teraz jeśli zostanie wywołana kolejna funkcja to operuje ona na tych samych rejestrach

    No to jeszcze doczytaj w książce jak działają funkcje, bo tu masz problem .... jak może kolejna funkcja działać na jakichś tam rejestrach no pomyśl chwilę ? .... Mówię ci poczytaj rozdział o tym co się dzieje podczas gdy funkcja rozpoczyna swoje życie i gdy je kończy i nie dopowiadaj sobie sam historii o rejestrach które po niej zostają bo przez to sam sobie w głowie mętlik wprowadzasz. Funkcja kończy życie a zmienna globalna pozostaje zmienną globalną w pamięci RAM i tego się trzymaj ... więc gdy przyjdzie kolejnej funkcji działać to także dobierze się do tej zmiennej globalnej w RAM ... a fakt że jej wartości muszą przejść przez jakieś tam rejestry jest mało istotny bo przy wyjściu z funkcji zmieniona wartość wróci znowu do zmiennej w RAM. Nie ma więc w tym jak widzisz nic tajemniczego ani dziwnego.....

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

    Cytuj:
    no właśnie z działania powyższego programu nie do końca tak jest.

    Wiesz ... jeśli ty uważasz że jak napiszesz program i on źle działa to oznacza że nieprawdą jest to co piszą po podstawach języka C no to hmmm dziwne podejście. Ja na twoim miejscu zadałbym sobie pytanie - "co ja robię źle w kodzie ... że mi źle działa? że zmienne nie są widoczne tak jak należy ? tak jak mowa o tym w podstawach C?" ... rozumiesz ? .... to ułatwi ci naukę języka C

    ------------------------ [ Dodano po: 3 minutach ]

    xentis napisał(a):
    Z kolei użycie volatile dla tablic kodw[] i kodt[] wywala warningi


    a co to ma oznaczać "z kolej" ??? z kolej ? czyli w związku z czym ?

    po co w ogóle im dajesz volatile ?

    _________________
    zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 21 lut 2015, o 12:08 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 23 paź 2014
    Posty: 1034
    Lokalizacja: Trójmiasto
    Pomógł: 190

    Panie Mirku ja nie twierdzę że w podstawach języka C kłamią. Zawsze powtarzam że mądrzejsi nad tym myśleli i skoro wymyślili to tak jest. Niestety mi jest czasem to ciężko ogarnąć.

    mirekk36 napisał(a):
    jak może kolejna funkcja działać na jakichś tam rejestrach no pomyśl chwilę ? .... Mówię ci poczytaj rozdział o tym co się dzieje podczas gdy funkcja rozpoczyna swoje życie i gdy je kończy i nie dopowiadaj sobie sam historii o rejestrach które po niej zostają bo przez to sam sobie w głowie mętlik wprowadzasz.

    No właśnie chodzi o to że nie zostają bo funkcja jest uruchamiana z funkcji - i właśnie chodzi o ten szczegół jak wygląda wtedy pobieranie zmiennych gdy funkcja uruchamia drugą funkcję, a skoro ta pierwsza ma wartości zmiennych globalnych w rejestrach i je już zmieniła to druga funkcja uruchomiona z tej pierwszej zobaczy zmiany poczynione z poziomu pierwszej funkcji (która przecież jeszcze żyje i nie zaktualizowała w ramie zmiennych - no chyba że jest inaczej) czy pobierze zmienne z RAMU niezmienione przez funkcję pierwszą?

    mirekk36 napisał(a):
    po co w ogóle im dajesz volatile ?

    Skoro funkcja nie widzi zmian w zmiennych globalnych poczynionych przez inną funkcję to pomyślałem że może jest tak jak przerwaniach - zmiany niejawne....

    Co do funkcji to rozdział ten czytałem kilku krotnie i nie wiem czy dobrze to rozumiem.
    Po starcie funkcji main zmienne globalne trafiają do rejestrów. Jeśli z poziomu funkcji main uruchomiona zostaje kolejna funkcja to jakie wartości widzi te z pamięci RAM czy te umieszczone w rejestrach dla main?
    Bo fakt że po zakończeniu funkcji zmienne w RAM są aktualizowane wartościami z rejestrów to rozumiem.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 22 lut 2015, o 16:15 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 23 paź 2014
    Posty: 1034
    Lokalizacja: Trójmiasto
    Pomógł: 190

    mokrowski napisał(a):
    xentis troszkę ,,zakałapućkałeś" się z tymi spekulacjami o rejestrach, zmiennych globalnych i innych takich ,,niskopoziomowych bebechach" :-)

    Ano wiem że trochę się zakręciłem jak słoik... Ale po ponownym przestudiowaniu kart BB i przeczytaniu Twojego łopatologicznego opisu to mi się rozjaśniło :)
    Dzięki za pomoc ;)



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

    Strefa czasowa: UTC + 1


    Kto przegląda forum

    Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 11 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:  
    cron
    Sitemap
    Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
    phpBB SEO