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



Teraz jest 4 kwi 2026, o 00:02


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 11 ] 
Autor Wiadomość
PostNapisane: 6 sty 2016, o 14:01 
Offline
Nowy

Dołączył(a): 02 sty 2016
Posty: 6
Pomógł: 0

Hej :)

Chcę podłączyć 3 czujniki odległości do kanałów ADC (porty PA1, PA2, PA3) i odczytywać z nich pomiary przez cały czas. Ponieważ po przetestowaniu czujników doszłam do wniosku że pewne czynniki wpływają na niestabilność pomiaru, chcę jako ostateczny wynik wziąć średnią arytmetyczną z 8 pomiarów przeprowadzonych w trakcie jednego cyklu pomarowego (mam nadzieję że dobrze się wyrażam :D). Zatem włączyłam obsługę przerwań, i w przerwaniu taki proces zdefiniowałam. Przerwanie włącza się po przepełnieniu timera, flaga jest ustawiona na 0. Po dokonaniu sumowania i obliczeniu średniej następuje kasowanie i ustawienie od nowa rejestru ADMUX, powrót do poczatkowej wartości licznika i ustawienie flagi na 1 czyli wyjście z przerwania. W mainie przypisuję obliczoną średnią do zmiennej jako ostateczny wynik i przechodzę do kolejnego kanału, ustawiając flagę na 0 czyli wykonując kolejne przerwanie, itd. Aby sprawdzić czy faktycznie następuje multipleksowanie, w każdym case włączam kolejno diody. Tylko że te diody mi się nie świecą wcale :D

No i tu pytanie, czy coś robię mega źle? Nie wiem też czy ustawiłam częstotliwość próbkowania ADC i timera0 odpowiednio do 1MHz taktowania procesora. W ogóle, czy takie rozwiązanie ma sens :?: Bardzo proszę o pomoc :*
Kod poniżej:

Cytuj:
#define F_CPU 1000000 //czêstotliwoœc oscylatora na 1MHz <---- tego NIGDY nie piszemy w kodzie .... a szczególnie na tym forum, bardzo o to proszę - mirekk36 ok?


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



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 6 sty 2016, o 22:15 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 29 maja 2013
Posty: 432
Lokalizacja: Gostyń / Poznań
Pomógł: 25

Ustawiasz jako wyjściowe PD4, PD5, i PD6 a sterować chcesz PD1, PD2 i PD3... To gdzie te diody są?

_________________
Podpis...



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 7 sty 2016, o 01:31 
Offline
Nowy

Dołączył(a): 02 sty 2016
Posty: 6
Pomógł: 0

sorry faktycznie powinno być DDRD=0x00001110; ale zmieniłam i nadal nie działa ;/



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 7 sty 2016, o 13:03 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 29 sty 2012
Posty: 777
Lokalizacja: Karpicko k. Wolsztyna
Pomógł: 197

Wirtam.

Po przejrzeniu kodu kilka rzeczy rzuciło mi się w oczy.

W przerwaniu timera zmienne number i SumADCH to zmienne lokalne, które na początku każdego przerwania będą miały wartość zero.
Warunek
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

się spełni bo number==0. Program przypisze wartość ADCH do SumADCH i zwiększy wartość number o jeden. Ale w następnym przerwaniu zmienne number i SumADCH znów będą miały wartość zero. Kod po else nigdy się nie wykona. A tym samym zmienna flag nigdy nie przyjmie wartości równej jeden i cały kod w pętli while w warunku if(flag) się nie wykona. Dlatego diody się nie świecą.

Zmienne number i SumADCH powinny być statyczne. Wtedy będą widoczne tylko w przerwaniu ale zachowają swoje wartości po wyjściu z przerwania. Tak jak zmienne globalne.
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Jeśli chcesz mierzyć napięcie na kilku kanałach to lepiej na początek zrezygnuj z trybu Free Running i zastosuj najzwyklejszy tryb z ręcznym wyzwalaniem pomiaru. W trybie Free Running przełączanie kanałów jest troszkę bardziej skomplikowane.

Wybór kanałów też masz błędny.
Jeśli zmienna input będzie miała wartość np. 2 to tą linią kodu
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

wybierzesz kanał ADC4 a nie ADC2.
Kanał ADC2 to takie ustawienie rejestru ADMUX 0b00000010. A ta linia ustawi trzeci bit w ADMUX czyli 0b00000100. A to jest kanał ADC4.
Jeśli zmienna input przyjmuje wartości 1, 2 i 3 to zamiast kanałów ADC1 (0b00000001), ADC2 (0b00000010) i ADC3 (0b00000011) wybierasz ADC2 (0b00000010), ADC4 (0b00000100) i pomiar różnicowy na ADC0 i ADC0 (0b00001000).

Wybór kanału powinie wyglądać tak, bez przesunięcia bitowego
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Teraz jeśli input będzie równe 2 to rejestr ADMUX zostanie ustawiony tak 0b00000010. Oczywiście w tym przykładzie pominąłem ustawienie trzech starszych bitów.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 7 sty 2016, o 19:00 
Offline
Nowy

Dołączył(a): 02 sty 2016
Posty: 6
Pomógł: 0

Okej, faktycznie, nanoszę poprawki do kodu. Tylko nie rozumiem jednej rzeczy, w jaki sposób wyzwolić ręcznie ADC? Czy moja flaga, którą sama sobie zadeklarowałam i używam do wejścia / wyjścia z przerwania, ma odniesienie do bitów ADIF i ADIE w rejestrze ADCSRA?

Cytuj:
• Bit 4 – ADIF: ADC Interrupt Flag
This bit is set when an ADC conversion completes and the Data Registers are updated. The ADC Conversion
Complete Interrupt is executed if the ADIE bit and the I-bit in SREG are set. ADIF is cleared by hardware when
executing the corresponding interrupt handling vector. Alternatively, ADIF is cleared by writing a logical one to
the flag. Beware that if doing a Read-Modify-Write on ADCSRA, a pending interrupt can be disabled. This also
applies if the SBI and CBI instructions are used.
• Bit 3 – ADIE: ADC Interrupt Enable
When this bit is written to one and the I-bit in SREG is set, the ADC Conversion Complete Interrupt is activated.


W jaki sposób wykonać w moim programie ręczne wyzwolenie ADC? Czy powinnam zrobić coś w stylu pętli while(ADCSRA & (1<<ADSC)) w każdym case? A gdzie miejsce na odczyt flagi za pomocą ADIF? Czy to jest zbędne? Pewnie to herezja jakaś co mówię :D



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 7 sty 2016, o 19:48 
Offline
Uzytkownik zasłużony dla forum.atnel.pl
Avatar użytkownika

Dołączył(a): 16 lip 2012
Posty: 2088
Lokalizacja: Leżajsk / Kraków
Pomógł: 411

natalia4646 napisał(a):
W jaki sposób wykonać w moim programie ręczne wyzwolenie ADC?

Należy ustawić bit ADSC - ADC Start Conversion w rejestrze ADCSRA. Robisz to zresztą na starcie, ale w każdym przerwaniu timera należy ponowić ustawianie tego bitu, ale dopiero na końcu, gdy już kanał jest przestawiony.

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

Tak nie rób. 0 << x daje 0 i PORTD = 0 wyzeruje cały port, aby wyzerować tylko jeden bit/pin używa się takiej konstrukcji:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Co jest równoważne z PORTD = PORTD & 0b11110111. 0 << x jest nieprzydatne bo to zawsze 0
Ustawianie wybranego bitu bez wyzerowania pozostałych to:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Więcej takich pomocnych rad znajdziesz na blogu Mirka

_________________
Dragonus Cracovus: Biomagia



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 7 sty 2016, o 21:25 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 29 sty 2012
Posty: 777
Lokalizacja: Karpicko k. Wolsztyna
Pomógł: 197

Obejrzyj ten http://mirekk36.blogspot.com/2013/06/pr ... acych.html
i resztę poradników o ADC. Wiele ci się wyjaśni.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 sty 2016, o 00:42 
Offline
Nowy

Dołączył(a): 02 sty 2016
Posty: 6
Pomógł: 0

Dziękuję bardzo za Wasze uwagi i wyjaśnienia, bardzo mi pomogły :) poprawiłam i diody teraz świecą, ale bardzo słabiutko, ogólnie zauważyłam że kiedy korzystam z przerwań to światło diody jest ledwo widoczne, jaki wpływ mają przerwania na jasność świecenia diody? co robię nie tak? Kod poprawionego programu:

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


Wieem muszę się podszkolić troche odnośnie ADC, przewertowałam moją ulubioną niebieską książkę Pana Mirka, a poradniki po troszku, ale większość przede mną. Ale bardzo mi zależy na Waszej pomocy również :)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 sty 2016, o 16:00 
Offline
Uzytkownik zasłużony dla forum.atnel.pl
Avatar użytkownika

Dołączył(a): 16 lip 2012
Posty: 2088
Lokalizacja: Leżajsk / Kraków
Pomógł: 411

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

Zakładam, że chcesz uruchomić start konwersji. To oznacza, że należy ustawić bit ADSC, a pozostałe pozostawić bez zmian tymczasem taka konstrukcja zrobi nie to co powinna:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Jest tu tak samo jak ze sterowaniem wyjściami portu i należy to sobie poćwiczyć celem utrwalenia.

_________________
Dragonus Cracovus: Biomagia



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 sty 2016, o 19:57 
Offline
Nowy

Dołączył(a): 02 sty 2016
Posty: 6
Pomógł: 0

aaaaj powinno być ADCSRA |= (1<<ADSC);
tak? Teraz dodam do rejestru ADCSRA (i jego wszyskich skonfigurowanych uprzednio bitów) ADSC =1 , i rozpocznie się konwersja.
A te diody to nie wiem dlaczego się tak słabo świecą, coś jest źle.. :/



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 sty 2016, o 13:18 
Offline
Uzytkownik zasłużony dla forum.atnel.pl
Avatar użytkownika

Dołączył(a): 16 lip 2012
Posty: 2088
Lokalizacja: Leżajsk / Kraków
Pomógł: 411

natalia4646 napisał(a):
A te diody to nie wiem dlaczego się tak słabo świecą, coś jest źle.. :/

Jak masz taki problem to tylko dla tej części sprzętu napisz sobie najprostszy program. Pokaż schemat itd. Programowanie to w gruncie rzeczy składanie czegoś większego z klocków. Najprościej na początek sprawdzić sobie coś, a potem lecieć dalej z kolejnym kawałkiem. Na koniec składasz wszystko.

_________________
Dragonus Cracovus: Biomagia



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