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



Teraz jest 24 lut 2025, o 23:13


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 11 ] 
Autor Wiadomość
PostNapisane: 11 wrz 2015, o 19:25 
Offline
Użytkownik

Dołączył(a): 18 lip 2014
Posty: 69
Pomógł: 0

Witam,

Chciałem napisać prosty program, który działałby w ten sposób, że po zwarciu wybranych dwóch pinów portu C zapalałaby się odpowiednia dioda (np. po zwarciu pinu 0 i pinu 3 zapalałaby się dioda podłączona do pinu 0 portu A, a po zwarciu pinu 0 i pinu 2 (portu C) zapalałaby się lampka podłączona do pinu 1 w porcie A).

Niestety program nie działa, tzn. diody albo nie świecą wcale albo zapala się i to niekoniecznie ta która powinna w danym momencie.

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


Czy mógłbym prosić o pomoc w znalezieniu błędu?



Ostatnio edytowano 11 wrz 2015, o 20:12 przez Loreno, łącznie edytowano 1 raz

Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 11 wrz 2015, o 19:42 
Offline
Użytkownik

Dołączył(a): 25 lut 2015
Posty: 252
Lokalizacja: Lublin
Pomógł: 23

Przeczytaj proszę info o wstawianiu kodu - topic7402.html

Co do pytania, to musicz ten program zapisać w postaci "strawialnej" dla ludzi,
a nie procesora ;), wtedy uzyskasz pomoc.
W kodzie używamy zapisu dwójkowego tylko w uzasadnionych przypadkach.
Normalnie operuje się zapisem szesnastkowym - czytelnym równie dobrze jak system dziesiętny dla programisty,
a przypadku programowania wręcz niezastąpionym.
Jak nie masz książki, to skorzystaj np z internetu, np. kurs: http://hobby.abxyz.bplaced.net/index.php?pid=4&cid=1
jest idealny na początek.

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

Sama opracja liczenia twoich zer i jedynek, czyli ustalanie poprawności zapisu jest tutaj czynnikiem odstraszającym :)

------------------------ [ Dodano po: 9 minutach ]

No i przede wszystkim nie zwiera się pinów procesora!
Pokaż schemat, co Ty tam powyczyniałeś w układzie.


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 11 wrz 2015, o 20:10 
Offline
Użytkownik

Dołączył(a): 18 lip 2014
Posty: 69
Pomógł: 0

Jeśli chodzi o zapis bitowy, to tak programowaliśmy na studiach i dla mnie było to po prostu coś normalnego :) Od razu widać w zapisie 8-bitowym, który pin jest w stanie wysokim, a który w stanie niskim.

Nie można zwierać pinów procesora? Pisząc ten program, tak na prawdę chciałem przygotować się do obsługi klawiaturki 16-przyciskowej. Jeszcze do mnie nie dotarła i na razie zamiast wciskać przyciski, łączę kabelki. W każdym razie, klawiatura jest zbudowana w taki sposób, że ma wyprowadzenia dla poszczególnych wierszy i kolumn. Każde takie wyprowadzenie łączy się do pinów procesora (czyli np. w moim przypadku będę miał 8 wyprowadzeń, bo w klawiaturze 16-przyciskowej mamy 4 kolumny i 4 wiersze). Wciskając jakikolwiek przycisk na klawiaturze dokonujemy zwarcia między wierszem a kolumną, w których znajduje się ten przycisk, czyli de facto zawieramy 2 piny. Czy coś źle rozumiem?
Schematu już dzisiaj nie mam niestety możliwości wstawić, postaram się jutro.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 11 wrz 2015, o 21:02 
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

Zaraz o ustawieniu stanu na porcie nie można go czytać. Jest tak ze względu na synchronizację z zegarem. Należy dodać pustą instrukcję:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Autor postu otrzymał pochwałę

_________________
Dragonus Cracovus: Biomagia



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 12 wrz 2015, o 06:18 
Offline
Użytkownik

Dołączył(a): 18 lip 2014
Posty: 69
Pomógł: 0

Dzięki za podpowiedź. Nie wiedziałem, że tak łatwo wstawia się fragmenty kodu w asemblerze. Spróbuję tak zrobić w swoim programie i dam znać czy to pomogło.

Czy mógłbym prosić o bardziej szczegółowe wyjaśnienie, dlaczego trzeba wstawiać takie opóźnienie? Dlaczego przeszkadza tu synchronizacja z zegarem?

//EDIT

Dodałem opóźnienia:

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


Schemat (przepraszam, że odręcznie):
Obrazek

Po zastosowaniu poprawki program działa nieco lepiej, ale nadal źle, tzn.:
* Po zwarciu PC0 i PC3 zapala się właściwa dioda (czyli dioda nr 1)
* Po zwarciu PC0 i PC2 zapala się właściwa dioda (czyli dioda nr 2), ale po wyjęciu zworki z pinów (czyli nic nie jest podłączone do portu C), gaśnie dioda 2 i zapala się dioda 1 (czyli ta, która powinna palić się po połączeniu PC0 i PC3) //EDIT Zauważyłem, że czasem po wyjęciu zworki z PC0 i PC2 nie zapala się dioda 1, tylko zostaje dioda 2 (czyli tak jak powinno być)
* Czasem wystarczy, że włożę jeden koniec zworki w pin PC0 i już zapala się dioda 1, mimo że drugi koniec jest w powietrzu. Tak samo dzieje się, gdy badam napięcie woltomierzem na pinach, też nagle zapala się dioda 1

Aha, po użyciu woltomierza okazuje się, że moje napięcie zasilania to ok. 4.7V, a nie 5V. Czy to źle? Napięcie biorę z USB w komputerze. Być może winny jest woltomierz, bo jest to jakiś chiński multimetr, który może mieć już słabą baterię.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 12 wrz 2015, o 09:46 
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

Loreno napisał(a):
Czy mógłbym prosić o bardziej szczegółowe wyjaśnienie, dlaczego trzeba wstawiać takie opóźnienie? Dlaczego przeszkadza tu synchronizacja z zegarem?
Instrukcje procesora i odczyt stanu pinu są wykonywane w takt zegara. Producent informuje o tym w specyfikacji mikrokontrolera. Instrukcja zapisu stanu na wyjście zmieni stan, ale następna instrukcja odczytu odczyta stary stan. Jest tak nawet przy zapisie i odczycie tego samego pinu. Zewnętrzne obwody mikrokontrolera (ścieżki i przewody) to pojemności i indukcyjności co powoduje dodatkowe opóźnienia. W swoim programie niepotrzebnie robisz to tak szybko. Do dyspozycji masz funkcje _delay_us(liczba_mikrosekund) i _delay_ms(liczba_ms). Dopisz tylko na początku #include <util/delay.h>


Autor postu otrzymał pochwałę

_________________
Dragonus Cracovus: Biomagia



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 12 wrz 2015, o 10:00 
Offline
Użytkownik

Dołączył(a): 18 lip 2014
Posty: 69
Pomógł: 0

Zamiast asm volatile("nop\n\t"::); użyłem _delay_ms(100), ale nadal tak samo, więc cofnąłem tę zmianę.

Mam nadzieję, że koledzy zauważą jakiś błąd w moim programie, bo ja nic nie widzę.

//EDIT

Nieco poprawiłem kod, dodając 2 dodatkowe warunki w środku:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Układ działa już prawie dobrze. Jedynie czasami gdy np. zewrę PC0 i PC3 to normalnie zapala się dioda 1 (czyli dobrze), ale gdy wyjmuję przewód zwierający, to nagle zapala się dioda 2. Wydaje mi się, że jeszcze jest cos nie tak z programem.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 12 wrz 2015, o 13:36 
Offline
Użytkownik

Dołączył(a): 25 lut 2015
Posty: 252
Lokalizacja: Lublin
Pomógł: 23

Wstaw proszę dłuższe opóźnienie pomiędzy pierwszym warunkiem i jego powtórzeniem:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Przy opóźnieniu nop - nawet poniżej 1 us i obiegu pętli while np. dziesiątki tysięcy razy na sekundę
wpływ mają stany nieustalone na przełączniku (twojej zworce).
Nie wiem jaki efekt chcesz uzyskać, ale jeśli zakładasz, że będzie załączany tylko jeden przycisk, a nie więcej jednocześnie,
to nie musisz sprawdzać warunku wciśnięcia drugiego.
Po sprawdzeniu warunku na pierwszy dajesz else i zapalasz od razu diodę z drugiego.
Czyli jeśli pierwszy wciśnięty to zapala jego diodę i leci dalej pomijając część else.
Jeśli nie wciśnięty pierwszy (to musi być z definicji drugi), wykonuje część else i zapala drugą diodę.


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 12 wrz 2015, o 14:05 
Offline
Użytkownik

Dołączył(a): 18 lip 2014
Posty: 69
Pomógł: 0

@jerrylu - Twój pomysł rozwiązał problem. Teraz układ działa tak jak powinien, czyli po zwarciu PC0 i PC3 zapala się dioda 1 i pali się cały czas, nawet po odjęciu zworki. Natomiast po zwarciu PC0 i PC2 zapala się dioda 2 i pali się cały czas, nawet po odjęciu zworki.

Jeszcze chciałem sprawdzić czy program będzie działać poprawnie gdy zamienię wszystkie asm volatile("nop\n\t"::) na _delay_ms(20), ale niestety w takim przypadku zdarza się, że gdy zewrę PC0 i PC3 (zapala się dioda 1) i odejmę zworkę, zapala się dioda 2 (a powinna palić się ciągle dioda 1).
Czy mógłbym prosić o wytłumaczenie tej kwestii? Gdzie mogę znaleźć więcej informacji na temat tych wymaganych opóźnień pomiędzy zapisem a odczytem pinu?

Jeśli chodzi o rozwiązanie z if else, to nie mogę tak zrobić, gdyż chciałbym zapalać 4 diody (zwierając PC0-PC2; PC0-PC3; PC1-PC2; PC1-PC3), na razie zrobiłem 2 diody, aby zobaczyć czy w ogóle to działa (teraz, dzięki Waszej pomocy, działa).
Ostatecznie chciałbym wykorzystać ten program do obsługi klawiatury 16-przyciskowej. Będę musiał wykorzystać wszystkie 8 pinów portu C (4 wiersze i 4 kolumny na klawiaturze). Zobaczę jak mi to wyjdzie, najpierw tak samo jak teraz będę zapalać diody, a później coś z wyświetlaczem LED i LCD.

Na prawdę dziękuję wszystkim za pomoc, jeśli będę miał problem, to wiem gdzie prosić o pomoc.

//EDIT
Dodałem jeszcze fragment kodu, aby lampki gasły po odjęciu zworek. Teraz odpowiednie lampki palą się tylko gdy sa zwarte odpowiednie piny.
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: 12 wrz 2015, o 14:24 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 09 gru 2014
Posty: 1540
Pomógł: 269

topic814.html



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 12 wrz 2015, o 20:39 
Offline
Użytkownik

Dołączył(a): 18 lip 2014
Posty: 69
Pomógł: 0

Jeszcze trochę zminimalizowałem program, wrzucając wszystko do funkcji, w której są 2 pętle (jedna odpowiada za wiersze klawiatury, a druga za jej kolumny). Dzięki temu program działa zarówno dla klawiatur 2x2 jak i np. 4x4. Jedynie muszę jeszcze zautomatyzować ustawianie na początku portu C, aby nie trzeba było ręcznie go zmieniać dla różnych klawiatur (np. PORTC = 0b00000011 dla klawiatury 2x2, ale już dla klawiatury 4x4 PORTC = 0b00001111), musze do tego zrobić oddzielną funkcję.

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



@anshar - nie za bardzo niestety rozumiem algorytmu pod tym linkiem. Autor niepotrzebnie dodał też obsługę LCD i trochę się to miesza. Nie do końca wiem nawet, który fragment odpowiada za obsługę klawiatury, większość to LCD.



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