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



Teraz jest 18 lis 2024, o 04:47


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 10 ] 
Autor Wiadomość
PostNapisane: 30 wrz 2013, o 21:53 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 cze 2013
Posty: 137
Lokalizacja: Kraków
Pomógł: 0

Cześć!
Chciałbym po raz pierwszy na tym forum pochwalić się swoim tworem ;). Na wstępie zaznaczę, że ani toto nowatorskie, ani wybitne, ale kiedyś trzeba zacząć, a tak się złożyło że akurat skończyłem tworzyć coś nowego. Pragnę więc przedstawić Wam generator 20 kanałów PWM.
Obrazek

Projekt zrealizowany jest w oparciu o ATmegę88PA z kwarcem 20MHz. Postawiłem na prostą komunikację - 2 bajty po UART i mamy zmodyfikowany dowolny z 20 kanałów. Choć tak naprawdę w normalnej pracy można użyć tylko 19 - dwudziesty jest na pinie resetu, który trzeba wyłączyć by móc go używać jako kanału PWM. Raczej nigdy z niego nie skorzystam, nie mam narzędzi do późniejszego odblokowania procka.
W każdym razie, warto napisać coś o osiągach tego tworu. Przed kompilacją programu w pliku nagłówkowym należy określić które kanały mają być włączone - każdy taki jeden kanał to 8 cykli zegara więcej przy każdym przerwaniu timera. Dla wszystkich 20 kanałów cała funkcja generująca sygnały trwa 180 cykli, co przy 8-bitowej rozdzielczości sprawia że docelowa częstotliwość kanałów PWM nie może przekroczyć 434Hz. Oczywiście im więcej kanałów wyłączymy, tym większą częstotliwość możemy ustawić - przykładowo, dla 5 kanałów możemy ustawić częstotliwość do 1300Hz.
Wszystkie te opcje - wybór kanałów, częstotliwość, szybkość USART - można zmienić w pliku nagłówkowym.
Obrazek

Jeśli chodzi o sam kod generujący kanały, rozwiązanie jest bajecznie proste. Jest sobie tablica przechowująca wartości "programowych OCR" dla wszystkich 20 kanałów, jest również zmienna "programowego TCNT". Ich działanie jest analogiczne ze sprzętowymi odpowiednikami - wartość TCNT jest zwiększana przy każdym wywołaniu funkcji, a potem sprawdzany jest warunek czy TCNT przekroczyło wartość OCR - jeśli tak, dany kanał jest zerowany. Przy powrocie TCNT do 0, następuje powtórne ustawienie wszystkich kanałów i jazda zaczyna się od nowa.

Uwagi montażowe:
Po wytrawieniu i zlutowaniu płytki, należy jeszcze przystosować ją do docelowej pracy. Jeśli mamy zamiar wykorzystać pin resetu jako 20. kanał PWM, należy rozewrzeć zworkę resetEN. W moim przypadku mam tam na stałe wlutowany rezystor zworkopodobny ("0R"). Drugą sprawą jest wybór zasilania - zakładając zworkę regON włączamy do obwodu zasilającego stabilizator, na który możemy podać napięcie >5V. W przeciwnym wypadku układ należy zasilić stabilizowanymi 5V.
Układ można zaprogramować bezpośrednio na płytce, podłączając linie programatora do odpowiednio oznaczonych wyprowadzeń. Podczas programowania stabilizator musi być odłączony.
Obrazek

Wnioski na dziś:
Spodziewałem się po tym dziwolągu nieco więcej niż mi dał :lol:. Miałem nadzieję na jakiś sensowny multipleksing, ale według moich obserwacji wymagałby on innej komunikacji - najpierw wysyłanie modyfikacji PWMów, a dopiero potem "zatrzaskiwanie" wszystkich nowych wartości. Może komuś będzie się to chciało dopisać, ale ja nie mam już ochoty na zmianę sposobu komunikacji.

Na koniec chciałbym jeszcze podkreślić, że zdaję sobie sprawę z istnienia dedykowanych scalaków do generowania PWM, które zapewne robią to lepiej niż ta oto zabaweczka. Nie zawsze chodzi jednak o możliwość wielu zastosowań - czasem warto coś zrobić dla samego faktu robienia :D. No a poza tym nie mogłem znaleźć tych scalaków w SMD. Dodatkowo sporym plusem jest fakt, że zabawka używa do komunikacji USART, co umożliwia sterowanie przy pomocy komputera. Poniżej zdjęcie i filmik z efektu sterowania PWMów komputerem przy pomocy Pythona. Genialny efekt to to może nie jest, ale dobrze ukazuje jak łatwo się tym steruje.
Obrazek



Tymczasem pozdrawiam i zapraszam do dyskusji :)
mopsiok


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



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



Skrypt w Pythonie generujący powyższy efekt:
Składnia: [ Pobierz ] [ Ukryj ]
język python
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Załączniki:

Aby zobaczyć załączniki musisz się zalogować. Tylko zalogowani użytkownicy mogą oglądać i pobierać załączniki.

_________________
Więcej dziwactw na: www.youtube.com/user/mopsiok



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 wrz 2013, o 22:45 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 12 paź 2011
Posty: 780
Pomógł: 20

Witam super :)

Może się czepiam ale warto wiedzieć, że jeżeli deklarujemy np 20 elemntową tablicę i wpiszemy jedną wartość w tablicy to automatycznie reszta wartości otrzymuje zera. W przeciwieństwie kiedy deklarujemy tylko tablice bez przypisywania jakichkolwiek wartości bo wtedy mamy przypadek dokładnie jak ze zmienną czyli mamy przypadkowe wartości.

czyli starczy zapisać

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


bo reszta tablicy zostaje wypełniona zerami :)

wykonanie super :)

Pozdrawiam

_________________
sig off ;(



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 wrz 2013, o 23:35 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 12 paź 2011
Posty: 780
Pomógł: 20

Tylko skopiowałem :P ale dzięki za info

ObrazekObrazek

To prawda przynajmniej dla czystego GCC i PC :P bo o tym mówi standard C :)

_________________
sig off ;(



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 paź 2013, o 04:51 
Offline
Moderator
Avatar użytkownika

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

stachu napisał(a):
Tylko skopiowałem :P ale dzięki za info

To prawda przynajmniej dla czystego GCC i PC :P bo o tym mówi standard C :)


Stachu nie chcę się kłócić ale ....

standard C mówi co innego wg mnie

przykłady które pokazałeś pięknie pokazują co się dzieje ze zmiennymi które inicjalizujemy jako zmienne lokalne czyli wewnątrz funkcji.

Ba! nawet w pierwszym przypadku na fotce po lewej kompilator KRZYCZY i wymiotuje warningami że tablica jest niezainicjalizowana ale że używasz kociego Atmel Studio to pewnie nawet tego nie widzisz bo domyślnie te warningi są wyłączone - a to jest właśnie jeden z wielu kamyczków z mojej strony do tego że atmel studio jest KOCIE niestety :( Poza tym wyjaśniam w Bluebooku co się dzieje ze zmiennymi inicjalizowanymi wewnątrz funkcji - że tworzą się na stosie i może się zdarzyć choć nie musi, że nie nie będą one miały zerowych wartości. To jest NORMALNE ... i o tym mówi standard C

ale mówi też jeszcze o czymś innym .... otóż o tym, że jeśli zmienne definiujemy jako GLOBALNE, to czy tego chcesz czy nie chcesz będą one miały ZEROWE wartości i nie ma sensu w ogóle ich inicjalizować zerem ani tak:

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


ani tak

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


bo pojawią się w sekcji zmiennych globalnych gdzie wszystkie są ZEROWANE automatycznie przy starcie ... i nawet nie ma sensu ich inicjalizować wtedy zerami "tak na wszelki wypadek" ;) bo i tak kompilator będzie miał to głęboko gdzieś ;) Zresztą zrób sobie taki sam test jak na obrazku po lewej tylko że definicję tablicy daj w obszarze zmiennych globalnych czyli przed main ok ?

--------------------------------------------

oczywiście, że specyfikator volatile jest tu absolutnie niepotrzebny przy tej tablicy i to z dwóch powodów:

1. bo nie jest to zmienna używana w przerwaniu
2. nawet gdyby była używana w przerwaniu i programie głównym - to w przypadku tablic volatile można pominąć bo i tak dostęp do nich jeśli odwołujemy się oczywiście przez indeks do całej tablicy jest także w asemblerze w ten sam sposób obsługiwany i nie może być zoptymalizowany. Ale gdyby gdzieś w kodzie programu ktoś chciał użyć jednego elementu tablicy np &tab[3] przez wrzucenie go do zmiennej trzeba byłoby sprawdzić bo teraz nie pamiętam.

--------------------------------

mopsiok - z tego co wyżej napisałem widać, że w ogóle niepotrzebnie próbujesz inicjalizować zerem wszystkie zmienne globalne - po prostu musisz na przyszłość zapamiętać co robi standardowo kompilator ;) będziesz miał mniej pisania

no i te paskudne typy

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


:( doprowadzą cię kiedyś do rozpaczy w AVR GCC zobaczysz - po to wymyślono typ

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


żeby go stosować w takich przypadkach....

_________________
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: 1 paź 2013, o 09:46 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 cze 2013
Posty: 137
Lokalizacja: Kraków
Pomógł: 0

Cześć!

Miło mi że rozwinęła się dyskusja w związku z moim tworem, a raczej w związku z moimi błędami programowymi :lol:. Dzięki za rady, bardzo fajnie że nie trzeba ustawiać tablic i zmiennych globalnych, doprowadzało mnie to do szału :D. Odpowiadając po kolei:

Antystatyczny napisał(a):
1. W jakim celu obsługujesz skok w złe przerwanie?
2. Co zadecydowało o tym, że compare() jest funkcją w pętli głównej zamiast w przerwaniu?

1. Przyznam że nie wiem, C uczyłem się z jakiejś tam książki i we wszystkich przykładach była ta obsługa. Pewnie nie ma to sensu, ale wolę dmuchać na zimne, bo to i tak tylko dwie linijki kodu.
2. Przyzwyczajenia ;). Staram się nie pakować dłuższego kodu w obsługę przerwania, a stosować raczej flagi.

mirekk36 napisał(a):
no i te paskudne typy [...]

Przyznam że nie bardzo rozumiem różnicę między unsigned char a uint8_t. Dla mnie to pierwsze wygląda ładniej, dlatego go używam ;). Poszukałem na szybko różnicy między tymi dwoma typami, ale znalazłem tylko coś o tym że to drugie informuje kompilator o tym że przechowujemy liczbę a nie znak, ale... co za różnica? Byłbym wdzięczny gdyby ktoś obeznany mi to wytłumaczył.

Dzięki za zainteresowanie, cieszę się że projekt nie został jakoś szczególnie skrytykowany :D.

_________________
Więcej dziwactw na: www.youtube.com/user/mopsiok



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 paź 2013, o 10:46 
Offline
Moderator
Avatar użytkownika

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

mopsiok napisał(a):
Dzięki za zainteresowanie, cieszę się że projekt nie został jakoś szczególnie skrytykowany


Projekt działa ;) ... pokazałeś nawet dość fajne efekty. A reszta to tylko uwagi właśnie, które mogą się przyczynić do podniesienia własnego skill'a w dalszym programowaniu.

Dodam więc, tak jak mówił Antystatyczny, że akurat taką obsługę PWMów programowych też bym zrobił w przerwaniu. Flagi owszem są potrzebne no ale nie należy przesadnie do tego podchodzić bo gdyby tak miało być jak u ciebie to można byłoby JESZCZE BARDZIEJ skrócić kod i w ogóle wywalić procedurę obsługi przerwania skoro w nim jest ustawiana tylko flaga. Dlaczego ? już tłumaczę - zresztą nie pierwszy raz na tym forum ;) .... ano dlatego że masz flagę sprzętową przerwania i z niej można korzystać dokładnie tak samo jak z tej programowej tyle tylko że tracisz O WIELE mniej czasu no i kodu we flashu robi się mniej ;) ... jak ? o tak: (twoja pętla główna)

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

(a oczywiście wywalasz całego ISR'a ;) no i przy inicjalizacji nie włączasz przerwań w tym timerze0 ;) )

Widzisz jak prosto .... ? ... dlatego twój przykład jest można powiedzieć troszkę nawet (ale nie odbierz tego źle - żartobliwie mówię) wynaturzeniem wręcz korzystania z flag. Ja wprawdzie w niebieskiej książce podaję podobny przykład przy obsłudze RTC i ustawianiu w ten sposób flagi ... ale to TYLKO po to żeby zrozumieć w ogóle o co chodzi w tych mechanizmach flag. Warto ich używać gdy coś jeszcze się dzieje w przerwaniu i niejako przy okazji wtedy można machać flagą ;) albo flagami do innych celów.

Do tego dodam, że u ciebie to działa bo w pętli głównej nic innego nie robisz poza obsługą tych PWM'ów .... ale gdybyś tam miał jeszcze kawał innego programu to sam byś zobaczył że nastąpiłaby MASAKRAAAA .... wtedy jedynym znowu ratunkiem byłoby przeniesienie tych porównań bezpośrednio do procedury obsługi przerwania ... a program główny robiłby swoje w pętli głównej .... taką drogą warto iść

Kolejna sprawa, to ten dziwoląg mały w kodzie :(

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


w ogóle niepotrzebny bo domyślnie kompilator sam to robi - to DOKŁADNIE tak samo jak z tą inicjalizacją zerami przez ciebie - niepotrzebną zresztą jak już wiesz.

--------------

unsigned char vs uint8_t

tu nie chodzi o różnicę pomiędzy typami ... bo jest to DOKŁADNIE to samo ale ... ale jest pewne ale ... o którym rzadko kto wspomina a potem początkujący tacy jak ty, którzy mówią z uporem że im się to podoba a programują w AVR GCC później mają rwanie włosów z głowy gdy przyjdzie wchodzić w dalsze bardziej zaawansowane techniki programowania - gdzie szczególnie wtedy początki są trudne ....

Po części wyjaśniam to także w swoim Bluebooku

http://atnel.pl/mikrokontrolery-avr-jezyk-c.html

i także już niejednokrotnie pisałem o tym na forum ale co tam ;) jeszcze raz

1. char - jest DOMYŚLNIE w opcjach kompilacji w AVR GCC zamieniany i tak na unsigned char - więc już chociażby z tego powodu nie ma w ogóle sensu pisać unsigned char (znowu to coś jak z tymi inicjalizacjami zerem) ;) ... Oczywiście można sobie wyłączyć w opcjach kompilatora tą automatyczną zamianę tylko po co panie? po co ?

A tymczasem taki początkujący jak ty - sporo piszący w AVR GCC dość szybko się przyzwyczaja do kociego unsigned char i jeszcze mówi że mu się to podoba ;) (matko! TYLE pisaniny :lol: zamiast krótkiego uint8_t)
Ale ok pierwsza zaleta jak widać to mniej pisania, ok ktoś powie czochra mnie to, Druga w takim razie zaleta - jak widać typ uint8_t to dla oka od razu jasne jest że chodzi o unsigned int short (8-bit) ....

No i NAJWAŻNIEJSZE - uważaj teraz dobrze - przede wszystkim twórcy C stworzyli typ char jak myślisz dlaczego ? zadałeś sobie kiedyś to pytanie ? ... ja tak i poszukałem , odpowiedź jest prosta char to skrót od character, czyli znak. I właśnie ten typ zwyczajowo służył do trzymania zmiennych które związane były z trzymaniem w nich np kodów ASCII znaków .... natomiast wszelkiego rodzaju liczby trzyma się w typach wszelkiej maści int, short int, long int itp

Tyle że z kolei stwórcy AVR GCC (mądrzy ludzie zresztą) postanowili znacząco uprościć życie programistom procków i żeby nikt się nie zastanawiał za długo ile bajtów/bitów ma np typ int czy long int czy short int w AVR GCC to stworzono (i słusznie)

uint8_t
int8_t

uint16_t (odpowiednik unsigned int)
int16_t (odpowiednik int)

uint32_t

.... i tak dalej

i teraz UWAGA .... przyjdzie ci w swojej dalszej karierze AVR GCC korzystać z wbudowanych funkcji w AVR GCC szczególnie operujących na wskaźnikach do char , wskaźnikach do uintX_t itp ....

i SZLAG cię będzie trafiał gdy zaczną się pojawiać kocie warningi no bo np do jakiejś tam funkcji przekazać chcesz wskaźnik do tablicy znaków ASCII np twoja zmienna:

unsigned char tab[]="test";

funkcja( tab );

a tu warning i warning - że typy się nie zgadzają ;) I dobrze ci tak ;) powiedziałbym - a po co stosujesz KOCI unsigned char zamiast char panie ? Bo z punktu widzenia kompilatora to już jest RÓŻNICA którą trzeba owarningować ....

więc gdybyś szedł za poradami tych ludzi którzy stworzyli kompilator z którego korzystasz - to nie pisałbyś właśnie unsigned char tylko char (bo domyślnie kompilator i tak zamieni to na unsigned) i masz z głowy

ale jak się uprzesz to możesz zostać przy swoim kocim unsigned i funkcję wołać tak ;)

funkcja( (char*) tab );

czyli robiąc jawne rzutowanie na typ char* ... ale skoro lubisz tyle pisania to może przy tym zostaniesz ;) do czasu aż kiedyś i tak cię to wkurzy - tak samo jak (wciąż wracam - zerowanie zmiennych globalnych) ;)

jak to mówią - wystarczy tylko poczytać instrukcję

------------------------

i ostatni argument dlaczego uint8_t zamiast unsigned char czy też zamiast char.

bo oczywiście taka forma syntaktycznie jest w pełni poprawna, np:

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


ale styl dobrego programowania w C a nie jakieś tam wymogi formalne mówi nam że warto to zrobić tak:

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


mniej więcej z takiego samego powodu jak ten poniżej, bo np jak widzisz takie zmienne w kodzie gdzie masz akurat tysiąc różnych zmiennych a pomiędzy nimi widać:

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


dla mnie - jak widzę taki kod - to widzę od razu niedbalstwo o typy o ich nazewnictwo, bo gdyby to napisać tak:

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


to ja od razu na pierwszy rzut oka widzę, że O! gościu używa zmiennej tablicowej buf na jakiś bufor znaków ASCII, tak samo zmiennej zn. A pozostałe zmienne to typowe numeryczne do jakichś tam obliczeń.

Czyli NAWET z tak trywialnego kawałka kodu coś widać dla oka - na pierwszy RZUT ... a wiadomo że im dłuższy kod tym ważniejsza jest jego CZYTELNOŚĆ i PRZEJRZYSTOŚĆ. A to był jeden z NAJWAŻNIEJSZYCH celów jaki przyświecał stwórcom języka C. Tyle że ma on tak dużo możliwości i można go używać na milion sposobów, że bardzo szybko tam gdzie wkrada się niedbałość o styl dobrego programowania to kody są o wiele trudniejsze do analizy nawet dla samego siebie po kilku latach ....

Popytaj ludzi - ci którzy używają char zgodnie z tą zasadą - powiedzą ci , że jak tylko człowiek to zrozumie i się przyzwyczai to później samemu inaczej wręcz czyta się własne nawet kody programów.

O to chodzi ;)

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

mopsiok napisał(a):
2. Przyzwyczajenia . Staram się nie pakować dłuższego kodu w obsługę przerwania, a stosować raczej flagi.


I sam widzisz - już masz przyzwyczajenia ale wcale nie najlepsze bo nie chodzi o długość ;) ale o jakość ;) ... to taki żarcik - ale nawiązujący też do tego co napisałem wyżej.

_________________
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: 1 paź 2013, o 11:22 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 12 paź 2011
Posty: 780
Pomógł: 20

No cóż myliłem się późno było ale dowiedziałem się przy okazji parę ciekawych rzeczy.

Przepraszam za wprowadzanie w błąd, przykład podałem w czystym GCC dla PC

Pozdrawiam.

_________________
sig off ;(



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 paź 2013, o 11:25 
Offline
Moderator
Avatar użytkownika

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

stachu napisał(a):
Przepraszam za wprowadzanie w błąd, przykład podałem w czystym GCC dla PC


Ale nie ma za co przepraszać - wszyscy razem się tu uczymy, a przykład podałeś dobry tyle że dla zmiennych lokalnych. Przyznam, że ja nawet nie pamiętałem o tym że jak się wpisze do tablicy przy inicjalizacji pierwszą wartość w takiej zmiennej lokalnej to kolejne zostaną już uzupełnione zerami a sprawdzić też jakoś mi się nie chciało.

Więc jak widać - z takiej dyskusji zawsze można się czegoś dowiedzieć ;)

_________________
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: 1 paź 2013, o 14:32 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 cze 2013
Posty: 137
Lokalizacja: Kraków
Pomógł: 0

Dzięki za odpowiedź Mirku, teraz już wiem dlaczego robić tak a nie inaczej. Staram się pisać zgodnie z "dobrym stylem programowania", po prostu nie zdawałem sobie sprawy że to co robię jest "złe" :D.
Zawsze wychodziłem z założenia że najwięcej się człowiek uczy na własnych błędach - prosty projekt, a ile ciekawostek się dowiedziałem. Zmienne globalne, odpowiednie typowanie, BADISR a nawet flagi przerwań (za tę informację szczególnie dziękuję, doceniam jej znaczenie ^^).

_________________
Więcej dziwactw na: www.youtube.com/user/mopsiok



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 lut 2014, o 15:15 
Offline
Nowy

Dołączył(a): 31 sty 2014
Posty: 7
Pomógł: 0

Świetny pomysł czasem sam też chciałbym coś przetestować i brakuje mi wolnego PWM-a a naraz jest 20 PWM :D Gratulacje



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

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 0 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