Uživatel:Vlachja5

Z MAM wiki

(Rozdíly mezi verzemi)
Přejít na: navigace, hledání
Řádka 1: Řádka 1:
 +
'''Cvičení 6, update''': větrák s přerušením, časovačem v modu Fast PWM a klávesnicí se třetím stavem.
 +
 +
<pre>
 +
; Soubor ze cvičení k regilaci otáček s detailnějšími komentáři a upraven
 +
; s klávesnicí ve třetím stavu pro eliminaci problému se stisknutím více tlačítek najednou
 +
 +
 +
.INCLUDE "m88def.inc"
 +
 +
.EQU PWM_PULSES = 36 ; value for 27.8 kHz PWM
 +
;.EQU PWM_PULSES = 45 ; value for 22.2 kHz PWM
 +
 +
 +
.ORG 0x000
 +
rjmp Main ; Při resetu (odpovídá vekt. 0000) skoč na Main
 +
 +
.ORG 0x004
 +
rjmp isr1 ; Při změně pinu (vektor 0008 - u každého AVR jinak!, definice konkrétního pinu níže) skož na isr1
 +
 +
Main:
 +
 +
ldi r16,high(RAMEND); Main program start
 +
out SPH,r16 ; Set Stack Pointer to top of RAM
 +
ldi r16,low(RAMEND)
 +
out SPL,r16
 +
 +
 +
; Hardware initialization
 +
 +
; Keyboard init:
 +
cbi DDRC, 2 ; Sloupce klávesnice jako vstupy (jen tři - písmena netřeba)
 +
cbi DDRC, 3
 +
cbi DDRC, 4
 +
 +
sbi PORTC, 2 ; nastavení měkkých jedniček na vstupy sloupců klávesnice - pull up odpory
 +
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
 +
 +
 +
; Timer controlled PWM init:
 +
;
 +
; There are registers TCCR0A and TCCR0B for config, DDRD for output bit
 +
; enabling, OCR0A for counter lenght and OCR0A for pulse "high" lenght.
 +
; Register TIMSK0 controlls interrupts - not used, 0x00 by default
 +
 +
PWM_INIT:
 +
ldi R17, 0b00100011 ; Nastavení 1. řídicího registru čítače, poslední dva bity nastavují mód čítače (v tomto případě Fast PWM kdy vrchní hodnota čítání bude v registru OCR0A - pozor! O módu rozhoduje také bit 3 v registru TCCR0B!), první čtyři bity nastavují, jak se čítač chová při dosažení porovnávací úrovně (v tomto případě nastaví na pinu OC0B jedničku když má čítač menší hodnotu než OCR0B a naopak) 
 +
out TCCR0A, R17 ;
 +
ldi R17, 0b00001001 ; nastavení módu viz přechozí komentář, čítání bez předděličky
 +
out TCCR0B, R17
 +
ldi R17, PWM_PULSES ; Čítač přeteče při dosažení hodnoty v prom. PWM_PULSES, tzn PWM na frekvenci  frekv. oscil/PWM_PULSES. Změnou OCR0B pak budu měnit střídu PWM
 +
out OCR0A, R17 
 +
 +
sbi DDRD, 5 ; Čítač sdílí svůj výstup OC0B s 5. pinem na portu D, musím tedy nastavit jako výstup
 +
 +
 +
; Keyboard interrupt setup
 +
;
 +
; 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
 +
 +
 +
;PCICR je registr nastavující na posledních třech bitech jeden jaký ze tří možných vektorů přerušení pro změnu na pinu budou aktivní
 +
ldi r26, PCICR ; R26 a 27 tvoří 16bit registr X. Do spodních 8 bitů dám adresu PCICR
 +
clr r27 ; Hořejšek registru X vymažu
 +
ldi r16,0b00000010 ; do R 16 si připravim požadované nastavení - v tomto případě PCINT1 - vektor 0008 viz začátek programu
 +
st X, r16 ; Uložim do X nastavení přerušení - tím nastavim registr PCICR
 +
 +
;PCMSK1 mi určuje piny, které budou způsobovat přerušení PCINT1, stejným způsobem nastavím jako předchozí
 +
ldi r26, PCMSK1
 +
clr r27
 +
ldi r16,0b00011100 ; Přerušení budou způsobovat piny PCINT10, PCINT11 a PCINT12, které mají stejné vývody jako piny 2,3,4 na portu C - to jsou naše slouce klávesnice s pullup odpory
 +
st X, r16
 +
 +
sei ; zapnutí přerušení: mělo by být ekvivalentní sbi SREG,7
 +
 +
 +
; Set sleep mode of the CPU
 +
; SMCR: 0,0,0,0,SM2,SM1,SM0,SE  SM2..0: Sleep Mode Select Bits, SE: Sleep enabled)
 +
 +
ldi r16,0b00000001 ; Aktivace Sleep módu - při provedení instukce sleep skutečně proc usne
 +
out SMCR,r16 ; Zápis do příslušného registru
 +
 +
 +
; Procesor bude spát dokud nezmáčknu klávesu a nezpůsobim přerušení
 +
 +
loop:
 +
sleep
 +
nop
 +
rjmp loop
 +
 +
 +
; PCINT0 Service Routine:
 +
;
 +
; To do: *** rpm reading, regulation, etc.
 +
 +
 +
isr1: ;obsluha přerušení při zmáčknutí klávesy
 +
rcall KEYPRESS
 +
 +
mov R17, R16
 +
lsl R17 ; posun vlevo - v bináru násobení dvěmi
 +
lsl R17 ; ještě jednou - takže dohromady 4, maximální hodnota při stisku 9 je tedy 36
 +
out OCR0B, R17  ; uložim číslo 0 ... 36 v (10 kroků, tlačítek) do porovnávacího registru k nastavení střídy
 +
 +
reti ; návrat z přerušení na poslední adresu před přerušením +1 (při reti se narozdíl od ret neukládá stavový registr, je nutno to udělat růčo)
 +
 +
 +
; Keyboard decoding:
 +
 +
KEYPRESS:
 +
KEY0: ;kontrola stistku nuly - po úpravě
 +
cbi DDRD,0
 +
cbi PORTD, 0
 +
cbi DDRD,1
 +
cbi PORTD, 1
 +
cbi DDRD,2
 +
cbi PORTD, 2 ; řádky které nekontroluji tak nastavím do třetího stavu, tj jako vstupy bez pullup
 +
 +
sbi DDRD,3 ; řádek odpovádající kontrolované klávese jako výstup do nuly
 +
cbi PORTD, 3
 +
 +
sbic PINC, 3 ; v případě že je kontrolovaná klávesa, a tedy je na PINC sražená měkká 1 na 0, přeskočim následující instrukci
 +
rjmp KEY1 ; skok na test další klávesy
 +
ldi R16, 0 ; do uživ. registru šoupnu zmáčknutou hodnotu (v tomto případě nulu) kterou pak vhodně navhájuju, vložim do komparační
 +
rjmp KEYRET
 +
KEY1:
 +
sbi DDRD,0 ; nulu na první řádek, testuju jedničku
 +
cbi PORTD, 0
 +
 +
cbi DDRD,1 ; třetí stav na ost. řádcích
 +
cbi PORTD, 1
 +
cbi DDRD,2
 +
cbi PORTD, 2
 +
cbi DDRD,3
 +
cbi PORTD, 3
 +
 +
sbic PINC, 2
 +
rjmp KEY2
 +
ldi R16, 1 ; pressed key 1
 +
rjmp KEYRET
 +
KEY2:
 +
sbic PINC, 3
 +
rjmp KEY3
 +
ldi R16, 2
 +
rjmp KEYRET
 +
KEY3:
 +
sbic PINC, 4
 +
rjmp KEY4
 +
ldi R16, 3
 +
rjmp KEYRET
 +
 +
KEY4:
 +
cbi DDRD,0
 +
cbi PORTD, 0
 +
 +
sbi DDRD,1
 +
cbi PORTD, 1 ; log. 0 to the row with 4, 5, 6, B
 +
 +
cbi DDRD,2
 +
cbi PORTD, 2
 +
cbi DDRD,3
 +
cbi PORTD, 3
 +
 +
sbic PINC, 2
 +
rjmp KEY5
 +
ldi R16, 4 ; pressed key 4
 +
rjmp KEYRET
 +
KEY5:
 +
sbic PINC, 3
 +
rjmp KEY6
 +
ldi R16, 5
 +
rjmp KEYRET
 +
KEY6:
 +
sbic PINC, 4
 +
rjmp KEY7
 +
ldi R16, 6
 +
rjmp KEYRET
 +
 +
KEY7:
 +
cbi DDRD,0
 +
cbi PORTD, 0
 +
cbi DDRD,1
 +
cbi PORTD, 1
 +
 +
sbi DDRD,2
 +
cbi PORTD, 2
 +
 +
cbi DDRD,3
 +
cbi PORTD, 3
 +
 +
sbic PINC, 2
 +
rjmp KEY8
 +
ldi R16, 7 ;pressed key 7
 +
rjmp KEYRET
 +
KEY8:
 +
sbic PINC, 3
 +
rjmp KEY9
 +
ldi R16, 8
 +
rjmp KEYRET
 +
KEY9:
 +
sbic PINC, 4
 +
rjmp KEYRET
 +
ldi R16, 9
 +
 +
KEYRET:
 +
sbi DDRD, 0
 +
sbi DDRD, 1 
 +
sbi DDRD, 2
 +
sbi DDRD, 3
 +
 +
cbi PORTD, 0
 +
cbi PORTD, 1
 +
cbi PORTD, 2
 +
cbi PORTD, 3
 +
ret ; návrat na adresu uloženou na vršku zásobníku - adresa posledního volání podprogramu +1
 +
 +
</pre>
 +
'''Cvičení 6''': větrák s přerušením, časovačem v modu Fast PWM a klávesnicí se třetím stavem.
'''Cvičení 6''': větrák s přerušením, časovačem v modu Fast PWM a klávesnicí se třetím stavem.

Verze z 28. 3. 2013, 09:04

Cvičení 6, update: větrák s přerušením, časovačem v modu Fast PWM a klávesnicí se třetím stavem.

; Soubor ze cvičení k regilaci otáček s detailnějšími komentáři a upraven
; s klávesnicí ve třetím stavu pro eliminaci problému se stisknutím více tlačítek najednou


.INCLUDE "m88def.inc"

.EQU PWM_PULSES = 36	; value for 27.8 kHz PWM
;.EQU PWM_PULSES = 45	; value for 22.2 kHz PWM


.ORG 0x000 
	rjmp Main ; Při resetu (odpovídá vekt. 0000) skoč na Main

.ORG 0x004 
	rjmp isr1 ; Při změně pinu (vektor 0008 - u každého AVR jinak!, definice konkrétního pinu níže) skož na isr1

Main: 

	ldi r16,high(RAMEND); Main program start
	out SPH,r16 ; Set Stack Pointer to top of RAM
	ldi r16,low(RAMEND)
	out SPL,r16


; Hardware initialization

; Keyboard init:
	cbi DDRC, 2 ; Sloupce klávesnice jako vstupy (jen tři - písmena netřeba)
	cbi DDRC, 3
	cbi DDRC, 4

	sbi PORTC, 2 ; nastavení měkkých jedniček na vstupy sloupců klávesnice - pull up odpory
	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


; Timer controlled PWM init:
;
; There are registers TCCR0A and TCCR0B for config, DDRD for output bit
; enabling, OCR0A for counter lenght and OCR0A for pulse "high" lenght.
; Register TIMSK0 controlls interrupts - not used, 0x00 by default 

PWM_INIT:
	ldi R17, 0b00100011	; Nastavení 1. řídicího registru čítače, poslední dva bity nastavují mód čítače (v tomto případě Fast PWM kdy vrchní hodnota čítání bude v registru OCR0A - pozor! O módu rozhoduje také bit 3 v registru TCCR0B!), první čtyři bity nastavují, jak se čítač chová při dosažení porovnávací úrovně (v tomto případě nastaví na pinu OC0B jedničku když má čítač menší hodnotu než OCR0B a naopak)   
	out TCCR0A, R17			; 
	ldi R17, 0b00001001	; nastavení módu viz přechozí komentář, čítání bez předděličky
	out TCCR0B, R17
	ldi R17, PWM_PULSES	; Čítač přeteče při dosažení hodnoty v prom. PWM_PULSES, tzn PWM na frekvenci  frekv. oscil/PWM_PULSES. Změnou OCR0B pak budu měnit střídu PWM
	out OCR0A, R17   		

	sbi DDRD, 5	; Čítač sdílí svůj výstup OC0B s 5. pinem na portu D, musím tedy nastavit jako výstup


; Keyboard interrupt setup
;
; 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


;PCICR je registr nastavující na posledních třech bitech jeden jaký ze tří možných vektorů přerušení pro změnu na pinu budou aktivní
	ldi r26, PCICR ; R26 a 27 tvoří 16bit registr X. Do spodních 8 bitů dám adresu PCICR
	clr r27 ; Hořejšek registru X vymažu
	ldi r16,0b00000010 ; do R 16 si připravim požadované nastavení - v tomto případě PCINT1 - vektor 0008 viz začátek programu
	st X, r16 ; Uložim do X nastavení přerušení - tím nastavim registr PCICR

;PCMSK1 mi určuje piny, které budou způsobovat přerušení PCINT1, stejným způsobem nastavím jako předchozí
	ldi r26, PCMSK1
	clr r27
	ldi r16,0b00011100 ; Přerušení budou způsobovat piny PCINT10, PCINT11 a PCINT12, které mají stejné vývody jako piny 2,3,4 na portu C - to jsou naše slouce klávesnice s pullup odpory
	st X, r16

	sei ; zapnutí přerušení: mělo by být ekvivalentní sbi SREG,7


; Set sleep mode of the CPU
; SMCR: 0,0,0,0,SM2,SM1,SM0,SE   SM2..0: Sleep Mode Select Bits, SE: Sleep enabled)

	ldi r16,0b00000001 ; Aktivace Sleep módu - při provedení instukce sleep skutečně proc usne
	out SMCR,r16 ; Zápis do příslušného registru


; Procesor bude spát dokud nezmáčknu klávesu a nezpůsobim přerušení

loop:
	sleep 
	nop 
	rjmp loop


; PCINT0 Service Routine:
;
; To do: *** rpm reading, regulation, etc.


isr1:	;obsluha přerušení při zmáčknutí klávesy
	rcall KEYPRESS

	mov R17, R16
	lsl R17		; posun vlevo - v bináru násobení dvěmi
	lsl R17		; ještě jednou - takže dohromady 4, maximální hodnota při stisku 9 je tedy 36
	out OCR0B, R17  ; uložim číslo 0 ... 36 v (10 kroků, tlačítek) do porovnávacího registru k nastavení střídy

	reti ; návrat z přerušení na poslední adresu před přerušením +1 (při reti se narozdíl od ret neukládá stavový registr, je nutno to udělat růčo)


; Keyboard decoding:

KEYPRESS:
KEY0:		;kontrola stistku nuly - po úpravě 
	cbi		DDRD,0
	cbi 	PORTD, 0
	cbi		DDRD,1
	cbi 	PORTD, 1
	cbi		DDRD,2
	cbi 	PORTD, 2	; řádky které nekontroluji tak nastavím do třetího stavu, tj jako vstupy bez pullup
	
	sbi		DDRD,3		; řádek odpovádající kontrolované klávese jako výstup do nuly
	cbi 	PORTD, 3	
	
	sbic	PINC, 3		; v případě že je kontrolovaná klávesa, a tedy je na PINC sražená měkká 1 na 0, přeskočim následující instrukci
	rjmp	KEY1		; skok na test další klávesy
	ldi		R16, 0		; do uživ. registru šoupnu zmáčknutou hodnotu (v tomto případě nulu) kterou pak vhodně navhájuju, vložim do komparační
	rjmp	KEYRET
KEY1:
	sbi		DDRD,0		; nulu na první řádek, testuju jedničku
	cbi 	PORTD, 0	
	
	cbi		DDRD,1		; třetí stav na ost. řádcích
	cbi 	PORTD, 1
	cbi		DDRD,2	
	cbi 	PORTD, 2
	cbi		DDRD,3
	cbi 	PORTD, 3
		
	sbic	PINC, 2
	rjmp	KEY2
	ldi		R16, 1		; pressed key 1
	rjmp	KEYRET
KEY2:
	sbic	PINC, 3
	rjmp	KEY3
	ldi		R16, 2
	rjmp	KEYRET
KEY3:
	sbic	PINC, 4
	rjmp	KEY4
	ldi		R16, 3
	rjmp	KEYRET

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

KEY7:
	cbi		DDRD,0		
	cbi 	PORTD, 0
	cbi		DDRD,1		
	cbi 	PORTD, 1

	sbi		DDRD,2
	cbi 	PORTD, 2	
	
	cbi		DDRD,3
	cbi 	PORTD, 3

	sbic	PINC, 2
	rjmp	KEY8
	ldi		R16, 7		;pressed key 7
	rjmp	KEYRET
KEY8:
	sbic	PINC, 3
	rjmp	KEY9
	ldi		R16, 8
	rjmp	KEYRET
KEY9:
	sbic	PINC, 4
	rjmp	KEYRET
	ldi		R16, 9

KEYRET:
	sbi DDRD, 0 
	sbi DDRD, 1  
	sbi DDRD, 2
	sbi DDRD, 3

	cbi PORTD, 0	
	cbi PORTD, 1
	cbi PORTD, 2
	cbi PORTD, 3
	ret				; návrat na adresu uloženou na vršku zásobníku - adresa posledního volání podprogramu +1

Cvičení 6: větrák s přerušením, časovačem v modu Fast PWM a klávesnicí se třetím stavem.


; Soubor ze cvičení k regilaci otáček s detailnějšími komentáři a upraven
; s klávesnicí ve třetím stavu pro eliminaci problému se stisknutím více tlačítek najednou


.INCLUDE "m168def.inc"

.EQU PWM_PULSES = 36	; value for 27.8 kHz PWM
;.EQU PWM_PULSES = 45	; value for 22.2 kHz PWM


.ORG 0x0000 
	jmp Main ; Při resetu (odpovídá vekt. 0000) skoč na Main

.ORG 0x0008 
	jmp isr1 ; Při změně pinu (vektor 0008 - u každého AVR jinak!, definice konkrétního pinu níže) skož na isr1

Main: 

	ldi r16,high(RAMEND); Main program start
	out SPH,r16 ; Set Stack Pointer to top of RAM
	ldi r16,low(RAMEND)
	out SPL,r16


; Hardware initialization

; Keyboard init:
	cbi DDRC, 2 ; Sloupce klávesnice jako vstupy (jen tři - písmena netřeba)
	cbi DDRC, 3
	cbi DDRC, 4

	sbi PORTC, 2 ; nastavení měkkých jedniček na vstupy sloupců klávesnice - pull up odpory
	sbi PORTC, 3
	sbi PORTC, 4

	cbi DDRD, 0 ; následujících 8 řádků nastaví řádky klávesnice do třetího stavu
	cbi DDRD, 1 ; 
	cbi DDRD, 2
	cbi DDRD, 3

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


; Timer controlled PWM init:
;
; There are registers TCCR0A and TCCR0B for config, DDRD for output bit
; enabling, OCR0A for counter lenght and OCR0A for pulse "high" lenght.
; Register TIMSK0 controlls interrupts - not used, 0x00 by default 

PWM_INIT:
	ldi R17, 0b00100011	; Nastavení 1. řídicího registru čítače, poslední dva bity nastavují mód čítače (v tomto případě Fast PWM kdy vrchní hodnota čítání bude v registru OCR0A - pozor! O módu rozhoduje také bit 3 v registru TCCR0B!), první čtyři bity nastavují, jak se čítač chová při dosažení porovnávací úrovně (v tomto případě nastaví na pinu OC0B jedničku když má čítač menší hodnotu než OCR0B a naopak)   
	out TCCR0A, R17			; 
	ldi R17, 0b00001001	; nastavení módu viz přechozí komentář, čítání bez předděličky
	out TCCR0B, R17
	ldi R17, PWM_PULSES	; Čítač přeteče při dosažení hodnoty v prom. PWM_PULSES, tzn PWM na frekvenci  frekv. oscil/PWM_PULSES. Změnou OCR0B pak budu měnit střídu PWM
	out OCR0A, R17   		

	sbi DDRD, 5	; Čítač sdílí svůj výstup OC0B s 5. pinem na portu D, musím tedy nastavit jako výstup


; Keyboard interrupt setup
;
; 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


;PCICR je registr nastavující na posledních třech bitech jeden jaký ze tří možných vektorů přerušení pro změnu na pinu budou aktivní
	ldi r26, PCICR ; R26 a 27 tvoří 16bit registr X. Do spodních 8 bitů dám adresu PCICR
	clr r27 ; Hořejšek registru X vymažu
	ldi r16,0b00000010 ; do R 16 si připravim požadované nastavení - v tomto případě PCINT1 - vektor 0008 viz začátek programu
	st X, r16 ; Uložim do X nastavení přerušení - tím nastavim registr PCICR

;PCMSK1 mi určuje piny, které budou způsobovat přerušení PCINT1, stejným způsobem nastavím jako předchozí
	ldi r26, PCMSK1
	clr r27
	ldi r16,0b00011100 ; Přerušení budou způsobovat piny PCINT10, PCINT11 a PCINT12, které mají stejné vývody jako piny 2,3,4 na portu C - to jsou naše slouce klávesnice s pullup odpory
	st X, r16

	sei ; zapnutí přerušení: mělo by být ekvivalentní sbi SREG,7


; Set sleep mode of the CPU
; SMCR: 0,0,0,0,SM2,SM1,SM0,SE   SM2..0: Sleep Mode Select Bits, SE: Sleep enabled)

	ldi r16,0b00000001 ; Aktivace Sleep módu - při provedení instukce sleep skutečně proc usne
	out SMCR,r16 ; Zápis do příslušného registru


; Procesor bude spát dokud nezmáčknu klávesu a nezpůsobim přerušení

loop:
	sleep 
	nop 
	rjmp loop


; PCINT0 Service Routine:
;
; To do: *** rpm reading, regulation, etc.


isr1:	;obsluha přerušení při zmáčknutí klávesy
	rcall KEYPRESS

	mov R17, R16
	lsl R17		; posun vlevo - v bináru násobení dvěmi
	lsl R17		; ještě jednou - takže dohromady 4, maximální hodnota při stisku 9 je tedy 36
	out OCR0B, R17  ; uložim číslo 0 ... 36 v (10 kroků, tlačítek) do porovnávacího registru k nastavení střídy

	reti ; návrat z přerušení na poslední adresu před přerušením +1 (při reti se narozdíl od ret neukládá stavový registr, je nutno to udělat růčo)


; Keyboard decoding:

KEYPRESS:
KEY0:		;kontrola stistku nuly - po úpravě 
	cbi		DDRD,0
	cbi 	PORTD, 0
	cbi		DDRD,1
	cbi 	PORTD, 1
	cbi		DDRD,2
	cbi 	PORTD, 2	; řádky které nekontroluji tak nastavím do třetího stavu, tj jako vstupy bez pullup
	
	sbi		DDRD,3		; řádek odpovádající kontrolované klávese jako výstup do nuly
	cbi 	PORTD, 3	
	
	sbic	PINC, 3		; v případě že je kontrolovaná klávesa, a tedy je na PINC sražená měkká 1 na 0, přeskočim následující instrukci
	rjmp	KEY1		; skok na test další klávesy
	ldi		R16, 0		; do uživ. registru šoupnu zmáčknutou hodnotu (v tomto případě nulu) kterou pak vhodně navhájuju, vložim do komparační
	rjmp	KEYRET
KEY1:
	sbi		DDRD,0		; nulu na první řádek, testuju jedničku
	cbi 	PORTD, 0	
	
	cbi		DDRD,1		; třetí stav na ost. řádcích
	cbi 	PORTD, 1
	cbi		DDRD,2	
	cbi 	PORTD, 2
	cbi		DDRD,3
	cbi 	PORTD, 3
		
	sbic	PINC, 2
	rjmp	KEY2
	ldi		R16, 1		; pressed key 1
	rjmp	KEYRET
KEY2:
	sbic	PINC, 3
	rjmp	KEY3
	ldi		R16, 2
	rjmp	KEYRET
KEY3:
	sbic	PINC, 4
	rjmp	KEY4
	ldi		R16, 3
	rjmp	KEYRET

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

KEY7:
	cbi		DDRD,0		
	cbi 	PORTD, 0
	cbi		DDRD,1		
	cbi 	PORTD, 1

	sbi		DDRD,2
	cbi 	PORTD, 2	
	
	cbi		DDRD,3
	cbi 	PORTD, 3

	sbic	PINC, 2
	rjmp	KEY8
	ldi		R16, 7		;pressed key 7
	rjmp	KEYRET
KEY8:
	sbic	PINC, 3
	rjmp	KEY9
	ldi		R16, 8
	rjmp	KEYRET
KEY9:
	sbic	PINC, 4
	rjmp	KEYRET
	ldi		R16, 9

KEYRET:
	cbi DDRD, 0 ; následujících 8 řádků nastaví řádky klávesnice do třetího stavu
	cbi DDRD, 1 ; 
	cbi DDRD, 2
	cbi DDRD, 3

	cbi PORTD, 0	
	cbi PORTD, 1
	cbi PORTD, 2
	cbi PORTD, 3
	ret				; návrat na adresu uloženou na vršku zásobníku - adresa posledního volání podprogramu +1
Osobní nástroje