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

Działająca funkcja, niepoprawna z mojego punktu widzenia

Modecom601 17 Mar 2012 16:07 1461 15
  • #1 17 Mar 2012 16:07
    Modecom601
    Poziom 13  

    Witam wszystkich!
    Bawię się rejestrem przesuwnym 74HC595, napisałem od początku do niego funkcję, która kompiluje się prawidłowo, natomiast ja wracając do niej po miesiącu przerwy nie rozumiem jej działania.

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Może opiszę krótko co jest dla mnie niejasne.
    Biorąc na pierwszy ogień tablicę ledson, wrzucam ją do funkcji, która od 7 do 0 sprawdza wartość, w zależności czy jest ==1 czy ==0 ustaw DS i cała zawartość tablicy pojawia się na wyjściach rejestru D0-D7. Działa dobrze, zmieniając zawartość tablicy również otrzymuję oczekiwany efekt.
    Nie rozumiem tylko dlaczego gdy wrzucam do tej funkcji tablicę tab[8], której wartościami są powyższe tablice, program działa również dobrze i wyświetla mi po jednej diodzie w odstępach np. 100ms. Przecież funkcja sprawdza tylko wartość każdego indeksu w tablicy od 0 do 7, a nie całą tablicę jak ma to miejsce w tab[8].
    Komentarze usunąłem, ze względu na możliwość wybuchnięcia śmiechem.
    Zawartości funkcji nie wstawiłem, gdyż nie ma tam nic skomplikowanego, a "najtrudniejszy" jej fragment opisałem wyżej.

    Proszę o rozjaśnienie.

    Pozdrawiam
    Modecom601

    0 15
  • Pomocny post
    #2 17 Mar 2012 16:26
    Michal_M66
    Poziom 15  

    Witam,

    Abstrahując od układu odniesienia - ponieważ nie dostarczyłeś kodu owej funkcji do której przekazujesz te tablice. To cytuję: "Nie rozumiem tylko dlaczego gdy wrzucam do tej funkcji tablicę tab[8], której wartościami są powyższe tablice, program działa również dobrze i wyświetla mi po jednej diodzie w odstępach np. 100ms. Przecież funkcja sprawdza tylko wartość każdego indeksu w tablicy od 0 do 7, a nie całą tablicę jak ma to miejsce w tab[8]. "
    Chyba czegoś nie rozumiem, albo Ty nie rozumiesz. Wydaje mi się że raczej ta druga możliwość wchodzi w tym przypadku w grę.
    Jak rozumiem tablica tab[8] miała być tablicą zawierającą wskaźniki do tablic l1-l8 tak? I chciałeś przekazując do funkcji (jakieś) tablicę ze wskaźnikami - mieć możliwość iterowania po tamtych tablicach? Sprawdź najpierw jak się deklaruje w C tablicę wskaźników.
    Poza tym, mówisz że mimo to "działa dobrze" skąd mamy wiedzieć jak funkcja działa? Czy wystawia jedynkę na pin kiedy w tablicy jest wartość 1 a zero gdy w tablicy 0, czy też jest warunek sprawdzający czy w tablicy jest cokolwiek różne od zera? W języku C/C++ w operacjach logicznych fałszem jest zero, a prawdą wszystko co różne od zera. Czyli jeśli nie zadeklarowałeś WYRAŹNIE if(l1[i]==1) {coś tam} else {coś tam} to każda wartość różna od zera będzie prawdą.
    Pozdrawiam
    M
    Pozdrawiam
    M

    0
  • Pomocny post
    #3 17 Mar 2012 16:28
    Jj_Johnys
    Poziom 21  

    W tablicy "tab" masz wartości liczbowe, a nie odwołania do tablic 11-18 :)
    Musiałbyś umieścić w niej wskaźniki do ww tablic i odpowiednio interpretować to w funkcji wykonawczej.

    0
  • #4 17 Mar 2012 16:47
    Modecom601
    Poziom 13  

    Dziękuję za błyskawiczne odpowiedzi
    Dostarczam zawartość funkcji

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Zgadzam się, ta druga opcja wchodzi w grę. Ja nie potrzebuję pisać tego na wsk. ponieważ funkcja działa. Napisałem tak jak mówisz robi to język C, wartości 0- false, !=0true.
    Nie mogę zrozumieć, dlaczego tworząc "tablicę tablic"(proszę się nie śmiać), funkcja sprawdzając pierwszy element tablicy tab[8] którym jest l1, program obsłuży cały rejestr, wszędzie wystawi 0 z wyjątkiem D0(w przypadku l1).

    Zaznaczam jeszcze raz - to działa :):)
    Jj_Johnys napisał:
    W tablicy "tab" masz wartości liczbowe, a nie odwołania do tablic 11-18 :)
    Musiałbyś umieścić w niej wskaźniki do ww tablic i odpowiednio interpretować to w funkcji wykonawczej.

    Tego to już w ogóle nie rozumiem, w tab[8] nie mam wartości liczbowych, tylko nazwy tablic l1-l8, odwołania do tablic to nie "jedynka" z przodu, tylko małe 'L'.
    wybaczcie moja niewiedzę :(

    0
  • #5 17 Mar 2012 20:26
    gaskoin
    Poziom 38  

    Wg wszelakich "coding standards" nazwa typu l jest nazwą z nie powiem czego. Zagadka dla Ciebie, który znak to l a który 1?:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Teraz dalej:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Od kiedy to int tab[8] jest deklaracją tablicy tablic? Słyszałeś kiedyś o czymś takim jak warning ? A może widziałeś nawet coś takiego: "initialization makes integer from pointer without a cast". W tablicy tab masz adresy tablic l1 do l8 a nie jakieś tam tablice. To, że ta funkcja działa to nie lada przypadek.

    I zmień te nazwy bo ja widzę tam liczby typu 18 a nie l8 (el osiem)

    --
    Dobra przemaglujmy jeszcze resztę programu:


    Kod: c
    Zaloguj się, aby zobaczyć kod


    Funkcja ta w 99.9% powinna działać tak:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Czymkolwiek są te makra. Może i działa, ale nie cieszyłbym się z tego powodu za bardzo na Twoim miejscu tylko dopisał sobie -Werrors do kompilatora.

    --
    Jeszcze co do:

    Modecom601 napisał:
    Bawię się rejestrem przesuwnym 74HC595, napisałem od początku do niego funkcję, która kompiluje się prawidłowo, natomiast ja wracając do niej po miesiącu przerwy nie rozumiem jej działania.


    To, że jest 0 errors nie oznacza, że program jest świetny :) Nie rozumiesz działania jednej funkcji bo napisałeś ją tak, że ja po tygodniu nie wiedziałbym jak działa. Nie wiem do teraz, dlaczego w ogóle działa ;]

    0
  • #6 17 Mar 2012 23:30
    Modecom601
    Poziom 13  

    gaskoin napisał:
    W tablicy tab masz adresy tablic l1 do l8 a nie jakieś tam tablice. To, że ta funkcja działa to nie lada przypadek.

    Nadal nie rozumiem, dlaczego wskazując na 1-szy el. tablicy (l1) ta wg. Was dziwna funkcja sprawdzi każdy el. tej tablicy(l1) i wystawi jej zawartość na rejestrze, skoro w funkcji sprawdza pojedyncza tablicę. Łopatologiczniej prosiłbym.
    gaskoin napisał:
    I zmień te nazwy bo ja widzę tam liczby typu 18 a nie l8 (el osiem)

    Zmieniłem. Jak wyżej napisałem była to tylko narazie zabawa.

    Makra te to nazwy od pinów rejestru, a liczba 0, 1 odpowiada stanowi logicznemu.

    Twoja wersja tej funkcji jest niepoprawna i nie ma prawa obsługiwać tego rejestru. Nie widzę nawet instrukcji DS1, która by ustawiała logiczną jedynke na wyjściu rejestru. W dodatku ST1 I SH1 wpisane w tych miejscach nie obsłużą rejestru prawidłowo.
    Więcej
    https://www.elektroda.pl/rtvforum/topic1693428.html

    gaskoin napisał:
    Nie rozumiesz działania jednej funkcji bo napisałeś ją tak, że ja po tygodniu nie wiedziałbym jak działa.


    Może mój sposób opisywania problemu jest niepoprawny, to nie widzę powodu, z jakiego miałbyś demotywować mnie do mnie dalszej zabawy i przez to nauki, gdyż zasadę działania rejestru DOSKONALE rozumiem, jego obsługa we funkcji jest w jakiś sposób rozwiązana, mam warningi zgadza się, ale jako początkujący zbytnio się tym nie przejąłem, jeśli program spełnia zadanie(tak wiem każdy warning traktować jako error).
    Ja nie pojmuję innej rzeczy którą opisałem na samym pocz. tego postu.
    Widocznie nie opłaca się pytać, dociekać zasady działania bo człowiek zostaje zrównany z ziemią, że napisał coś niezgodnego z Datasheetem albo strukturą języka C, skoro to działa, jakby nie działało to by przez gcc nie przeszło...

    0
  • #7 17 Mar 2012 23:44
    gaskoin
    Poziom 38  

    Modecom601 napisał:
    Widocznie nie opłaca się pytać, dociekać zasady działania bo człowiek zostaje zrównany z ziemią, że napisał coś niezgodnego z Datasheetem albo strukturą języka C, skoro to działa, jakby nie działało to by przez gcc nie przeszło...


    Nikt nie będzie analizował kodu bez zgodności ze strukturą C. Nikomu się nie będzie chciało domyślać co chciałeś zrobić. Dlatego koledzy, i ja z resztą też, napisaliśmy Ci co jest bez sensu, a Ty się obruszyłeś, bo kod idealnie działa, tylko wszyscy się nie wiadomo czemu i czego czepiają. Jeżeli chcesz się czegoś nauczyć (a zakładam, że chcesz, skoro napisałeś) to z łaski swojej zajrzyj na google co ten warning chociaż oznacza, poczytaj o wskaźnikach, tablicach kilku wymiarowych i może sam za chwilę stwierdzisz, że to co zrobiłeś jest bez sensu. Jak jesteś początkujący to tym bardziej powinieneś sprawdzić co to za warning a nie go olać.

    Jeżeli chcesz łopatologicznie to nie będę wrzucał wszystkiego na raz, bo widzę, że i tak nie przeczytałeś tego, co napisałem, zbyt dokładnie. Nie demotywuję Cię, tylko chcę Ci uświadomić, że brnąc dalej w takie "programowanie" robisz krzywdę tylko sobie nie nam. Więc nie upieraj się, że funkcja działa, skoro nikt, nawet Ty, nie jesteś w stanie powiedzieć dlaczego.

    Więc od początku. Zaczniemy od zagadek:

    Jaka wg Ciebie jest wartość tab[0] ? Proszę o konkretną liczbę lub ich zbiór.

    0
  • #8 17 Mar 2012 23:51
    Modecom601
    Poziom 13  

    ROzumiem, że przeczytałeś link, który umieściłem, tam zasada działania jest opisana, stamtąd zrodził się pomysł na taki a nie inny sposób obsługi rejestru.

    gaskoin napisał:
    Jaka wg Ciebie jest wartość tab[0] ? Proszę o konkretną liczbę lub ich zbiór.

    TO jest pytanie, na które chciałbym uzyskać odpowiedź, gdyż we funkcji obsługuję jedną tablicę, wskazuję jej każdy el. pojedynczo od 7 do 0, a wskazując na tab[0] wskazuję na tablicę l1(dobrze mówie?) a nie na zbiór zer i jedynek. moja odp. Nie wiem
    gaskoin napisał:
    Więc nie upieraj się, że funkcja działa, skoro nikt, nawet Ty, nie jesteś w stanie powiedzieć dlaczego.

    Bo działa, nie rozumiem, dlaczego podany el. tablicy tab[8] sprawdzi jeszcze następną całą tablicę.

    0
  • #9 17 Mar 2012 23:58
    gaskoin
    Poziom 38  

    Blisko, ale tab[0] na nic nie wskazuje. tab[0] zawiera adres tablicy l1 jako liczbę całkowitą.

    Powiedz mi teraz więc, jaki sens ma taki porównanie:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    tab zawiera adresy tablic. To porównanie sprawdza, czy adres (czegoś) w pamięci, jest równy 1, wytłumacz mi sens takiego porównania? Skąd wiesz, jaki adres co będzie miało po kompilacji ?

    Ps. Kod z tematu, który podlinkowałeś ma niewiele wspólnego z Twoim kodem.

    0
  • #10 18 Mar 2012 00:06
    Modecom601
    Poziom 13  

    Jak ma niewiele wspólnego, skoro tam jest zasada działania rejestru? po to sprawdzam 8 razy stan każdego elementu w tablicy by potem pin DS odpowiednio ustawić, potem '1' na SH_CP by przesunąć informację o jeden bit, by zrobić miejsce na następną informacje, i wprowadzac to tak długo, aż nie ustawię '1' na ST_CP, wtedy cała zawartość tablicy wprowadzona do tej funkcji jest sprawdzona, a rejestr steruje 8 diodami.
    sens sprawdzenia tego warunku jest w przypadku podania funkcji pojedynczej tablicy, nie zbioru tablic, mimo to gdy podam do funkcji tab[8] z przerwami 100ms program "przesuwa" jedną diodę. Chyba nie potrzebujesz filmiku na dowód, że to działa, pytam dlaczego to działa.

    0
  • #11 18 Mar 2012 00:27
    gaskoin
    Poziom 38  

    Chyba nie rozumiesz, tego co piszę.

    Ja piszę o przypadku zbioru tablic, a nie o tablicy z wartościami - tu jest ok i nie o tym przecież mówimy.
    W przypadku zbioru - po raz 700 Ci napiszę, że rozwiązałeś to źle, więc nikt Ci nie powie dlaczego to działa, bo działa przypadkiem. Najlepiej jakbyś wrzucił cały kod to ktoś Cię naprowadzi, bo póki co, nie przyjmujesz do wiadomości żadnej krytyki tylko żądasz wyjaśnień pod karą śmierci. Pamiętaj, że czasem działa ale nie znaczy to, że jest dobrze. Nie robię nikomu na złość, nie mam konta na forum żeby "żądnym wiedzy" wkładać kłody pod nogi, ale łatwiej by mi było, gdybyś użył C, a nie wymyślał nowe języki programowania.

    W przeciwnym wypadku już dawno by mnie tu nie było. Chociaż mikrokontrolery mają akurat małą inwigilację :) Gdzie indziej moderatorzy sprawdzają każdy przecinek.

    0
  • #12 18 Mar 2012 01:04
    Modecom601
    Poziom 13  

    gaskoin napisał:
    Ja piszę o przypadku zbioru tablic,

    Ja też.
    Pytam dlaczego to działa po czym za chwilę otrzymuję odpowiedź
    gaskoin napisał:
    działa przypadkiem

    Mogłeś od razu napisać, że nie umiesz laikowi tego wytłumaczyć, albo sam nie wiesz skąd taki przypadek zaszedł i dlaczego działa ok. Przyjmuję każdą krytykę, ale nie lubię gdy ktoś robi ze mnie jeszcze większego durnia za jakiego mnie ma(chyba nikt nie lubi prawda). Dwa posty wyjaśniałem Tobie, że obsługa rejestru jest dobrze rozwiązana, innej sprytnej opcji ustawienia SIPO nie byłoby dla mnie, zresztą każdy, kto chce obsłużyć H595 musi sterować tymi 3 pinami by cokolwiek ustawić na wyjściach tego rejestru, więc założe się o aktywność tego konta, że nawet doświadczony user, napisałby podobnie obsługę rejestru, nie mówię o zbiorze tablic teraz. Po co mam bawić się wskaźnikami, skoro działa to prościej, jak mówisz działa z przypadku, ok jestem fe bo napisałem niezgodnego coś z C, natomiast nie będę się obwiniać, za złe, działające tak jak zamierzałęm rozwiązanie, widocznie mój poziom wiedzy o języku programowania uC na dzień dzisiejszy pozwolił na zapis tylko tego. Chciałem się dowiedzieć why, odpowiedzi konkretnej nie dostałem, przepraszam - przypadek, albo szczęście miałem...

    0
  • #13 18 Mar 2012 10:49
    gaskoin
    Poziom 38  

    OMG człowieku czy Ty naprawdę nie rozumiesz co ja piszę? Mam pisać w języku suahili ? Proszę tylko o kod, a Ty jak król się zarzekasz, że jest dobra obsługa i go nie dasz, mamy odpowiadać czemu działa. Jest świetna, ale nie dla zbioru tablic, dopóki nie dasz całego kodu to nikt Ci na żadne pytanie w tym wątku już raczej nie odpowie:)

    pozdrawiam

    0
  • #14 18 Mar 2012 11:24
    Modecom601
    Poziom 13  

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Atmega8 1 Mhz
    Jeżeli jest źle rozwiązane zaproponuj coś prostszego.

    0
  • Pomocny post
    #15 18 Mar 2012 12:09
    gaskoin
    Poziom 38  

    Nie można było tak od razu? Teraz przynajmniej mogę Ci powiedzieć dlaczego działa.

    Deklarując te 8 tablic i wkładając je do tablicy liczb całkowitych, dokonujesz niejawnego rzutowania z wskaźnika na tablicę (którym jest nazwa tablicy) na liczbę całkowitą. Potem jak wkładasz kolejne elementy tablicy tab do funkcji rejestr to dokonujesz znowu konwersji w drugą stronę bo Twoja funkcja jako argument przyjmuje wskaźnik na tablicę.

    Żeby było cacy to parametrem funkcji rejestr powinien być:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    A tablica tab (ta globalna), Powinna być typu:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    I działa to tak, że w mainie w pętli pakujesz kolejne elementy tablicy tab do funkcji rejestr (która jako parametr ma tablice). W funkcji rejestr masz znowu pętle która sprawdza kolejne elementy tablic d1...d8 ot cała filozofia. Wrzucając tam ledsona, nie powinieneś robić tego w pętli for, tylko poprostu jako:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #16 18 Mar 2012 12:17
    Modecom601
    Poziom 13  

    DOstałem odpowiedź :) Dziękuję!
    Dołoże wskaźniki, sprawdzę czy działa należycie, sprawdzę również, czy .hex nie zmniejszył rozmiaru. Czy wg. Ciebie jest jeszcze jakiś inny prosty sposób na zapis tego?

    Dzięki jeszcze raz!

    0