Uživatel:Madrvojt

Z MAM wiki

Přejít na: navigace, hledání

Obsah

[editovat] Procesor ATtiny2313

Soubor:ATtiny2313.png

[editovat] Příklad 1 - Ledka

[editovat] Popis

Blikající LED

[editovat] Zdroják


        .EQU DDRB = $17		; DDRB odkaz na konfiguracní registr (Nastaveni portu I/O)
	.EQU PORTB = $18	; PORTB odkaz na konfiguracní registr (Hodnota na danem portu)

	.EQU LED_X = 3		; LED_X is on PB0, pin 12 of ATtiny2313


	 SBI	DDRB, LED_X	; SBI - Nastavi dany port jako vystupni
;**************************************************************************
HOP:                            ; Deklarace návěští
	SBI	PORTB, LED_X    ; Nastavi 1 na danem portu
	RCALL WAIT              ; Volani podprogramu
	CBI	PORTB, LED_X    ; Nastavi 0 na danem portu
	RCALL WAIT              ; Volani podprogramu
	RJMP HOP                ; Skok na návěští

WAIT:
	LDI	R16, 4
WAIT1:	INC	R1
	BRNE	WAIT1
	INC	R2
	BRNE	WAIT1
	DEC	R16
	BRNE	WAIT1
	RET
				; RET - Return from Subroutine


[editovat] Příklad 2 - Dvoubarevná LED

[editovat] Popis

Antiparalelní dvojbarevná LED bliká zeleně nebo červeně

[editovat] Zdroják


	.EQU DDRB = $17		; DDRB odkaz na konfiguracní registr (Nastaveni portu I/O)
	.EQU PORTB = $18	; PORTB odkaz na konfiguracní registr (Nastaveni hodnoty na danem portu)
	.EQU PIND = $10         ; PIND odkaz na konfiguracní registr (Hodnota na danem portu)

	.EQU DDRD = $11         ; DDRD odkaz na konfiguracní registr (Nastaveni portu I/O)
	.EQU PORTD = $12

	.EQU LED_X=1
	.EQU LED_Y=0
        .EQU TLAC=5

	SBI	DDRB, LED_X     ; NASTAVENI PB1 JAKO VYSTUP
	SBI	DDRB, LED_Y	; NASTAVENI PB0 JAKO VYSTUP

	CBI DDRD, TLAC	        ; NASTAVENI PD5 JAKO VSTUP
	SBI PORTD, TLAC	        ; ZAPNUTI PULL UP RESISTORU NA PD5

;************************************

BLIK:
	SBIS PIND, TLAC         ; Jeli hodnota PIND 1 pak přeskoč instrukci
	RJMP HOP1               ; Skok na návěstí HOP1
	SBIC PIND, TLAC         ; Jeli hodnota PIND 0 pak přeskoč instrukci
	RJMP HOP2               ; Skok na návěstí HOP2
HOP1:
	RCALL ZELENA
	RJMP BLIK
HOP2:
	RCALL CERVENA
	RJMP BLIK


CERVENA:                        ; Cervené blikání
	SBI PORTB, LED_X        ; 1
	CBI PORTB, LED_Y        ; 0
	RCALL WAIT
	SBI PORTB, LED_X        ; 1
	SBI PORTB, LED_Y        ; 1
	RCALL WAIT
RET

ZELENA:                         ; Zelené blikání
	CBI PORTB, LED_X        ; 0
	SBI PORTB, LED_Y        ; 1
	RCALL WAIT
	SBI PORTB, LED_X        ; 1
	SBI PORTB, LED_Y        ; 1
	RCALL WAIT
RET


WAIT:
	LDI	R16, 4
WAIT1:	INC	R1
	BRNE	WAIT1
	INC	R2
	BRNE	WAIT1
	DEC	R16
	BRNE	WAIT1
	RET


[editovat] Příklad 3 - Klávesnice

[editovat] Popis

Při stisku tlačítka 1 resp. 5 svítí dvojbarevná LED zeleně resp. červeně

[editovat] Zdroják


.EQU DDRB = $17		; DDRB odkaz na konfiguracní registr (Nastaveni portu I/O)
	.EQU PORTB = $18	; PORTB odkaz na konfiguracní registr (Nastaveni hodnoty na danem portu)
	.EQU PINB = $16       

	.EQU DDRD = $11         ; DDRD odkaz na konfiguracní registr (Nastaveni portu I/O)
	.EQU PORTD = $12

	.EQU PD0=0
	.EQU PD1=1
	.EQU PD2=2
	.EQU PD3=3


	.EQU PB0=0
	.EQU PB1=1
	.EQU PB2=2
	.EQU PB3=3
	
	.EQU PB6=6
	.EQU PB7=7


	SBI	DDRB, PB6       ; Nastavení portu PB6 jako vystup
	SBI	DDRB, PB7       ; Nastavení portu PB7 jako vystup


	CBI	DDRD, PD0       ;Porty D vstupní
	CBI	DDRD, PD1
	CBI	DDRD, PD2
	CBI	DDRD, PD3

	CBI PORTD, PD0          ;Bez pull up resistoru
	CBI PORTD, PD1
	CBI PORTD, PD2
	CBI PORTD, PD3

        CBI	DDRB, PB0       ;Porty D vstupni
	CBI	DDRB, PB1
	CBI	DDRB, PB2
	CBI	DDRB, PB3

	SBI PORTB, PB0          ;Pull up resistory
	SBI PORTB, PB1
	SBI PORTB, PB2
	SBI PORTB, PB3


;*******************************************
MAIN:
	RCALL ROW1
	SBIS PINB, PB0
	RCALL CERVENA
	
	RCALL ROW2
	SBIS PINB, PB1
	RCALL ZELENA



RJMP MAIN

ROW1:
	SBI DDRD, PD0       ;Port PD0 vystup
	CBI PORTD, PD0      ;0 na portu PD0
	CBI DDRD, PD1       ;Ostatni vstupni (Stav velke impedance)
	CBI DDRD, PD2
	CBI DDRD, PD3
RET

ROW2:
	CBI DDRD, PD0
	SBI DDRD, PD1
	CBI PORTD, PD1
	CBI DDRD, PD2
	CBI DDRD, PD3
RET

ROW3:
	CBI DDRD, PD0
	CBI DDRD, PD1
	SBI DDRD, PD2
	CBI PORTD, PD2
	CBI DDRD, PD3
RET

ROW4:
	CBI DDRD, PD0
	CBI DDRD, PD1
	CBI DDRD, PD2
	SBI DDRD, PD3
	CBI PORTD, PD3
RET

ZELENA:
	CBI PORTB, PB6
	SBI PORTB, PB7 
RET

CERVENA:
	SBI PORTB, PB6
	CBI PORTB, PB7 
RET


[editovat] Příklad 4 - Větráček

[editovat] Popis

Při stisku tlačítka 1 na klávesnici běh naplno (3 je vypnutý a při stisku 2).

[editovat] Zdroják


         EQU DDRB = $17		; DDRB odkaz na konfiguracní registr (Nastaveni portu I/O)
	.EQU PORTB = $18	; PORTB odkaz na konfiguracní registr (Nastaveni hodnoty na danem portu)
	.EQU PINB = $16       

	.EQU DDRD = $11         ; DDRD odkaz na konfiguracní registr (Nastaveni portu I/O)
	.EQU PORTD = $12

	.EQU PD0=0
	.EQU PD1=1
	.EQU PD2=2
	.EQU PD3=3


	.EQU PB0=0
	.EQU PB1=1
	.EQU PB2=2
	.EQU PB3=3
	
	.EQU PB7=7



	SBI	DDRB, PB7       ; Nastavení portu PB7 jako vystup


	CBI	DDRD, PD0       ;Porty D vstupní
	CBI	DDRD, PD1
	CBI	DDRD, PD2
	CBI	DDRD, PD3

	CBI PORTD, PD0          ;Bez pull up resistoru
	CBI PORTD, PD1
	CBI PORTD, PD2
	CBI PORTD, PD3

        CBI	DDRB, PB0       ;Porty D vstupni
	CBI	DDRB, PB1
	CBI	DDRB, PB2
	CBI	DDRB, PB3

	SBI PORTB, PB0          ;Pull up resistory
	SBI PORTB, PB1
	SBI PORTB, PB2
	SBI PORTB, PB3


;*******************************************
MAIN:
	RCALL ROW1
	SBIS PINB, PB0
	RCALL PLNA

	RCALL ROW1
	SBIS PINB, PB1
	RCALL PULKA
	
	RCALL ROW1
	SBIS PINB, PB2
	RCALL VYP


RJMP MAIN

ROW1:
	SBI DDRD, PD0       ;Port PD0 vystup
	CBI PORTD, PD0      ;0 na portu PD0
	CBI DDRD, PD1       ;Ostatni vstupni (Stav velke impedance)
	CBI DDRD, PD2
	CBI DDRD, PD3
RET

ROW2:
	CBI DDRD, PD0
	SBI DDRD, PD1
	CBI PORTD, PD1
	CBI DDRD, PD2
	CBI DDRD, PD3
RET

ROW3:
	CBI DDRD, PD0
	CBI DDRD, PD1
	SBI DDRD, PD2
	CBI PORTD, PD2
	CBI DDRD, PD3
RET

ROW4:
	CBI DDRD, PD0
	CBI DDRD, PD1
	CBI DDRD, PD2
	SBI DDRD, PD3
	CBI PORTD, PD3
RET

PLNA:
	SBI PORTB, PB7
RET

VYP:
	CBI PORTB, PB7
RET

PULKA:
	SBI PORTB, PB7
	RCALL VERYSMALLWAIT
	RCALL VERYSMALLWAIT
	CBI PORTB, PB7
	RCALL VERYSMALLWAIT
	RCALL VERYSMALLWAIT
	RCALL VERYSMALLWAIT
	RCALL VERYSMALLWAIT
	RCALL VERYSMALLWAIT


	SBIS PINB, PB0
	RCALL MAIN

	SBIS PINB, PB2
	RCALL MAIN


RJMP PULKA

VERYSMALLWAIT:
	LDI R20, 0xFC
	MOV R1, R20
RET


[editovat] Domácí úkol 1 - Snad funkční

[editovat] Popis

Zvolte vhodné zapojení a procesor a v assembleru naprogramujte 2 na sobě nezávislé PWM regulace osvětlení do auta. Jedna je pro vnitřní osvětlení, po sepnutí dveřního kontaktu nastaví okamžitě plný svit, po rozpojení ještě asi 5 s plný svit a následuje asi 2 sekundy dosvit s poklesem od maxima do nuly, druhá PWM je pro regulované osvětlení palubní desky, vstup potenciometr, výstup výkonová PWM regulace asi 10 % až 100 %. Napájecí napětí auta je 12 V, špičky rušení mohou dosáhnout až 20 V.


[editovat] Komentář

TMR0 a TMR2 zajišťují osvětlení jak interiéru, tak palubní desky. TMR - kontroluje přerušení programu. Program je tvořen několika podprogramy, které se zabývají převodem analogového napětí na digitální, kontrolou opakování cyklu (Jde vypnout pomocí tlačítka) atd. Pro tvoření jsem využil připravený program z PWM a dalších programu, které jsem nalezl na MAM wiki. Snažil jsem se co nejvíce popsat funkci každého příkazu.

Společná práce s Lukášem Němcem[1]

[editovat] Zdroják


.nolist
.include "m88def.inc"
.list


;*******************************************************
;inicializace

.equ 	Svetlo = 5				; vnitřní osvětleni na PD5
.equ 	Palubka = 3				; palubka na PD3
.equ 	Nulováni = 0 				
.equ 	Tlacitko = 5				; spinání na zemi vůci vnitřnimu PULL-UP resistoru

.equ 	P_TMR1 = 0				; kontrola přerušení TRM1
.equ 	P_Int_Sviti = 1				; kontrola svitu světla
.equ 	P_Druhy_Cykl = 2			; kontrola druhého cyklu citani
.equ 	P_Stmivani = 3				; kontrola zhasínání 2s

.equ 	Pwm_Pulses_Int = 40			; 25 kHz ( interier )
.equ 	Pwm_Pulses_Pal = 36			; 27,8kHz ( osvetleni palubi desky )


;registry

.def 	Temp = r16				; docasny registr
.def 	Priznaky = r17				; uchovani priznaku
.def 	Pwm_Value_Int = r18			; PWM (osvetleni interieru)
.def 	Pwm_Value_Pal = r19			; PWM (pro palubni desku)
.def 	Casovac1 = r0				; osvetlení interieru
.def 	Casovac2 = r1				; zhasinani behem 2s
	

;resetovaci vektory

.org 0x000 
	rjmp 	Start 				; resetování
.org 0x00D
	rjmp 	Tim1_Ovf			; přerušení při přetečení

;**************************************************************************

;program

Start:

;Příprava zásobníku

	ldi 	Temp,high(RAMEND)		 
	out 	SPH, Temp			
	ldi 	Temp,low(RAMEND)		
	out 	SPL, Temp			


;Inicializace portu

	ldi	Temp, 0b011110			; PC0 je vstup ADC a PC5 je vstup pro tlacitko
	out	DDRC, Temp			
	ldi	Temp, 0b100000			; vystupy do 0 a interni pull-up pro PC5
	out	PORTC, Temp			
	ser	Temp				; PORTD a PORTB jako vystupy (implicitne v 0)
	out	DDRD, Temp			
	out	DDRB, Temp			
	clr	Temp				; PORTD a PORTB jsou vsechny v 0
	out	PORTB, Temp			; celý port B výstup v L
	out	PORTD, Temp			; celý port D výstup v L

;***********************************************************************************

;TMR0 - osvětleni interiéru

	ldi 	Temp, 0b00100011		; rychlá PWM, výstup na PD5, neinvertující
	out 	TCCR0A, Temp			; Time counter control register
	ldi 	Temp, 0b00001001		; rychlá PWM, vnitřní hodiny, prescale = 1
	out 	TCCR0B, Temp
	ldi 	Temp, Pwm_Pulses_Int		; počet hodinových pulzů na jednu PWM periodu
	out 	OCR0A, Temp

;***********************************************************************************
;Při nastavené nulové střídě se na výstupu PWM objevuje zakmit, to znamená, když se nesvítí,
;je vystup generátoru odpojen a připojen jako obyčejný vystup v 0. Před rozsvícením světla
;je potřeba ho opět připojit (viz. Tlačítko) a po zhasnuti odpojit (viz. Stmíváni).
;***********************************************************************************	

        in	Temp, TCCR0A			; odpojeni výstupu od PWM generátoru 
	cbr	Temp, 0x10			; CLEAR BIT in Register
	out	TCCR0A, Temp			; out = nastavení IN PORT

;***********************************************************************************

;TMR2 - osvětlení palubní desky

;***********************************************************************************
;Stejné nastavení jako u TMR0, jiný způsob (nejsou dostupné registry pomoci "out")
;U palubní desky není třeba vystup generátoru odpojovat, protože minimální střída má byt 10%	
;************************************************************************************     


        ldi	Temp, 0b00100011		; rychlá PWM, výstup na OC0B (PD5), neinvertující
	sts	TCCR2A	, Temp			; Time counter control register
	ldi	Temp, 0b00001001		; rychlá PWM, vnitřní hodiny, prescale = 1
	sts	TCCR2B, Temp			
	ldi	Temp, Pwm_Pulses_Pal            ; počet hodinových pulzů na jednu PWM periodu
	sts	OCR2A, Temp			 



;inicializace ADC
			
	ldi	Temp, 0b11100000		; interní 1.1 V reference s kapacitou na pinu AREF (Zarovnání výsledku vlevo a vstup na ADC0)
	sts	ADMUX, Temp			; Store Direct = ulož do RAM
	ldi	Temp, 0b10000100		; ADC "zapnut", int. off, autotriger off, dělící poměr 16 (tj. 62,5kHz)
	sts	ADCSRA, Temp			; ADC controlní a postavení registru A
	clr	Temp				; Autotriger zdroj -> Autotriger je vypnutý
	sts	ADCSRB, Temp			
	ldi	Temp, 0x01			; disable digital input buffer for pin ADC0 (snizeni spotreby)
	sts	DIDR0, Temp			; Digitální vstupní rušící registr


;inicializace přerušeni od TMR1
;registry pro TMR1 nejsou v rozsahu instrukce "out"

	
        ldi	Temp, 0xD8			; zkrácení čítáni TMR1 na 10000 (10E+4 * 1us = 10ms); 10000dec=2710hex
	sts	TCNT1H, Temp			
	ldi	Temp, 0xF0			
	sts	TCNT1L, Temp			
	clr	Temp				; vynulování TCCR1A
	sts	TCCR1A, Temp			
	ldi	Temp, 0b00000001		; Clock Select -> CLKio/1 (no prescaler)
	sts	TCCR1B, Temp			
	sts	TIMSK1, Temp			; Timer1 Overflow Interruption enabled
	
        sei					; Povolení přerušení, Set interrupt flag		
	

	clr	Temp				; Vynulovani hodnoty Casovac2, další nulování už v programu
	mov	Casovac2, Temp			

;**************************************************************************************

;hlavní smyčka

Main:
	sbrs  	Priznaky, P_TMR1		; nastalo přerušení od TMR1?
	rjmp  	Preruseni_TMR1		        ; pokud ne, přeskočit testovaní tlacítka a ADC, hodnoty PWM se pak nemění
	clt					; pokud ano, zruš přiznak přerušení od TMR1 pro příště (CLEAR T-FLAG)
	bld	Priznaky, P_TMR1		; BIT LOAD FROM REGISTER to T
        rcall 	Tlacitko			; Testování tlačítka, jestli je stisknuté
        sbrc  	Priznaky, P_Int_Sviti		; Svítí interiér ( SKIP if register set)
	rcall 	Hlidej_Cas			; Dekrementace hodnoty Casovac, popřípadě regulace jasu
	out   	OCR0B, Pwm_Value_Int		; Nastavení PWM interieroveho svetla dle aktualni hodnoty
	rcall 	AD_Prevod			; Zjistění paměti podle potenciometru
	rcall 	Dekod_AD			; Jeho úprava pro použití PWM
	sts	OCR2B, Pwm_Value_Pal		; Nastavení podle aktuální hodnoty

Prerusení_TMR1:

;uspání procesoru ? Bylo by to asi možné, protože i TRM 1 je uspané!
	
	rjmp	Main

;**************************************************************************************

;Podprogram pro testovaní tlačítka

Tlacitko:
	
        sbic 	PINC, Tlac			; Kontrola stisku
	rjmp 	Neni_Stisk			; Pokud ne, ukončí kontrolu

;Rozsvícení a inicializace časovače
	
        set					; nastav příznak, ze interier svítí
	bld	Priznaky, P_Int_Sviti		
	ldi	Pwm_Value_Int, Pwm_Pulses_Int	; do hodnoty PWM se uloží maximální svit
	in	Temp, TCCR0A			; připojení výstupu k PWM generátoru
	set					
	bld	Temp, 5				
	out	TCCR0A, Temp		
	ldi	Temp, 0xFF			; uložení hodnoty 255
	mov	Casovac, Temp			
	clt					; vynulování příznaku když:
	bld	Priznaky, P_Druhy_Cykl 		; Nedoslo k jednomu procítaní registru Casovac
	bld 	Priznaky, P_Stmivani		; Jestě neprobíhá proces stmívaní

Neni_Stisk:
	ret                                     ; návrat


;Dekrementování Časovače

;****************************************************************************************
;Kvůli délce 7s je nutnost počítat do 700, náš registr Casovac čítá od 0 - 255, 
;poté nastaví příznak P_Druhy_Cykl a registr Casovac znovu. Následně se 20x odčítají od hodnot PWM, dokud nenastane 0.
;****************************************************************************************


Hlidej_Cas:
	
        sbrc 	Priznaky, P_Stmivani		; Kontrola procesu stmívání
	rjmp 	Stmivani			; ANO, povolený průchod dál
	dec	Casovac				; NE, dekrementace časovače
	brne 	Konec_Hlidej_Cas 		; Pokud není nula = konec
	sbrc 	Priznaky, P_Druhy_Cykl		; Pokud je nule, kontrola spustění druhého cyklu
	rjmp 	Nastav_Stmivani			; ANO, skončení 5s plného svitu a začátek stmívání
	set					; NE, časovač jede znovu
	bld	Priznaky, P_Druhy_Cykl		
	rjmp 	Konec_Hlidej_Cas		; Ukončení procesu


Nastav_Stmivani:



;Příznak, který nastavuje, že cyklus běží po druhé. Je ho poté možné zrušit při příštím stisku tlačítka
       
        set					; Okamžité nastavení stmívání
	bld	Priznaky, P_Stmivani				

Stmivani: 
	inc	Casovac2			; Zvýší hodnotu Casovac2, z 10 na 100 ms
	mov	Temp, Casovac2			; Casovac2 nejde porovnat primo instrukci CPI (r1)
	cpi	Temp, 0x0A			; 10s testování
	brne 	Konec_Hlidej_cas		; Pokud se nastaví, vše ok
	clr	Temp				; Pokud se nanastaví, dalších 10s
	mov	Casovac2, Temp			
	subi 	Pwm_Value_Int, 0x02		; odečtení hodnoty 2 z aktuálního svitu
	tst	Pwm_Value_Int			; Testování, zda je nastavená 0
	brne 	Konec_Hlidej_cas		; Pokud NE, vše OK
	clt					; Pokud ANO, interiér je vypnutý
	bld	Priznaky, P_Int_Sviti		


;Příznak, který zruší stmívání při dalším stisku tlačítka

	
        in	Temp, TCCR0A			; Odpojeni výstupu od PWM generátoru ( Standardní výstup je v 0)
	clt					
	bld	Temp, 5 			; Nulování 5tého bitu
	out	TCCR0A, Temp		

Konec_Hlidej_Cas:
	
        ret                                     ; Návrat


;Převod ADC (analog) napětí na digitální.

;******************************************************************************************
;Dokud na ADCSRA nastaven 6 bit, převod trvá.
;******************************************************************************************

AD_Prevod:
	clr	Temp				; Smazání předchozího výpočtu
	sts	ADCH, Temp			

	lds	Temp, ADCSRA			; Kopírování ADCSRA do registru Temp
	set					; Nastavení 6tého bitu (tj. začátek AD převodu)
	bld	Temp, 6				
	sts	ADCSRA, Temp			; Ukládání nazpět (Skutečný začátek převodu)


Probiha_ADC:
	
        lds	Temp, ADCSRA			; Kopírování ADCSRA do Temp
	sbrc 	Temp, 6				; Zkoumání nastavení ADCH
	rjmp 	Probiha_ADC			; Nastaven, trvání čekání
	ret					; Nenastaven, konec převodu (Výsledek je v ADCH, tím pádem nás ADCL nezajímá)



;Převod hodnoty z ADC do intervalu 10 - 100% (Použití v PWM)

;**********************************************************************************************
;Maximální hodnota PWM je 36. Pokud maximální hodnota z AD převodníku je 255, tak po vyděleni osmi je zaokrouhleně 31.
;Při přičtení 4 máme tedy 35.
;Maximální střída je tímto 97%, minimální je v intervalu ADCH od 0 do 7, kdy je výsledek rovný čtyřem 11%. 
;************************************************************************************************

Dekod_AD:
	lds	Temp, ADCH			; hodnotu H bytu z AD prevodu do Temp
	lsr 	Temp				; lsr - dělí hodnotu 2 (Logical Shift Right)
	lsr 	Temp				
	lsr	Temp				
	mov	Pwm_Value_Pal, Temp		; hodnota ADCH/8 do Pwm_Value_Pal
	ldi	Temp, 0x04
	add	Pwm_Value_Pal, Temp		; přičte k Pwm_Value_Pal 4

;Uloží hodnotu do Pwm_Value_Pal
	
        ret


;podfunkce přerušení

Tim1_Ovf:

;využití zásobníku

	push 	Temp				; uloženi hodnot promenných, které se mužou v přerušení zmenit
	in	Temp, SREG			; SREG - příznakový registr
	push 	Temp				; ok

;reinicializace TMR1

	ldi	Temp, 0xD8			; zkrácení čitání TMR1 na 10000 (10E+4 * 1us = 10ms)	
	sts	TCNT1H, Temp			
	ldi	Temp, 0xF0			
	sts	TCNT1L, Temp	
		
;přerušení( vlastní program )
	
        set					; nastav příznak, ze došlo k přerušeni od TMR1 
	bld	Priznaky, P_TMR1		

Konec_Tim1_Ovf:

;obnova (načtení SREG ze zásobníku)
	
        pop	Temp				; obnova registru pro návrat z přerušení
	out	SREG, Temp			
	pop	Temp		 		
	reti

[editovat] PWM

[editovat] Popis

Větrák s PWM :) Rozhodně není 100% jistá funkčnost ... doupravuje se ... tvořeno s Radkem Tesařem [2]

[editovat] Zdroják

 

.INCLUDE "m88def.inc"

.EQU PWM_PULSES = 36	; hodnota 27.8 kHz PWM
;.EQU PWM_PULSES = 45	; hodnota 22.2 kHz PWM


.ORG 0x0000 
	rjmp Main ; Reset Handler

.ORG 0x0008 
	rjmp isr1 ; PCINT1 Handler



; Hlavní program

Main: 

; Zásobník:
	
        ldi r16,high(RAMEND); 
	out SPH,r16 ;
	ldi r16,low(RAMEND)
	out SPL,r16

; Klávesnice - nastavení viz. předchozí úlohy
	
        cbi DDRC, 2 ;
	cbi DDRC, 3
	cbi DDRC, 4

	sbi PORTC, 2 ; 
	sbi PORTC, 3
	sbi PORTC, 4

	sbi DDRD, 0 ; 
	sbi DDRD, 1 ; 
	sbi DDRD, 2
	sbi DDRD, 3

	cbi PORTD, 0	
	cbi PORTD, 1
	cbi PORTD, 2
	cbi PORTD, 3


PWM_INIT:
	ldi R17, 0b00100011	
	out TCCR0A, R17	
	ldi R17, 0b00001001	
	out TCCR0B, R17
	ldi R17, PWM_PULSES	
	out OCR0A, R17   

	sbi DDRD, 5	


; Klávesnice - Načítání


	ldi r26, PCICR 
	clr r27
	ldi r16,0b00000010 
	st X, r16 

	ldi r26, PCMSK1
	clr r27
	ldi r16,0b00011100 
	st X, r16

	sei 


; Uspávací mód (Sleep Mode)


	ldi r16,0b00000001  
	out SMCR,r16



loop:
	sleep 
	nop 
	rjmp loop




isr1:
	
	rcall KEYPRESS

	cpi R16,0		;zvýšení rychlosti
	brne Zacatek	
	mov R17, R16
	lsl R17
	lsl R17	
	out OCR0B, R17  
	rjmp isr1 



Start:      ; Po stisku pusti 50% rychlost
	ldi R20, PWM_PULSES
	mov R21, R20
	lsr R21         ; Poloviční PWM pulz
	out OCR0B, R21  ; Polovicni pulz na výstup
	clr R20
	clr R21
	ldi R22, 2

Start1:
	inc R20
	brne Zacatek1
	inc R21
	brne Zacatek1
	dec R22
	brne Zacatek1
	ret


; Klávesnice dekódování - postup vyz. výše

KEYPRESS:
KEY0:
	sbi 	PORTD, 0
	sbi 	PORTD, 1
	sbi 	PORTD, 2
	cbi 	PORTD, 3		
	sbic	PINC, 3
	rjmp	KEY1
	ldi	R16, 0		    
	ldi R17, 0b00000011 
	rjmp	KEYRET
KEY1:
	cbi 	PORTD, 0	
	sbi 	PORTD, 1	
	sbi 	PORTD, 2
	sbi 	PORTD, 3	
	sbic	PINC, 2
	rjmp	KEY2
	ldi	R16, 1		    
	ldi R17, 0b00100011 
	rjmp	KEYRET
KEY2:
	sbic	PINC, 3
	rjmp	KEY3
	ldi	R16, 2
	ldi R17, 0b00100011
	rjmp	KEYRET
KEY3:
	sbic	PINC, 4
	rjmp	KEY4
	ldi	R16, 3
	ldi R17, 0b00100011
	rjmp	KEYRET

KEY4:
	sbi 	PORTD, 0
	cbi 	PORTD, 1	;log. 0 to the row with 4, 5, 6, B
	sbi 	PORTD, 2
	sbi 	PORTD, 3	
	sbic	PINC, 2
	rjmp	KEY5
	ldi	R16, 4		;pressed key 4
	ldi R17, 0b00100011
	rjmp	KEYRET
KEY5:
	sbic	PINC, 3
	rjmp	KEY6
	ldi	R16, 5
	ldi R17, 0b00100011
	rjmp	KEYRET
KEY6:
	sbic	PINC, 4
	rjmp	KEY7
	ldi	R16, 6
	ldi R17, 0b00100011
	rjmp	KEYRET

KEY7:
	sbi 	PORTD, 0
	sbi 	PORTD, 1
	cbi 	PORTD, 2	
	sbi 	PORTD, 3	
	sbic	PINC, 2
	rjmp	KEY8
	ldi	R16, 7		
	ldi R17, 0b00100011
	rjmp	KEYRET
KEY8:
	sbic	PINC, 3
	rjmp	KEY9
	ldi	R16, 8
	ldi R17, 0b00100011
	rjmp	KEYRET
KEY9:
	sbic	PINC, 4
	rjmp	KEYRET
	ldi	R16, 9
	ldi R17, 0b00100011

KEYRET:
	cbi PORTD, 0	
	cbi PORTD, 1
	cbi PORTD, 2
	cbi PORTD, 3
	out TCCR0A, R17	
	ret

[editovat] Posuvný registr

[editovat] Popis

[editovat] Zdroják

INCLUDE "m88def.inc"

.equ CISLO1 = 6;
.equ CISLO2 = 7;
.DEF opak = R20;
.ORG 0x0000
rjmp Main ; Reset Handler


.ORG 0x0020
PREVOD:
;LDI R16,CISLO1;
MOV R16,R17; zaloha r17 do r16
ADD R16,R16; vynasobeni * 2, kazda druha instrukce je RET
INC R16
INC R16
INC R16; pricteni cisla 3, 3 instrukce od ulozeni PC
LDI ZH,HIGH(PC);nacteni vyssiho bytu PC do HIGH Z
LDI ZL,LOW(PC);nacteni nizsiho bytu PC do LOW Z
ADD ZL,R16;zvyseni LOW Z o R16
IJMP ; skok PC na hodnotu v Z

ldi R16,0b11000000;//0 
RET
ldi R16,0b11111001;//1
RET
ldi R16,0b10100100;//2
RET
ldi R16,0b10110000;//3
RET
ldi R16,0b10011001;//4
RET
ldi R16,0b10010010;//5
RET
ldi R16,0b10000010;//6
RET
ldi R16,0b11111000;//7
RET
ldi R16,0b10000000;//8
RET
ldi R16,0b10010000;//9
RET



sbi DDRD, 1
sbi DDRD, 2
sbi DDRD, 3



RCALL PREVOD

Main:
	RCALL NACTENI
	LDI OPAK,0;
ZOBRAZ:
	
	RCALL VYSTUP
	RCALL CLOCK
	RCALL POSUN
	
	INC OPAK
	SBRS OPAK,3;
	RJMP ZOBRAZ
	LDI OPAK,0;
	RCALL STORAGE_CLOCK
	RJMP Main


NACTENI:
	MOV R19,R16
	RET

VYSTUP:
	SBRS R19, 0;
	CBI PORTD,1
	NOP
	
	SBRC R19, 0;
	SBI PORTD,1
	NOP

	RET;
	
CLOCK:
	SBI PORTD,2
	NOP
	CBI PORTD,2
	RET

STORAGE_CLOCK:
	SBI PORTD,3
	NOP
	CBI PORTD,3
	RET

POSUN:
	LSR R19
	RET





.INCLUDE "m88def.inc"

;Definice promennych a konstant
.equ CISLO1 = 9;
.equ CISLO2 = 0;
.DEF FLAG = R18
.DEF CISLO = R17; DO R17 se ulozi v dec cislo,ktere se zobrazi na 7segmentovce
.DEF opak = R20;

;VEKTORY PRERUSENI
.ORG 0x0000		;RESET VEKTOR
RJMP MAIN ; Reset Handler

.ORG 0x004 	;VEKTOR EXTERNIHO PRERUSENI PCINT1 (Pin change interrupt request 1)
RJMP int_PCINT1

MAIN:

;NASTAVENI I/O PINU
sbi DDRD, 1		
sbi DDRD, 2
sbi DDRD, 3

cbi DDRC, 2 ; vstup pro tlacitka
cbi DDRC, 3
cbi DDRC, 4


;Inicializace preruseni
	; Activation of pin change interrupt - PROBLEM!!! PCICR and PCIMSK are 
	; extended I/O registers (0x68 and 0x6C), and must be handled as 
	; a memory location
ldi r26, PCICR ; load address of PCICR in Y low
clr r27 ; load high byte with 0
ldi r16,0b00000010 ; activate PCINT1
st X, r16 ; store new PCINT1
ldi r26, PCMSK1 ; load address of PCMSK1 in Y low
clr r27 ; load high byte with 0
ldi r16,0b00011100 ; allow pin change interrupt on portC bits 2,3,4
st X, r16 ; store new PCMSK1
sei ; POVOLENI PRERUSENI

LOOP:
	NOP
	RJMP LOOP


NACTENI:
	MOV R19,R16
	RET

VYSTUP:
	SBRS R19, 0;
	CBI PORTD,1
	NOP
	
	SBRC R19, 0;
	SBI PORTD,1
	NOP

	RET;
	
CLOCK:
	SBI PORTD,2
	NOP
	CBI PORTD,2
	RET

STORAGE_CLOCK:
	SBI PORTD,3
	NOP
	CBI PORTD,3
	RET

POSUN:
	LSR R19
	RET

PREVOD:
MOV R16,CISLO; zaloha r17 do r16
ADD R16,R16; vynasobeni * 2, kazda druha instrukce je RET
INC R16
INC R16
INC R16; pricteni cisla 3, 3 instrukce od ulozeni PC
LDI ZH,HIGH(PC);nacteni vyssiho bytu PC do HIGH Z
LDI ZL,LOW(PC);nacteni nizsiho bytu PC do LOW Z
ADD ZL,R16;zvyseni LOW Z o R16
IJMP ; skok PC na hodnotu v Z

ldi R16,0b11000000;//0 
RET
ldi R16,0b11111001;//1
RET
ldi R16,0b10100100;//2
RET
ldi R16,0b10110000;//3
RET
ldi R16,0b10011001;//4
RET
ldi R16,0b10010010;//5
RET
ldi R16,0b10000010;//6
RET
ldi R16,0b11111000;//7
RET
ldi R16,0b10000000;//8
RET
ldi R16,0b10010000;//9
RET

int_PCINT1:

NOP

SBRS FLAG,0
LDI CISLO,CISLO1;

SBRC FLAG,0
LDI CISLO,CISLO2;

INC FLAG
ANDI FLAG, 1


;TELO PROGRAMU
SMYCKA:
	RCALL PREVOD
	RCALL NACTENI
	LDI OPAK,0;
ZOBRAZ:
	
	RCALL VYSTUP
	RCALL CLOCK
	RCALL POSUN
	
	INC OPAK
	SBRS OPAK,3;
	RJMP ZOBRAZ
	LDI OPAK,0;
	RCALL STORAGE_CLOCK
	;RJMP SMYCKA
	NOP
	RETI; NAVRAT Z PRERUSENI
Osobní nástroje