; **** Projekt PRZYCISK 3 **** ; ; PA0 = D1 (IN1) (IN1:IN4 MOZLIWY DO PODLACZENIA ULN2003 OD SILNIK KROKOWY) ; PA1 = D2 (IN2) ; PA2 = D3 (IN3) ; PA3 = D4 (IN4) ; ; PB0 = S1 (W1) ; PB1 = S5 (W2) ; PB2 = S9 (W3) ; ; PC0 = D6, PC1 = D7 w JP22 ; ; PD7 = KOLUMNA C1 ; PD6 = a od LED ; PD5 = d ; PD4 = e ; PD3 = f ; ; PD2 = OUT Z GRZYBKA AWARYJNEGO DO PRZERWANIE INT0 ; ; PD0 = g ; ; VCC, GND ZASILANIE GRZYBKA AWARYJNEGO ; ; maska RAMEND - adres zdefiniowany w pliku m32def.inc ; zaczynamy :D .include "m32def.inc" .def JEDEN = R16 .def DWA = R17 .def W1 = R18 .def W2 = R19 .def W3 = R20 ; * liczniki opoznienia .def licznik1 = R21 .def licznik2 = R22 .def licznik3 = R23 ; * rejest do obsulgi SRAM .def RAM1 = R24 .def RAM2 = R25 ; * rejestr do wpisywania cykli "Migania" .def CYKLE = R26 ; * przypisanie nazw zmiennym .equ zera = 0x00 .equ jedynki = 0xff .equ bit0 = 0b0000_0001 ; zmiena do testowania S1 .equ bit1 = 0b0000_0010 ; zmiena do testowania S5 .equ bit0i2 = 0b0000_0010 ; zmiena do testowania S9 z S1 jednoczesnie .cseg .org 0x0000 jmp Start nop nop Start: ; od razu aktywujemy STOS(!) ldi JEDEN, high(RAMEND) ; łaladuj rejestr roboczy MSB adresu konca pamieci SRAM out SPH, JEDEN ; inicjalizuj MSB wskaźnika stosu ldi JEDEN, low(RAMEND) ; laduj rejestr roboczy LSB adresu konca pamieci SRAM out SPL, JEDEN ; inicjalizuj LSB wskaźnika stosu ; STOS jest już zdefiniowany, miejsce na reszte programu ; ; miejsce na procedurę uruchamiajaca przerwanie INT0 ; ; przygotowanie słowa adresowego w rejestrze Y ldi YL, 0x00 ; ladowanie LSB rejestru Y ldi YH, 0x02 ; ladowanie MSB rejestru Y ; * konfiguracja działania portów ldi JEDEN, zera ldi DWA, jedynki out DDRA, DWA ldi JEDEN, 0b1111_1000 out DDRB, JEDEN ldi JEDEN, 0b0000_0011 out DDRC, JEDEN ; port C z diodami ldi CYKLE, 20 ldi RAM1, 0b0000_1000 ldi RAM2, 0b0000_0001 ;* tworzenie tabeli zmiennych programu ;* Zmienne_W1: st Y, RAM1 inc YL lsr RAM1 mov R3, YL breq Zmienne_W2 rjmp Zmienne_W1 ;* tworzenie tabeli zmiennych programu ;* Zmienne_W2: st Y, RAM2 inc YL lsl RAM2 mov R4, YL brhs Zmienne_W3 rjmp Zmienne_W2 ;* tworzenie tabeli zmiennych programu ;* Zmienne_W3: ldi RAM2, 0b0010_0001 st Y, RAM2 inc YL swap RAM2 st Y, RAM2 mov R5, YL rjmp Test_W1 ; * testowanie przycisku S1 Test_W1: ldi W1, bit0 out PORTB, W1 in W1, PINB ; tutaj warto zastanowić się nad wprowadzeniem dodatkowych warunków/procedur dla upewnienia się mikrosterownika, ; czy nie wciśnięto przy okazji S9? sbrs W1, 0 ; testowanie bitu nr 0 w W1, rjmp Zapal_L ; skok, jesli wcisnieto S1 rjmp Test_W2 ; skok, jesli nie wcisnieto S1 ; * testowanie przycisku S5 Test_W2: ldi W2, bit1 inc W2 out PORTB, W2 in W2, PINB sbrs W2, 1 ; testowanie bitu nr 1 rjmp Zapal_R ; skok, jesli wcisnieto S5 rjmp Test_W3 ; skok, jesli nie wcisnieto S5 ; * testowanie przycisku S9 z S1 Test_W3: ldi W3, 0b0000_0111 out PORTB, W3 nop ; moment na wcisniecie S9 z S1 nop ; przytrzymujemy in W3, PINB ; mamy to! nop ; mozna zwolnic switche nop cpi W3, bit0i2 breq Miganie ; skok, jesli wcisnieto jednocześnie S9 z S1 rjmp Test_W1 ; skok, jesli nie wcisnieto switchów ; * podprogram z procedura obslugi klawisza S1 Zapal_L: ldi JEDEN, jedynki OBROT_L: mov YL, R3 ld W1, -Y out PORTA, W1 ld W1, -Y out PORTA, W1 ld W1, -Y out PORTA, W1 ld W1, -Y out PORTA, W1 dec JEDEN brne OBROT_L clr W1 out PORTA, W1 rjmp Test_W1 ; powrot z podprogramu ; * podprogram z procedura obslugi klawisza S5 Zapal_R: ldi JEDEN, jedynki OBROT_R: mov YL, R4 ld W2, -Y out PORTA, W2 ld W2, -Y out PORTA, W2 ld W2, -Y out PORTA, W2 ld W2, -Y out PORTA, W2 dec JEDEN brne OBROT_R clr W2 out PORTA, W2 rjmp Test_W1 ; powrot z podprogramu ; * podprogram z procedura obslugi klawisza S9 z S1 jednoczesnie Miganie: mov YL, R5 ld W3, Y out PORTC, W3 ld W3, -Y out PORTC, W3 nop rol CYKLE brcc Miganie clr W3 out PORTC, W3 rjmp Start ; powrot z podprogramu ; * KONIEC PROGRAMU GLOWNEGO ; * podprogram Delay spowalniający (zajmujący) PC Delay: ldi licznik3, 100 Loop0: ldi licznik2, 50 Loop1: ldi licznik1, 20 Loop2: dec licznik1 brne Loop2 ; licznik1 = 0 (flaga Z = 0 w SREG, to powrot do dekrementacji) dec licznik2 ; brne Loop1 ; testowanie czy różne od 0 dec licznik3 ; brne Loop0 ; testowanie czy różne od 0 nop nop ### ; uzupełnij nazwą instrukcji powrotu z podprogramu do miejsca w programie z inztrukcja rcall, call lub icall ; * KONIEC DELAY ; PONIZEJ FRAGMENTY DO URUCHOMIENIA PRZERWANIA ;jmp Start ;.org INT0addr ; standardowa formula dotyczy uruchomienia obsługi przerwania zewnętrznego INT0 ;jmp przerwanie_INT0 ; przeniesienie do etykiety z procedura obslugi przerwania ;Start: ; miejsce na procedurę uruchamiajaca przerwanie INT0 ;in Jeden, MCUCR ; kopia rejestru MCUCR ;sbr Jeden, 1 << ISC00 ; reczna konfiguracja bitu ISC00 w INT0 na stan 0 i nie zmienia pozostałych bitow ;sbr Jeden, 1 << ISC01 ; reczna konfiguracja bitu ISC01 w INT0 na stan 1 i nie zmienia pozostałych bitow ;out MCUCR, Jeden ; ETAP I zrealizowany, teraz mamy juz zdefiniowane przerwanie, ; ktore będzie wywolywane sygnalem zbocza opadającego wywoływanego wcisnieciem wsitcha S13 ; uaktywnienie przerwania w rejestrze GICR: ;in Jeden, GICR ; główny rejestr kontroli przerwań ;sbr Jeden, 1 << INT0 ; reczne ustawienie bitu na 1 odpowiadajacego za odblokowanie ; zewnętrznego przerwania INT0 znajdujacego się pod adresem INT0addr ;out GICR, Jeden ; ETAP II, od teraz już tylko czekamy na zbocze opadajace, ktore ma pojawic sie na INT0 ;sei ; ETAP III, od teraz mamy aktywne przerwania zewnetrzne, bo flaga I w SREG jest ustawiona ; etykieta z petla testujaca stan przycisków na JP23 ; za Delayem wprowadz podprogram do obslugi przerwania przerwanie_INT0: in Jeden, SREG push Jeden push CYKLE ldi JEDEN, 0x08 ; LICZBA MIGANIA E Migaj_E: ldi W3, 0b1111_1011 out DDRD, W3 clr W3 out PORTD, W3 rcall Delay nop ldi W3, 0b1111_1011 out PORTD, W3 rcall Delay dec Jeden brne Migaj_E pop CYKLE pop JEDEN out SREG, Jeden reti