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



Teraz jest 25 mar 2026, o 23:34


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 22 ] 
Autor Wiadomość
PostNapisane: 12 paź 2015, o 09:19 
Offline
Użytkownik

Dołączył(a): 07 paź 2015
Posty: 79
Pomógł: 0

Szanowni Forumowicze!
Jako, że jestem tu nowy, na początku chciałbym wszystkich serdecznie przywitać :)
A teraz do rzeczy :D - od kilku dni próbuję obsłużyć termometr firmy Dallas model DS18B20. O ile na Arduino nie ma z tym problemu z racji gotowych bibliotek, o tyle na atmedze8 sprawia mi to kłopot. Nie chcę korzystać z gotowych bibliotek do obsługi tego termometru (przynajmniej nie na tym etapie nauki) bo zależy mi na zrozumieniu i nauczeniu standardu 1-wire. Poza tym, jak zrozumiem jeden przykład to i dalej będzie łatwiej. Poniżej wstawiam kod, prawie identyczny z artykułu, który jest w załączniku:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Mój problem polega na tym, że po skompilowaniu i wgraniu, na LCD wyświetla się ciągle "cisza", czyli nawet impuls resetu nie został wysłany. Prawdopodobnie problem tkwi w opóźnieniach zrobionych przy pomocy funkcji 'delay' i byłoby lepiej do odmierzenia tak małych przedziałów czasowych jak mikrosekudny wykorzystać timer i przerwania. Do tej pory wykorzystywałem przerwania globalnie, tzn. uruchamiałem je przed pętlą główną i zgłaszałem przerwanie przy przepełnieniu licznika. Ale takie rozwiązanie "liczy" impulsy cały czas, a ja potrzebuję odmierzać czas w konkretnych miejscach w programie. W takim razie moje pytanie: czy prawidłowym jest uruchamianie przerwań lokalnie w miejscach, gdzie potrzebne jest mi odliczanie czasu? Np w funkcji uc1Wire_ReadBit() w miejscu, gdzie obecnie mam 'delay' ustawiam początkową wartość rejestru TCNT0 tak, aby zliczanie impulsów trwało tyle, ile potrzebuję (od rozpoczęcia do przerwania), zgłaszam przerwanie przy przepełnieniu, wykonuję obsługę przerwania (polegającą na odczekaniu wymaganego czasu), a potem wyłączam przerwania i przechodzę do dalszej części programu? Czy może problem tkwi gdzie indziej?
Dodam, że termometr jest sprawny (sprawdzałem za pomocą Arduino i działa), procesor to atmega8, taktowanie ustawione na zewnętrzny kwarc 16MHz. Żeby uzyskać zliczanie impulsów co 1us mógłbym np. zmienić kwarc na 8MHz i ustawić preskaler na 8. Bluebooka mam, ale odpowiedzi na moje pytanie nie znalazłem :(
Proszę uprzejmie o wskazówki.
Pozdrawiam.


Załączniki:

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



Ostatnio edytowano 12 paź 2015, o 10:23 przez dawid75_75, łącznie edytowano 1 raz

Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 12 paź 2015, o 10:15 
Offline
Użytkownik

Dołączył(a): 22 sty 2014
Posty: 1806
Zbananowany użytkownik

Pomógł: 168

Wstaw kod w znaczniki syntax=C bo w tej chwili jest mega nieczytelny


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 12 paź 2015, o 10:24 
Offline
Użytkownik

Dołączył(a): 07 paź 2015
Posty: 79
Pomógł: 0

Poprawione - wstawiłem w tym znaczniku, ale 'c' napisałem wielką literą i już nie odczytało poprawnie.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 12 paź 2015, o 15:05 
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

dawid75_75 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.

Masz wykrzyknik ! zamiast pionowej kreski |


Autor postu otrzymał pochwałę

_________________
Dragonus Cracovus: Biomagia



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 12 paź 2015, o 15:47 
Offline
Użytkownik

Dołączył(a): 05 lut 2014
Posty: 252
Lokalizacja: obok Częstochowy
Pomógł: 14

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


A to jest dobrze ?


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 12 paź 2015, o 15:56 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 17 sie 2013
Posty: 3797
Lokalizacja: Grudziądz
Pomógł: 143

Jeżeli funkcja cos zraca.

Namazane ze smarta.

_________________
Usługi druku przestrzennego - www.drumik.pl



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 12 paź 2015, o 19:14 
Offline
Użytkownik

Dołączył(a): 07 paź 2015
Posty: 79
Pomógł: 0

Krauser napisał(a):
dawid75_75 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.

Masz wykrzyknik ! zamiast pionowej kreski |


Rzeczywiście, nie zauważyłem. Nie wiem jakim cudem tam to wpisałem.

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
- odnośnie funkcji uv1Wire_ReadByte();

Poprawiłem, ale dalej "cisza", czyli nawet reset nie działa. Problem w interwałach czasowych i potrzebny timer/counter do precyzyjnego odmierzania czasu?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 12 paź 2015, o 20:03 
Offline
Użytkownik

Dołączył(a): 05 lut 2014
Posty: 252
Lokalizacja: obok Częstochowy
Pomógł: 14

Wrzuciłem twój kod do eclipsa.
Nie masz zainkludowanej biblioteki do tej funkcji:

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


Niepotrzebnie też inkludujesz plik .c od wyświetlacza.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 12 paź 2015, o 20:09 
Offline
Użytkownik

Dołączył(a): 07 paź 2015
Posty: 79
Pomógł: 0

W opcjach projektu mam dodaną bibliotekę: "libprintf_flt.a" i ta konwersja mi działa, bo sprawdzałem to przy programie mierzącym temperaturę za pomocą termometru MCP9700.
A kiedy nie zainkluduję pliku .c do wyświetlacza to kompilator wyrzuca takie błędy:
undefined reference to `LCD_Initalize' i tak to każdej funkcji dotyczącej wyświetlacza.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 12 paź 2015, o 21:39 
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

Na początek sprawdź czy rzeczywiście delay działa jak należy. Zamiast termometru podłącz LED przez rezystor 1k i użyj takiego kodu:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


W define nie dawaj średników, bo masz teraz jakby zdublowane. Tak wystarczy
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 chodzi załączanie plików c to nie powinieneś tego robić. Plik ma być w drzewku projektu i zostanie skompilowany, a załącza się tylko plik *.h

------------------------ [ Dodano po: 10 pikosekundach ]

Opóźnienie na timerze typu delay możesz zrealizować bez użycia przerwań. Wpisujesz do licznika timera odpowiednią wartość. Konfigurujesz timer w odpowiedni tryb i ustawiasz preskaler (co włącza zliczanie). Sprawdzasz w pętli while flagę przerwania (co wstrzymuje program). Wyłączasz timer. Dla innego opóźnienia ustawiasz inaczej.


Autor postu otrzymał pochwałę

_________________
Dragonus Cracovus: Biomagia



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 12 paź 2015, o 22:09 
Offline
Użytkownik

Dołączył(a): 07 paź 2015
Posty: 79
Pomógł: 0

Średniki usunąłem i sprawdziłem delay... nie działa w ogóle, za szybko przeskakuje dalej, w ogóle nie widzę, żeby zapaliło diodę. A dioda sprawna, bo jak podłączyłem bezpośrednio pod 5V to się ładnie świeci.

Co ciekawe, w innym programie, gdzie miałem tylko mruganie na zmianę LEDami to opóźnienie delay(1000)ms działało prawidłowo... Jednak wtedy miałem ustawiony wewnętrzny oscylator na 1MHz. Tutaj mam kwarc ma 16MHz, ale w opcjach projektu zdefiniowałem F_CPU.
Co może być powodem, przez który delay nie działa?

Edit-----
Napisałeś tak:
Cytuj:
Opóźnienie na timerze typu delay możesz zrealizować bez użycia przerwań. Wpisujesz do licznika timera odpowiednią wartość. Konfigurujesz timer w odpowiedni tryb i ustawiasz preskaler (co włącza zliczanie). Sprawdzasz w pętli while flagę przerwania (co wstrzymuje program). Wyłączasz timer. Dla innego opóźnienia ustawiasz inaczej.

Pierwsze 3 zdania rozumiem - np. ustawiam sobie timer 16bitowy i korzystam z rejestru TCNT1 do ustawiania licznika z odpowiednią wartością. Mogę ustawić atmegę na 8MHz i preskaler na 8 co da mi zliczanie impulsów co 1us.
Ale już w 4. zdaniu piszesz, że sprawdzam flagę przerwania, a w pierwszym zdaniu, że przerwań nie używamy i to sprawia, że całości pojąć nie mogę :D Proszę uprzejmie o bliższe wskazówki.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 12 paź 2015, o 23:16 
Offline
Użytkownik

Dołączył(a): 06 maja 2014
Posty: 415
Lokalizacja: Kraków
Pomógł: 26

Według mnie chodzi o to:

Ustawiasz licznik, żeby liczył zadany przez Ciebie czas - to już sam napisałeś, że pojmujesz.
W momencie, gdy licznik się przepełni, czyli "przeskakuje" z max na 0 (ewentualnie realizuje funkcję liczenia do odpowiedniej wartości) w odpowiedzim rejestrze ustawiana jest flaga (czyli taki znacznik), że licznik doliczył do oczekiwanej wartości i powinno zostać zrealizowane przerwanie z tym związane. Jednak nie musisz pisać procedury wykonania tego przerwania - wystarczy wtedy wyczyścić flagę timera.

W skrócie: wystawienie flagi przez timer oznacza, że przerwanie powinno się w tym momencie wykonać. Jednak można pominąć wykonanie przerwania i ręcznie skasować tą flagę (domyślnie kasuje się ona samoczynnie przy wykonywaniu przerwania). Zwróć uwagę, że w dalszym ciągu wiesz, ile czasu minęło - bo timer liczy prawidłowo.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 12 paź 2015, o 23:21 
Offline
Użytkownik

Dołączył(a): 07 paź 2015
Posty: 79
Pomógł: 0

Czy to jest to samo co to (?):
http://www.electroons.com/electroons/timer_delay.html
Tutaj też wykorzystuję timer i nie zgłaszam przerwania.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 13 paź 2015, o 07:49 
Offline
Użytkownik

Dołączył(a): 06 maja 2014
Posty: 415
Lokalizacja: Kraków
Pomógł: 26

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


Taka jest idea, jednak tutaj jest to źle zrealizowane - zauważ, że programista sam odejmuje wartości w liczniku (TCNT1=(TCNT1-1);) - więc po co do tego używać licznika? Taką operację można zrobić na jakiejkolwiek zmiennej. Dodatkowo najpierw ustala preskaler na 64, a następnie zmienia wartość tego countera/timera z maksymalną prędkością, w każdym obiegu pętli - gdzie tu sens, gdzie logika?
Chodzi o to, żeby licznik sam sobie liczył, a Ty w odpowiednim momencie tylko go zerujesz.

Jak dla mnie wyglądałoby to w ten sposób (pseudo-kod, pokazujący ideę):

void czekaj(void) - oczywiście tutaj można uzmiennić, żeby dało się zmieniać wartość wykonywanego opóźnienia
{
TCCR0 |= ... ; - tutaj ustawić sobie preskaler aby timer odliczał z odpowiednią prędkością
TCNT = ... ; - tutaj ustawić wartość początkową (aby miał do zliczenia odpowiednią ilość impulsów)
while (!(TIFR && TOV0)); - tutaj oczekuje, aż timer odliczy sobie czas
TIFR |= (1 << TOV0); - w momencie, gdy już doliczy (i powinno się pojawić przerwanie) czyści flagę przepełnienia timera
TCCR0 |= ... ; - tutaj wyzerować preskaler, aby timer przestał odliczać (w kolejnym wywolaniu funkcji znów go uruchomisz)

}

Powyższy przykład pisany na przykładzie TIMER'a 0 w atmega 8. Musisz go dostosować do swojej sytuacji - ustawić odpowiednie rejestry, preskalery itd.

Mam nadzieję, że nie napisałem steku bzdur z powodu wczesnej godziny :D
Krzysiek



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 13 paź 2015, o 08:31 
Offline
Użytkownik

Dołączył(a): 07 paź 2015
Posty: 79
Pomógł: 0

Zgodnie z Twoimi wskazówkami krzysssztof wypociłem takie coś:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Nada się?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 13 paź 2015, o 13:14 
Offline
Użytkownik

Dołączył(a): 06 maja 2014
Posty: 415
Lokalizacja: Kraków
Pomógł: 26

Wygląda w porządku, niezbyt mam teraz czas otwierać notę katalogową i dokładnie sprawdzać.
Zamiast
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

powinno być
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
- czyli trzeba użyć &&, żeby wykonać maskowanie bitowe, żeby sprawdzić tylko bit TOV1.

Napisz jakiś prosty program do migania diodą, użyj tej funkcji i wtedy przekonasz się, czy jest prawidłowo :)

Miej też na uwadze, że szybkość zliczania timera zależy od częstotliwości taktowania procesora.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 13 paź 2015, o 13:34 
Offline
Użytkownik

Dołączył(a): 06 maja 2014
Posty: 415
Lokalizacja: Kraków
Pomógł: 26

Faktycznie, napisałem odwrotnie do rzeczywistości. Dzięki



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 13 paź 2015, o 14:17 
Offline
Użytkownik

Dołączył(a): 07 paź 2015
Posty: 79
Pomógł: 0

No nie wiem co się dzieje, ale w ogóle nie chce to działać. Ustawiłem wewnętrzny oscylator na 8MHz, preskaler na 8, co mi da zliczanie impulsów z prędkością 1MHz. To znaczy, że 16bitowy licznik liczy od 0 do 65535 z krokiem 1us między impulsami. Zwykłe delay też nie chce działać, nawet jeśli chodzi o milisekundy. Sprawdzałem na diodzie ustawiając port C jako wyjście i dając stan wysoki na pin PC4. O co tu może chodzić?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 13 paź 2015, o 15:00 
Offline
Użytkownik

Dołączył(a): 06 maja 2014
Posty: 415
Lokalizacja: Kraków
Pomógł: 26

PC4 powiadasz ?
A co to za procesor, JTAG wyłączyłeś?
Spróbuj podłączyć tą diodę pod inny port niż PORT C.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 13 paź 2015, o 17:40 
Offline
Nowy

Dołączył(a): 18 mar 2014
Posty: 16
Pomógł: 0

Witam, przymierzam się do napisania projektu potrzebnego na zajęcia z programowania. Natrafiłem na problem, posiłkowałem się poradnikiem z linku u góry. Sprawdziłem _delay odmierza dobry czas na migającej diodzie, lecz na wyświetlaczu pojawiają się zera, obojętnie z której metody bym nie skorzystał. Napis 'cisza' także się nie wyświetla.
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: 13 paź 2015, o 19:56 
Offline
Użytkownik

Dołączył(a): 07 paź 2015
Posty: 79
Pomógł: 0

Więc tak: procesor to Atmega8 i JTAG nie posiada.
Przerzuciłem całość na port B i też nic się nie dzieje.
Sprawdziłem, czy z procesorem wszystko w porządku i skompilowałem malutki programik do migania jedną diodą. Działa na porcie B i C na tym samym pinie co próbuję uruchomić ten przeklęty termometr. Funkcje delay działają. Źródło taktowania zmieniłem z wewnętrznego oscylatora na zewnętrzny kwarc 8MHz i kondensatory 22pF.
Przyczyna leży gdzieś indziej, proszę o dalsze wskazówki :)

Edit - - -
Czy fakt, że mam podłączony LCD może mieć coś na rzeczy?

Edit 2 - - -
skopiowałem kod odpowiedzialny za miganie diodą na pinie PB0 z programu, który działał na tych samych ustawieniach procesora do pętli głównej tego nieszczęsnego programu i co dziwne - nic, w ogóle nie zostało to wykonane. O co tu może chodzić?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 13 paź 2015, o 20:54 
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

krzysssztof napisał(a):
TIFR |= (1 << TOV0); - w momencie, gdy już doliczy (i powinno się pojawić przerwanie) czyści flagę przepełnienia timera

Wyjątek od reguły występuje dla zerowania fag przerwań. Powyższy przykład jest błędny już tłumaczę dlaczego. Flagi przerwań zerowane są przez wpisanie tam 1 i na przykład mamy rejestr TIFR z flagami przerwań o zawartości 0b00000101. Jak chcemy wyzerować bit 0 to należy użyć instrukcji:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

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

i jest to to samo co:
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 to tak, że do rejestru zostanie wpisana liczba 0b00000001 i ta jedynka wyzeruje bit 0, a zera nic nie zmienią. Użycie
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

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

Wywoła następujące działania:
Odczytanie TIFR w którym np. jest 0b00000101, wykonanie sumy bitowej 0b00000101 | 0b00000001 = 0b00000101 i zapisanie tego do rejestru TIFR czyli:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Spowoduje to wyzerowanie zarówno flagi TOV0 jak i TOV1, a tego akurat nie chcemy.
dawid75_75 napisał(a):
Czy fakt, że mam podłączony LCD może mieć coś na rzeczy?

Jego funkcje mogą przekonfigurować inne piny na tym samym porcie, ale nie muszą. Najlepiej LCD trzymaj na oddzielnym porcie, ale to wszystko zależy jak to zostało zaimplementowane.

_________________
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: 22 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 1 gość


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