logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[asm]Kilka pytań i prośba o sprawdzenie programu i schematu

Cataclysm 22 Gru 2009 14:51 2026 5
REKLAMA
  • #1 7422360
    Cataclysm
    Poziom 10  
    Witam, mam kilka pytań dotyczących asemblera pod avr i nie tylko.

    Dlaczego nie mogę się odwoływać do rejestrów poniżej 15 np r1 przez instrukcję ldi?
    Czy ustawienie pinu jako wejście z pull-up'em oznacza że jego stan początkowy równy jest 1?
    Ze wszystkich pinów mogę korzystać normalnie jeśli w odpowiednich rejestrach nie ustawie bitów odpowiedzialnych za ich inne funkcje(np. ADC, int0 itd.)?
    Jak wygląda definiowanie zmiennych?

    Oto schemat i program do sprawdzenia. Mam wątpliwości co do microswitchy i ustawień pinu jako wejście, a także przerwania INT0
    .nolist
    .include "m8def.inc"
    .list
    .listmac
    
    
    .cseg
    .org 0
    
    
    rjmp start			;skok do początku programu
    
    ;przerwania
    .org 	INT0addr 	; Przerwanie zewnętrzne int0 (microswitch)
    rjmp microswitch	; Skok do procedury przerwania
    .org 	INT1addr 	; Przerwanie zewnętrzne int1
    reti 	  	
    .org 	ICP1addr 	; Input Capture1 Interrupt
    reti 	  
    .org 	OVF0addr 	; Przerwanie przepełnienia timer0
    reti 	
    .org 	OVF1addr 	; Przerwanie przepełnienia timer1
    reti
    .org 	URXCaddr 	; UART Receive Complete
    reti 	
    .org 	UDREaddr 	; UART Data Register Empty
    reti 	 
    .org 	UTXCaddr 	; UART Transmit Complete
    reti 
    .org 	ACIaddr 	; Analog Comparator
    reti 	  
    
    start:
    	cli							;wyłaczenie przerwań na czas ustawiania proca
    
    	ldi  	r16, LOW(RAMEND)  	;załadowanie do rejestru r16 polowy stalej konca stosu
      	out 	SPL, r16 			;zapisania polowy konca stosu
      	ldi 	r16, HIGH(RAMEND) 	;załadowania do rejestru r16 2 polowy stalej konca stosu
      	out 	SPH, r16 			;zapisanie 2 polowy konca stosu
    	
    	ldi 	r16, 1				;załadowanie 0b00000001
    	out 	DDRB, r16			;ustawienie PB0 jako wyjście, reszta jako wejscia
    	out 	PORTB, r16			;w stanie wysokim
    	ldi		r16, 128			;załadowanie 0b10000000
    	out 	DDRD, r16			;ustawienie PD7 jako wyjście
    	ldi		r16, 192
    	out 	PORTD, r16			;w stanie wysokim PD7, z pullupem PD6
    	
    	ldi		r16, 64         	;ustawienie bitu odpowiedzialnego za akceptcję
       	out	    GICR, r16          	;przerwania INT0 w rejestrze GIMSK 
    	ldi	    r16, 0         		;poziom niski sygnału na INT0 będzie
       	out    	MCUCR, r16         	;generowac przerwanie 
    	
    	sei							;włączenie przerwań
    	
    	
    mainloop:
    	in		r16, PIND			;do PD6 i PD2 microswitche, na PD2 jako przerwanie int0
    	ldi 	r20, 64				;ustawienie bitu 6 w r20
    	and		r16, r20			;wyizolowanie bitu 6 (PD6)
    	ldi		r20, 0
    	cpse	r16, r20			;jezeli jest rowny 0(wcisniety, zwarty do masy) opusc nastepna instrukcje
    	rjmp 	mainloop			;petla
    	;jesli 0 czyli microswitch wcisniety
    	in		r16, PORTB			;wczytaj jak jest ustawiona dioda na PB0
    	ldi 	r20, 1
    	and		r16, r20			;izoluj bit 0
    	cpse	r16, r20			;jesli jest jeden
    	rjmp ustaw					;wyzeruj bit 7 portu d
    	;jesli nie to
    	cbi		PORTB, 0			;zeruj bit 7 portu d	
    	rjmp 	mainloop			;petla
    	ustaw:
    	sbi		PORTB, 0			;ustaw
    	rjmp 	mainloop			;powrot
    
    
    microswitch:					;przerwanie od przycisku, zmieniajacy stan diody na PD7
    	in		r2, PORTD			;wczytaj jak jest ustawiona
    	ldi 	r19, 128
    	and		r2, r19				;izoluj bit 7
    	cpse	r2, r19				;jesli jest jeden
    	rjmp ustaw2
    	;jesli nie to
    	cbi		PORTD, 7			;zeruj bit 7 portu d
    	reti						;powrót z przerwania
    	ustaw2:
    	sbi		PORTD, 7			;ustaw bit 7 portu d
    	reti						;powrót z przerwania
    

    [asm]Kilka pytań i prośba o sprawdzenie programu i schematu

    Za wytykanie czytelności kodu//schematu także będę wdzięczny.
  • REKLAMA
  • Pomocny post
    #2 7422419
    tmf
    VIP Zasłużony dla elektroda
    LDI operuje tylko na rejestrach R16-R31, tak juz jest. Ustawienie pull upa znaczy tylko tyle, ze odczytasz '1' o ile do pinu nie bedzie podlaczony sygnal wymuszajacy inny poziom. Dopoki nie wykorzystujesz innych peryferii piny sa po prostu portami IO (z malym wyjatkiem - pinow na ktorych jest JTAG - JTAG jest domyslnie wlaczony i musisz go wylaczyc przed wykorzystaniem tych pinow; ale nie wszytkie procesory JTAG maja - ATMega8 nie ma).
    Na schemacie switche masz podlaczone ok, ustawione tez. Z ta tylko uwaga, ze switche jako elementy mechaniczne przy przelaczaniu drgaja generujac raczej serie impulsow. Stad musisz ten sygnal filtrowac - analogowo (kondensator) lub cyfrowo.
    BTW, nie prosciej ci to napisac w C?
  • REKLAMA
  • #3 7422464
    Cataclysm
    Poziom 10  
    Może i prościej ale chcę się nauczyć asemblera, na komputer programuje w C++ więc z C jak będzie mi potrzebne problemu nie będzie ;)
    Kondensator równolegle do switcha, jakaś konkretna wartość? Z tym ustawianiem wejść miałem problem bo na symulatorze nie działo się tak jak opisujesz.
    To w jaki sposób mogę załadować dane do tych rejestrów?
    I jeszcze: jak wygląda definiowanie zmiennych?
  • REKLAMA
  • Pomocny post
    #4 7423768
    tmf
    VIP Zasłużony dla elektroda
    Kondensator mozesz tak dac, chociaz pewnie ciekawszym rozwiazaniem jest zrobienie takiego filtra programowo. Symulator drgan przycisku ci nie zasymuluje, stad klopod z takim programem. Co do rejestrow R0-R15 to mozesz je zerowac, ustawiac (255), ale nie mozesz bezposrednio wpisywac innych wartosci. Zeby to zrobic potrzebujesz ciagu instrukcji, np:
    LDI R16,34
    MOV R1,R16
    Rejestry R0-R15 sa specyficzne, a R0 i R1 jeszcze bardziej :)
    Zmienne definiujesz poprzez dyrektywy .DB i pochodne, np:
    zmienna: .DB 0
  • REKLAMA
  • Pomocny post
    #5 7425210
    grysek
    Poziom 19  
    Na rejestrach r0 - r15 nie można wykonywać żadnej instrukcji która wykonuje jakąś operację (np dodawania) rejestru ze stałą. Czyli tak samo nie uda Ci się np. cpi, andi itd.. Natomiast wszystkie inne opracje możesz wykonywać na tych rejestrach
    Pozdrawiam :D
  • Pomocny post
    #6 7430164
    asembler
    Poziom 32  
    Standardową procedurą jest zachowanie na stosie lub w dowolnym rejestrze nie uzywanym nigdzie indziej wartosci rejestru statusu (SREG) i odtworzenie tej wartosci tuz przed wyjsciem z przerwania RETI. W innym przypadku nie masz żadnej kontroli nad programem głownym. Zeby nauczyc sie dobrze programwac w aseblerze oprocz znajomosci mnemoników miedzy innymi musisz tez wykuć na pamieć ktore z rozkazów powoduja zmiany w rejestrze SREG
REKLAMA