Aktyw Forum

Zarejestruj się na forum.ep.com.pl i zgłoś swój akces do Aktywu Forum. Jeśli jesteś już zarejestrowany wystarczy, że się zalogujesz.

Sprawdź punkty Zarejestruj się

Przerwania

xamrex
-
-
Posty: 10
Rejestracja: 9 paź 2010, o 15:44
Lokalizacja: kosmosu

Przerwania

Postautor: xamrex » 12 paź 2010, o 11:28

Zrobiłem sobie pod Attiny2313 wyświetlacz LED 7 segmentowy..

Chcę aby na początku była wyświetlona cyfra 0, po 0,5 sekudzie cyfra 1 , po następnej 0,5 sekundy cyfra 2 itd..

A jeśli zewrze pind.2 (bo tam jest INT) do masy, to chcę aby prędkość zmiany cyfr rosła,
Czyli, aby zmiana cyfry z 0 na 1 nie nastąpiła po upływie 0,5sek a po upływie 0,45 sek..

Mam taki kod:

Kod: Zaznacz cały

$regfile = "attiny2313.dat" 'najpierw określamy typ proca $crystal = 1000000 Config Portb = Output ' ustawienie całego Portu B jako wyjscia Portb = &B11111111 ' stan spoczynkowy wszystkich wyjsć ustawiony na 1 Config Portd = Input Portd = &B1111111 ' stan spoczynkowy wszystkich bitów ustawiony na 1 Dim Czas As Integer Czas = 500 On Int0 Czas Enable Interrupts Enable Int0 Do Gosub Zero Waitms Czas Gosub Jeden Waitms Czas Gosub Dwa Waitms Czas Gosub Trzy Waitms Czas Gosub Cztery Waitms Czas Gosub Piec Waitms Czas Gosub Szesc Waitms Czas Gosub Siedem Waitms Czas Gosub Osiem Waitms Czas Gosub Dziewiec Waitms Czas Loop Czas: ' jesli INT0 zewrze do masy wykonuje sie to: If Czas > 80 Then ' zablokowanie mniejszej szybkosci ni 80ms gdyz jesli jest ponizej 80ms nie widac ze zmieniaja sie liczby Czas = Czas - 1 ' gdy INT0 jest zwarty maleje czas o 1ms Waitms 10 End If Return End 'Cyferki Zero: Portb = &B11000000 Return Jeden: Portb = &B11111001 Return Dwa: Portb = &B10100100 Return Trzy: Portb = &B10110000 Return Cztery: Portb = &B10011001 Return Piec: Portb = &B10010010 Return Szesc: Portb = &B10000010 Return Siedem: Portb = &B11111000 Return Osiem: Portb = &B10000000 Return Dziewiec: Portb = &B10010000 Return
Już jest prawie cacy...
Opisze jak to działa..
Lecą sobie cyferki z 0,5sek opóźnieniem...
Gdy zewrze INT0 do masy to na wyświetlaczu zatrzymuje się jakaś cyfra, i gdy puszczę INT0, to leci od tej samej cyfry na której się zatrzymało tyle, że szybciej..

Niby cacy, ale chciałbym, że jeśli zewrze INT0 do masy, to aby cyferki dalej leciały (szybciej), a nie się zatrzymywały..

Dam filmik, żeby było wiadomo o co mi chodzi..
http://www.youtube.com/watch?v=B1-32UOTLXc

matrix
-
-
Posty: 342
Rejestracja: 7 maja 2010, o 14:02
Lokalizacja: Sochaczew
Kontaktowanie:

Postautor: matrix » 12 paź 2010, o 13:53

czemu robisz to na poleceniach waitms?
zaprzęgnij timer i po kłopocie. w chwili po zwarciu owego pinu do masy wpiszesz nową wartość do timera i problem zniknie.

zmiany na wyświetlaczu czyli zatrzymywanie się cyferek spowodowane jest skokiem do podprogramu czas
Ostatnio zmieniony 12 paź 2010, o 14:09 przez matrix, łącznie zmieniany 2 razy.

xamrex
-
-
Posty: 10
Rejestracja: 9 paź 2010, o 15:44
Lokalizacja: kosmosu

Postautor: xamrex » 12 paź 2010, o 13:59

zaprzęgnij timer i po kłopocie.
Mógłbyś wytłumaczyć co dokładniej powinienem zrobić

matrix
-
-
Posty: 342
Rejestracja: 7 maja 2010, o 14:02
Lokalizacja: Sochaczew
Kontaktowanie:

Postautor: matrix » 12 paź 2010, o 14:09

przy zegarze 8MHz ustaw:

config timer1=timer, prescaler=64
timer1=3036 ' załadowanie tej wartości wywoła przerwanie dokładnie co 500ms

po wywołaniu przerwania na INT0 załaduj do timera wartość 34286 co da przerwanie dokładnie co 250ms czyli dwa razy szybciej.

podałem Ci wszystko jak na tacy. zostało Ci napisanie softu jak należy.

zmianę cyferek na wyświetlaczu należy zaimplementować w procedurze wywoływanej przerwaniem od timera. ale niekoniecznie całość w tymże podprogramie.

można tam umieścić zmienną i zmieniać jej wartość a samo wyświetlanie umieścić gdzie indziej.
a, i samo przerwanie od INT0 trzeba ustawić na przykład na falling bo w przeciwnym razie będzie ono wywoływane cały czas co popsuje całą pracę Twojego urządzenia.

xamrex
-
-
Posty: 10
Rejestracja: 9 paź 2010, o 15:44
Lokalizacja: kosmosu

Postautor: xamrex » 12 paź 2010, o 20:41

Chyba już wiem co masz na myśli i co powinienem zrobić.
Najpierw zrobiłem sobie taki mały test.
Napisałem program:

Kod: Zaznacz cały

$regfile = "attiny2313.dat" 'najpierw określamy typ proca $crystal = 1000000 ' stan spoczynkowy wszystkich wyjsć ustawiony na 1 Config Portd = Output Config Portb = Output Portd = &B11111111 Portb = &B00000000 Config Timer1 = Timer , Prescale = 64 On Timer1 Sekunda On Int0 Mniejsek Enable Timer1 Enable Interrupts 'Enable Int0 Timer1 = 49911 Do Loop End Mniejsek: ' TO JEST TYLKO PO TO ŻEBY ZOBACZYĆ CZY JEŚLI ZROBIMY PRZERWANIE PORTB DOSTANIE STAN WYSOKI Portb = &B11111111 Return Sekunda: Timer1 = 49911 Toggle Portd Return
specjalnie za komentowałem 'Enable Int0....
Bo Teraz (gdy jest to za komentowane) to dioda sobie fajnie miga co 0,5sek (jest dołączona do portu PD.1)
Teraz tak jak mówiłeś muszę zrobić jakieś przerwanie.
Więc gdy od komentuję te 'Enable Int0 to program się sypie..

Mianowice dioda się włączy, po 0,5 sek zgaśnie i na porcie B będzie stan wysoki...

CO robię źle?

matrix
-
-
Posty: 342
Rejestracja: 7 maja 2010, o 14:02
Lokalizacja: Sochaczew
Kontaktowanie:

Postautor: matrix » 12 paź 2010, o 22:12

napisz tak tylko pozmieniaj piny bo ja korzystam z atmega8:

Kod: Zaznacz cały

Config Portd = Output config pinc.0 = input dim zmiana as bit przycisk alias pinc.0 set przycisk zmiana = 0 Portd = &B11111111 Config Timer1 = Timer , Prescale = 64 On Timer1 Sekunda Enable Timer1 Enable Interrupts Timer1 = 3036 Do if przycisk = 0 then toggle zmiana bitwait przycisk , set end if Loop End Sekunda: stop timer1 Toggle Portd if zmiana = 0 then timer1 = 3036 else timer1 = 34286 end if start timer1 Return
działa na bank przy zegarze 8MHz. rozkmiń sobie sam.
nieelegancko zastosowałem polecenie bitwait, ale w tak prostym programie nie ma to znaczenia. zamiast bitwait możesz napisać waitms 250

xamrex
-
-
Posty: 10
Rejestracja: 9 paź 2010, o 15:44
Lokalizacja: kosmosu

Postautor: xamrex » 13 paź 2010, o 14:49

My się chyba nie rozumiemy...
Ten kod co dałeś, to były tam tylko 2 możliwości migania diody
(timer1 = 3036
else
timer1 = 34286 )

Załączę może ten obrazek:
Obrazek

// Trzeba pozmieniać piny, w tym kodzie co dałeś ale sobie z tym poradzę..
Napiszę co chcę uzyskać..

Miga sobie ta dioda załóżmy co 500ms
Teraz jeśli nasz przycisk (pind.0) = 0 Dioda ma migać co 495ms,
Jeśli znowu pind.0 = 0 dioda ma migać co 490ms..
Jeśli znowu pind.0 = 0 dioda ma migać co 485ms..
Teraz załóżmy, że puściliśmy przycisk to dioda ma migać co 485ms ..

Jeśli trzymam kliknięty przycisk, to prędkość migania diody ma się zmieniać...

matrix
-
-
Posty: 342
Rejestracja: 7 maja 2010, o 14:02
Lokalizacja: Sochaczew
Kontaktowanie:

Postautor: matrix » 13 paź 2010, o 14:51

no to trzeba było tak od razu pisać.
obserwuj temat, dzisiaj wieczorem Ci napiszę kod, bo teraz nie mam czasu i edytuję ten post.

xamrex
-
-
Posty: 10
Rejestracja: 9 paź 2010, o 15:44
Lokalizacja: kosmosu

Postautor: xamrex » 13 paź 2010, o 14:58

Dzięki,
Tylko pamiętaj, że nie może być to realizowane za pomocą waitms np.

Kod: Zaznacz cały

Dim Czas As Integer Czas = 500 Do if pind.0 = 0 then Czas = Czas - 5 endif toggle port.b waitms Czas End
bo jeśli ten przycisk zwarłbym akurat w czasie kiedy procesor robi Waitms czas(np. 500)
to nic się nie stanie.. ;
Nie wykona wtedy polecanie Czas=Czas - 5
(mam nadzieję, że rozumiesz o co mi chodzi)

matrix
-
-
Posty: 342
Rejestracja: 7 maja 2010, o 14:02
Lokalizacja: Sochaczew
Kontaktowanie:

Postautor: matrix » 13 paź 2010, o 16:37

jak pisałem wyżej, pozmieniaj sobie piny. masz 13 kroków, krok co 5ms od wartości 0,5sek. po 13 kroku dioda będzie migać na powrót co 0,5sek.

Kod: Zaznacz cały

$crystal = 8000000 Config Portd = Output config pinc.0 = input dim wartosc_x as word przycisk alias pinc.0 set przycisk Portd = &B11111111 Config Timer1 = Timer , Prescale = 256 On Timer1 Sekunda Enable Timer1 Enable Interrupts wartosc_x = 9286 Do if wartosc_x <= 536 then wartosc_x = 9286 end if if przycisk = 0 then wartosc_x = wartosc_x - 625 waitms 250 end if Loop End Sekunda: stop timer1 Toggle Portd load timer1 , wartosc_x start timer1 Return

xamrex
-
-
Posty: 10
Rejestracja: 9 paź 2010, o 15:44
Lokalizacja: kosmosu

Postautor: xamrex » 13 paź 2010, o 17:41

Mógłbyś jeszcze napisać jak wyliczyłeś wartość
9286

matrix
-
-
Posty: 342
Rejestracja: 7 maja 2010, o 14:02
Lokalizacja: Sochaczew
Kontaktowanie:

Postautor: matrix » 13 paź 2010, o 18:42

jeżeli przy konfiguracji timera

Kod: Zaznacz cały

Config Timer1 = Timer , Prescale = 256
i częstotliwości zegara 8MHz wartość 3036 odpowiada pół sekundzie a każda zmiana wartości odmierzanego czasu o 5ms to wartość timera 625, to wystarczy prosta matematyka (mnożenie i dodawanie) i uzyskasz wartość o którą pytasz.

a w ogóle do wyliczania wartości przerwań ściągnij sobie z załącznika avr kalkulator. mam nadzieję że autor nie pogniewa się, ale nie mogę teraz znaleźć skąd go pobrałem. na pewno jest freeware.
Załączniki
kalk.zip
(131.05 KiB) Pobrany 385 razy

xamrex
-
-
Posty: 10
Rejestracja: 9 paź 2010, o 15:44
Lokalizacja: kosmosu

Postautor: xamrex » 13 paź 2010, o 18:55

dzieki!!

Wróć do „Projektowanie PCB, programy EDA, CAD, narzędziowe”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 82 gości