Uživatel:Nemazjan

Z MAM wiki

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

[editovat] Samostatná práce

Použité zdroje: Datasheet ATMEGA168, Datasheet Agilent HSDL-3612, Application note AVR1303: Use and configuration of IR communication module


Zadání: Navrhněte libovolné "zábavné" úlohy pro předvedení možností periferií jednotlivých řad procesorů AVR s vzužitím externího hardware (vstupní zařízení, výkonové členy, atd.). Návrh doplňte základním programem, který periferie nakonfiguruje do požadovaného módu.

Rozšíření úlohy s klávesnicí a sedmisegmentovkou – optická komunikace

Číslo stisknuté na klávesnici se zobrazí na sousedově sedmisegmentovce, číslo stisknuté u souseda se zobrazí u nás. Všichni mají identické HW zapojení a skoro stejné SW řešení (asi by bylo vhodné, aby se jeden choval jako master, druhý jako slave) :-) Lze posílat hodnotu stisknutého čísla (jen 4 bity), nebo přímo znak na sedmisegmentovku (7, popř 8 bitů, jednodušší implementace do našeho programu)


Infraport:

Modul infraportu HSDL-3612-008 od Agilent Technologies. IrDA 1.0 porporuje rychlosti 9,6 kb/s až 115,2 Kbit/s komunikace na vzdálenost i větší než 1,5 m Vzhledem k odrazům infrazáření může funovat jen jako poloviční duplex.

Soubor:OBR2.jpg

Hardwarové nastavení modulu infraportu:

Soubor:OBR1.jpg Soubor:OBR3.jpgSoubor:infraschema.png

Komunikace z mikrokontroléru se realizuje pomocí „Universal Synchronous and Asynchronous serial Receiver and Transmitter“ – USART Kontroléry řady XMEGA mají modul IRCOM pro kódování/dekódování dat IrDA protokolem. V nižších řadách je nutnost čistě softwarového řešení. My však nepotřebujeme standardizovaný IrDA protokol :-)

Předpokládám využití známých mikrokontrolérů ATMEGA168, a proto veškerá nastavení jsou právě pro tento mikrokontrolér.

nastavení vektorů přerušení od USART

.ORG 0x0024	jmp odeslano 	;USART  Rx complete 	handler
.ORG 0x0024	jmp prijato	;USART  Tx complete 	handler
;.ORG 0x0024	jmp prazdno	;USART  register empty handler - nevyužíváme

HW inicializace USARTu. Přerušení povolit až po HW inicializaci!

USART_INIT:
;ldi R26, UBRR0H
;clr R27
;ldi R17, 0b00000000	
;st X, R17	
ldi R26, UBRR0L
clr R27
ldi R17, 0b00001000	;snížení baudové rychlosti na 3676 baud/s kvůli snížení chybovosti
st X, R17	
;ldi R26, UCSR0A
;clr R27
;ldi R17, 0b00000000	; Bez double speed modu, bez multiprocesorového modu
;st X, R17
ldi R26, UCSR0B
clr R27
ldi R17, 0b11010000	; enable RxC interrupt a TxC interrupt, disable UDRE interrupt, Rx enable, Tx disable, max 8bit slovo
st X, R17	
ldi R26, UCSR0C
clr R27
ldi R17, 0b00110110	; asynchronní provoz, lichá parita, 1 stop bit, 8bitové slovo
st X, R17	

Kostra hlavního programu:

; Main program start

Main: 
;Provést HW inicializaci všech potřebných periferií...
;nastavit potřebná přerušení a povolit je
;nastavit sleep mode, ze kterého se vždy probudí některým z interruptů

KEYPRESS: 
;sem vložit rutinu z dřívějších úloh, aby uložila do R19 osmibitový kód čísla odpovídající LEDkám rozsvěcovaným na sedmisegmentovce
jmp USART_Transmit


odeslano: 		;musím uvolnit kanál a začít poslouchat
ldi R26, UCSR0B
clr R27
ldi R17, 0b11010000	
st X, R17		;nastavujeme bit Rx enable - Povolujem příjem
reti

prijato:		;zobrazím přijatá data 
in r18,UDR0; 	Uložím přijatá data, která chci zobrazit na semisegmentovce
sbic FE0		;kontrola frame error
R18=0b01111001	;v případě chyby se na sedmisegmentovku vypíše „E“ (error)
sbic DOR0		;kontrola data overrun
R18=0b01111001	;v případě chyby se na sedmisegmentovku vypíše „E“ (error)
sbic UPE0		;kontrola parity error
R18=0b01111001	;v případě chyby se na sedmisegmentovku vypíše „E“ (error)
rcall VYPIS_7SEG
reti

VYPIS_7SEG:
;sem vložit rutinu , která pošle obsah R18 na sedmisegmentovku
ret



USART_Transmit:
sbis UCSR0A,UDRE0	;kontrola že UDRE je prázdný
rjmp USART_Transmit
out UDR0,r19		; Put  data (r19) into buffer, sends the data
ldi R26, UCSR0B
clr R27
ldi R17, 0b11001000	
st X, R17		;nastavujeme bit Tx enable, nulujeme Rx enable – spouštíme odesílání
ldi R17, 0b11000000	
st X, R17		; nulujeme Tx enable – po odeslání rámce se vysílání ukončí
reti

prázdno:
nop
reti

[editovat] Domácí úkol 1.

Použité zdroje: Datasheet ATMEGA168, odkazy z "Program cvičení" na MAM WIKI a skvělé rady Ing. Zdeňka Horčíka přes E-mail.


.INCLUDE "m168def.inc"

.EQU PWM_PULSES = 100	; value for 10 kHz PWM
.EQU PWM2_PULSES = 64


.ORG 0x0000 
	jmp Main ; Reset Handler

.ORG 0x0008 
	jmp isr1 ; PCINT1 Handler

.ORG 0x001A
	jmp palubka	;TIMER1 OVF Handler


; Main program start

Main: 

; Stack pointer init:
	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

	cbi DDRC,0		;nastavení vstupu pro dveřní kontakt
	sbi PORTC,0
;nastavení výstupních pinů pro PWM
	cbi DDRD,5		;kabina	
	sbi DDRD,6		;palubka


; 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 

PWM0_INIT:
	ldi R17, 0b00100011	; Fast PWM Mode, out on OC0B, non Inverting
	out TCCR0A, R17			; 
	ldi R17, 0b00001001	; WGM2:1 (Fast PWM), CS2..0:001 (internal clock, prescale=1)
	out TCCR0B, R17
	ldi R17, PWM_PULSES	; load number of clock pulses for 1 PWM period
	out OCR0A, R17 
	
PWM2_INIT:

	ldi R26, TCCR2A
	clr R27
	ldi R17, 0b00100011	; Fast PWM Mode, out on OC0B, non Inverting
	st X, R17	
	ldi R26, TCCR2B		; 
	ldi R17, 0b00001001	; WGM2:1 (Fast PWM), CS2..0:001 (internal clock, prescale=1)
	st X, R17
	ldi R26, OCR2A
	ldi R17, PWM2_PULSES	; load number of clock pulses for 1 PWM period
	st X, R17

TIMER1_INIT:
	
	ldi R26, TCCR1B
	clr R27
	ldi R17, 0x01 ;bez předděličky - 15krát za sekundu přeteče a vyvolá přerušení
	st X, R17

ADC_INIT:

	ldi R26, ADMUX
	clr R27
	ldi R17, 0b00100001		;ADLAR=1 (zarovnat vlevo), použít nohu C1, použít vnější AREF
	st X, R17
	ldi R26, ADCSRA
	clr R27
	ldi R17, 0b10000010		;enable ADC, division rate 4
	st X, R17
		

; Nastavení interruptu časovače

	ldi r26, TIMSK1 ; load address of TIMSK1 in Y low
	clr r27 ; load high byte with 0
	ldi r16,0b00000001 ; Allow timer overflow interrupt (timer1)
	st X, r16 ; store new TIMSK1


;Nastavení iterruptu dveřního kontaktu

	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,0b00000001 ; allow pin change interrupt on portC bit 0
	st X, r16 ; store new PCMSK1

	sei ; Enable interrupts


; 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 ; Idle mode 
	out SMCR,r16 ; Sleep mode set


; Sleep loop, wake up by the Interrupt, return with RETI back to sleep loop

loop:
	sleep ; now AVR sleeps
	nop ; return from Interrupt to this instruction
	rjmp loop ; and sleep again


isr1:
	rcall KEYPRESS
	reti ; return from Interrupt

;Obsluha potenciometru
palubka:

	ldi R26, ADCSRA
	clr R27
	ldi R17, 0b11000010	;Start conversion, division factor 4
	st X, R17	
	ldi  r18, 13	;čekání na dokončení převodu
	HOP:	dec  r18
	brne HOP
	
	ldi R26, ADCH		;zápis výstupu z ADC do PWM
	clr R27
	ld  R17,X
	ldi R26,OCR0B
	clr R27
	st X,R17

		
reti


; Obsluha dveřního kontaktu

KEYPRESS:
	sbis PINC,0			;jsou dveře otevřené?
	rjmp STMIVANI		;dveře zavřené, budeme stmívat
	ldi R16,100			;dveře otevřené, svítíme naplno
	mov R17, R16
	sbi DDRD,5
	out OCR0B, R17  ; output pulse "high" lenght to PWM compare unit 
ret


STMIVANI:				
	ldi R18, 250
	SMYCKA:				  ;5s plného svitu - neměníme nastavení PWM
		rcall WAIT20mSEC
		dec R18
		BRNE SMYCKA

	ldi R18, 100
	SMYCKA2:			;2s ztmívání - postupně snižujeme střídu PWM
		mov R17, R18
		out OCR0B, R17
		rcall WAIT20mSEC
		dec R18
		BRNE SMYCKA2
	cbi DDRD,5			;nakonec výstup vypneme
ret




WAIT20mSEC:
    ldi  r19, 26
    ldi  r20, 255
	L2:	dec  r20
		brne L2
		dec  r19
		brne L2
ret


 |.......................................................................|
 | S Honzou Markem jsme rozchodili 7segmentovku přes posuvný registr :-) |
 |.......................................................................|

Ukradeno od Martina Jelínka a upraveno

LDI R16,6	;Znak "1" do registru R16
;LDI R16,31 ;Znak "0" do registru R16
REGISTR: 
LDI R17, 128 ; pro osmibitove slovo (pro 7-bitove ulozit64)
POSUN_DALSI: 
CBI PORTC, 0	 ; vynuluje vystup 
SBRC R16, 0	 ; otestuje 0 bit v R16 
SBI PORTC, 0	 ; vystup do 1
SBI PORTC, 1	 ; hodiny na shift registr - vzestup hr. 
ROR R16	 ; rotace vpravo R16 
CBI PORTC, 1	 ; hodiny na shift registr - sestup hr. 
SBRC R17, 0	 ; neni posledni 
RJMP POSUN_KONEC 
ROR R17	 ; rotace vpravo R17 
RJMP POSUN_DALSI
POSUN_KONEC: 
SBI PORTC, 2	 ; hodiny na storage registr - vzestup hr. 
NOP 
NOP 
CBI PORTC, 2	 ; hodiny na storage registr - sestup hr.
RET



Poslední verze (spolupráce s Honzou Markem - marekj20)

.INCLUDE "m168def.inc"

.EQU PWM_PULSES = 36	; value for 27.8 kHz PWM
;vektory preruseni
.ORG 0x0000 jmp Main ; Reset Handler
.ORG 0x0008 jmp isr1 ; PCINT1 Handler

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

;nastaveni klavesnice
cbi DDRC,2
cbi DDRC,3  ;nastaveni sloupcu jako vstupy
cbi DDRC,4
cbi DDRC,5
sbi PORTC,2 ;pull-up resistor
sbi PORTC,3
sbi PORTC,4
sbi PORTC,5
sbi DDRD,0
sbi DDRD,1
sbi DDRD,2		;nastaveni radku jako vystupu
sbi DDRD,3
cbi PORTD,0 ;nastavení do nuly
cbi PORTD,1
cbi PORTD,2
cbi PORTD,3
PWM_INIT: 
ldi R17, 0b00100011	; Fast PWM Mode, out on OC0B, non Inverting out TCCR0A, R17	 ; ldi R17, 0b00001001	; WGM2:1 (Fast PWM), CS2..0:001 (internal clock, prescale=1) out TCCR0B, R17 ldi R17, PWM_PULSES	; load number of clock pulses for 1 PWM period out OCR0A, R17
sbi DDRD, 5	; set pin 11 as PWM output OC0B (PD5 pin)

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 ; Enable interrupts

;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 ; Idle mode out SMCR,r16 ; Sleep mode set

;Sleep loop, wake up by the Interrupt, return with RETI back to sleep loop
loop: sleep ; now AVR sleeps 
nop ; return from Interrupt to this instruction 
rjmp loop ; and sleep again

isr1: rcall KEYPRESS
mov R17, R16 lsl R17 lsl R17	; multiply key number by 4 for 10 steps in 40 clock pulses of PWM out OCR0B, R17  ; output pulse "high" lenght to PWM compare unit
reti ; return from Interrupt

;Ovladani klavesnice

KEYPRESS:
;nastavení radku do vysoke impedance
cbi DDRD,0
cbi DDRD,1
cbi DDRD,2	
cbi DDRD,3
;aktivace prvniho radku
sbi DDRD,0 
SBIS PINC,2 
RCALL KEY1 
SBIS PINC,3 
RCALL KEY2 
SBIS PINC,4 
RCALL KEY3 
SBIS PINC,5 
RCALL KEYA
;aktivace druheho radku
cbi DDRD,0 ;prvni radek je opet vstup - vysoká impedance
sbi DDRD,1 ;druhy radek je vystup - tvrdá nula
SBIS PINC,2 
RCALL KEY4 
SBIS PINC,3 
RCALL KEY5 
SBIS PINC,4 
RCALL KEY6 
SBIS PINC,5 
RCALL KEYB
;aktivace 3 radku
cbi DDRD,1 
sbi DDRD,2 
SBIS PINC,2 
RCALL KEY7 
SBIS PINC,3 
RCALL KEY8 
SBIS PINC,4 
RCALL KEY9 
SBIS PINC,5 
RCALL KEYC
;aktivace 4 radku
cbi DDRD,2 
sbi DDRD,3 
SBIS PINC,2 
RCALL KEYHV 
SBIS PINC,3 
RCALL KEY0 
SBIS PINC,4 
RCALL KEYKR 
SBIS PINC,5 
RCALL KEYD
RET


KEY0: ldi R16,0 
		RJMP KEYRET
KEY1: ldi R16,1 
		RJMP KEYRET
KEY2: ldi R16,2 
		RJMP KEYRET
KEY3: ldi R16,3
		RJMP KEYRET
KEY4: ldi R16,4 
		RJMP KEYRET
KEY5: ldi R16,5 
		RJMP KEYRET
KEY6: ldi R16,6 
		RJMP KEYRET
KEY7: ldi R16,7 
		RJMP KEYRET
KEY8: ldi R16,8 
		RJMP KEYRET
KEY9: ldi R16,9 
		RJMP KEYRET
KEYA: 	NOP 
		RJMP KEYRET
KEYB: 	NOP 
		RJMP KEYRET
KEYC: 	NOP 
		RJMP KEYRET
KEYD: 	NOP 
		RJMP KEYRET
KEYHV: 	NOP
		RJMP KEYRET
KEYKR: 	NOP
		RJMP KEYRET

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

RET



.EQU DDRC = $07	 ; DDRB address 
.EQU PORTC = $08	; PORTB address 
.EQU PINC = $06 
.EQU DDRD = $0A 
.EQU PORTD = $0B

; Tady klavesnice
KEY:
SBI DDRC,0 ; VÝSTUP PRO VENTILÁTOR

CBI DDRC,2	;BUDÍCÍ ČÁST
CBI DDRC,3
CBI DDRC,4
CBI DDRC,5

SBI PORTC,2	; PULL UP REZISTORY
SBI PORTC,3
SBI PORTC,4
SBI PORTC,5

CBI DDRD,2	;VSTUPNÍ ČÁST
CBI DDRD,3
CBI DDRD,4
CBI DDRD,5

SBI DDRD,2
CBI PORTD,2;TEST PRVNÍHO SLOUPCE
SBI PORTD,3
SBI PORTD,4
SBI PORTD,5

SBIS PINC,2
RCALL TLAC1
SBIS PINC,3
RCALL TLAC4
SBIS PINC,4
RCALL TLAC7
SBIS PINC,5
RCALL TLACHV


CBI DDRD,2
SBI DDRD,3
SBI PORTD,2;TEST 2 SLOUPCE
CBI PORTD,3

	SBIS PINC,2
	RCALL TLAC2
	SBIS PINC,3
	RCALL TLAC5
	SBIS PINC,4
	RCALL TLAC8
	SBIS PINC,5
	RCALL TLAC0

CBI DDRD,3
SBI DDRD,4
SBI PORTD,3;TEST 3 SLOUPCE
CBI PORTD,4

	SBIS PINC,2
	RCALL TLAC3
	SBIS PINC,3
	RCALL TLAC6
	SBIS PINC,4
	RCALL TLAC9
	SBIS PINC,5
	RCALL TLACKR

CBI DDRD,4
SBI DDRD,5
SBI PORTD,4;TEST 4 SLOUPCE
CBI PORTD,5

	SBIS PINC,2
	RCALL TLACA
	SBIS PINC,3
	RCALL TLACB
	SBIS PINC,4
	RCALL TLACC
	SBIS PINC,5
	RCALL TLACD

JMP KEY



TLAC0:
	RCALL	FAN_OFF
RET

TLAC1:
	RCALL	FAN_ON
	RCALL	VERYSMALLWAIT  
	RCALL	FAN_OFF
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
RET

TLAC2:
	RCALL	FAN_ON
	RCALL	VERYSMALLWAIT  
	RCALL	VERYSMALLWAIT
	RCALL	FAN_OFF
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
RET

TLAC3:
	RCALL	FAN_ON
	RCALL	VERYSMALLWAIT  
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	FAN_OFF
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
RET

TLAC4:
	RCALL	FAN_ON
	RCALL	VERYSMALLWAIT  
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	FAN_OFF
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
RET

TLAC5:
	RCALL	FAN_ON
	RCALL	VERYSMALLWAIT  
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	FAN_OFF
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
RET

TLAC6:
	RCALL	FAN_ON
	RCALL	VERYSMALLWAIT  
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	FAN_OFF
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
RET

TLAC7:
	RCALL	FAN_ON
	RCALL	VERYSMALLWAIT  
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	FAN_OFF
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
RET

TLAC8:
	RCALL	FAN_ON
	RCALL	VERYSMALLWAIT  
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	FAN_OFF
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
RET

TLAC9:
	RCALL	FAN_ON
	RCALL	VERYSMALLWAIT  
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	FAN_OFF
	RCALL	VERYSMALLWAIT
RET

TLACA:
RCALL	FAN_ON
RET

TLACB:
RET
TLACC:
RET
TLACD:
RET
TLACHV:
RET
TLACKR:
RET



VERYSMALLWAIT:
	LDI R20, 0xFC
	MOV R1, R20
SMALLWAIT:
	INC	R1
	BRNE	SMALLWAIT
	RET

FAN_ON:
	SBI	PORTC, 0
	RET

FAN_OFF:
	CBI	PORTC, 0
	RET






example LED-show program for ATtiny 2313 2-color LED with 300 Ohm resistor in series is supposed to be connected between pins 12 (PB0, LED_X) and 13 (PB1, LED_Y). Color1 shines when LED_X is high and LED_Y is low Color2 shines when LED_Y is high and LED_X is low LED is off when LED_Y and LED_X are both low or both high

.EQU DDRB = $17	 ; DDRB address 
.EQU PORTB = $18	; PORTB address 
.EQU PINB = $16 
.EQU PIND = $10 
.EQU DDRD = $11 
.EQU PORTD = $12


.EQU LED_X = 0	 ; LED_X is on PB0, pin 12 of ATtiny2313 .EQU LED_Y = 1	 ; LED_Y is on PB1, pin 13 of ATtiny2313
Pins connected to LED are outputs, DDRx=1 (set)
SBI	DDRB, LED_X	; SBI - Set Bit in I/O Register SBI	DDRB, LED_Y

; Tady klavesnice
   SBI DDRD,2
   SBI PORTD,2
   SBI DDRD,3
   SBI PORTD,3
   SBI DDRD,4
   SBI PORTD,4
   SBI DDRD,5
   SBI PORTD,5	

   CBI DDRB,2
   CBI PORTB,2
   SBI DDRB,3
   SBI PORTB,3
   SBI DDRB,4
   SBI PORTB,4
   SBI DDRB,5
   SBI PORTB,5 ;prvni radek
SBIS PIND,2
RCALL TLAC1
SBIS PIND,3
RCALL TLAC2
SBIS PIND,4
RCALL TLAC3
SBIS PIND,5
RCALL TLACA

SBI DDRB,2
CBI DDRB,3
SBI PORTB,2
CBI PORTB,3 ;druhy radek
	SBIS PIND,2
	RCALL TLAC4
	SBIS PIND,3
	RCALL TLAC5
	SBIS PIND,4
	RCALL TLAC6
	SBIS PIND,5
	RCALL TLACB

SBI DDRB,3
CBI DDRB,4
SBI PORTB,3
CBI PORTB,4 ;treti radek
	SBIS PIND,2
	RCALL TLAC7
	SBIS PIND,3
	RCALL TLAC8
	SBIS PIND,4
	RCALL TLAC9
	SBIS PIND,5
	RCALL TLACC

SBI DDRB,4
CBI DDRB,5
SBI PORTB,4
CBI PORTB,5 ;ctvrty radek
	SBIS PIND,2
	RCALL TLAC*
	SBIS PIND,3
	RCALL TLAC0
	SBIS PIND,4
	RCALL TLAC#
	SBIS PIND,5
	RCALL TLACD




TLAC0:
RET
TLAC1:
RET
TLAC2:
RET
TLAC3:
RET
TLAC4:
RET
TLAC5:
RET
TLAC6:
RET
TLAC7:
RET
TLAC8:
RET
TLAC9:
RET
TLACA:
RET
TLACB:
RET
TLACC:
RET
TLACD:
RET
TLAC*:
RET
TLAC#:
RET



SHOW:	 RCALL	COLOR1	; RCALL - Relative Call to Subroutine RCALL	WAIT
RCALL	DARK RCALL	WAIT
RCALL	COLOR1 RCALL	WAIT
RCALL	DARK RCALL	WAIT
RCALL	COLOR2 RCALL	WAIT
RCALL	DARK RCALL	WAIT
RCALL	COLOR2 RCALL	WAIT
RCALL	DARK RCALL	WAIT
RCALL	COL3W
RCALL	DARK RCALL	WAIT
RCALL	COL3W
RCALL	DARK RCALL	WAIT
RET	 ; RJMP - Relative Jump
P R O C E D U R E S
SMALLWAIT: INC	R1	 ; INC - Increment BRNE	SMALLWAIT	; BRNE - Branch if Not Equal (Z flag) RET	 ; RET - Return from Subroutine
WAIT: LDI	R16, 2	 ; LDI - Load Immediate WAIT1:	INC	R1 BRNE	WAIT1 INC	R2 BRNE	WAIT1 DEC	R16 BRNE	WAIT1 RET
COLOR1:
   SBI	PORTB, LED_X
CBI	PORTB, LED_Y	; CBI - Clear Bit in I/O Register RET
COLOR2:
   SBI	PORTB, LED_Y
CBI	PORTB, LED_X RET
COL3W: LDI	R16, 1 COL3X:
	RCALL	COLOR1
RCALL	SMALLWAIT RCALL	COLOR2 RCALL	SMALLWAIT INC	R2 BRNE	COL3X DEC	R16 BRNE	COL3X
DARK:
   CBI	PORTB, LED_X
CBI	PORTB, LED_Y RET
;...................................................................









; 
; example LED-show program for ATtiny 2313
;
; 2-color LED with 300 Ohm resistor in series is supposed to be
; connected between pins 12 (PB0, LED_X) and 13 (PB1, LED_Y).
;
; Color1 shines when LED_X is high and LED_Y is low
; Color2 shines when LED_Y is high and LED_X is low
; LED is off when LED_Y and LED_X are both low or both high


	.EQU DDRB = $17		; DDRB address
	.EQU PORTB = $18	; PORTB address
	.EQU PINB = $16
	.EQU PIND = $10
	.EQU DDRD = $11
	.EQU PORTD = $12


	.EQU LED_X = 0		; LED_X is on PB0, pin 12 of ATtiny2313
	.EQU LED_Y = 1		; LED_Y is on PB1, pin 13 of ATtiny2313

; Pins connected to LED are outputs, DDRx=1 (set):

	SBI	DDRB, LED_X	; SBI - Set Bit in I/O Register
	SBI	DDRB, LED_Y


	; Tady klavesnice

    SBI DDRB,2
    SBI PORTB,2

	STISK:
    
	 SBIS PINB,2
	 RCALL SHOW
     RJMP STISK




SHOW:	
	RCALL	COLOR1	; RCALL - Relative Call to Subroutine
	RCALL	WAIT
	
	RCALL	DARK
	RCALL	WAIT
	
	RCALL	COLOR1
	RCALL	WAIT
	
	RCALL	DARK
	RCALL	WAIT
	
	RCALL	COLOR2
	RCALL	WAIT

	RCALL	DARK
	RCALL	WAIT
	
	RCALL	COLOR2
	RCALL	WAIT

	RCALL	DARK
	RCALL	WAIT

	RCALL	COL3W

	RCALL	DARK
	RCALL	WAIT

	RCALL	COL3W

	RCALL	DARK
	RCALL	WAIT
	
	RET		; RJMP - Relative Jump 

;;;
;;;
;;; P R O C E D U R E S
;;;
;;;
	
SMALLWAIT:
	INC	R1				; INC - Increment
	BRNE	SMALLWAIT	; BRNE - Branch if Not Equal (Z flag) 
	RET					; RET - Return from Subroutine

WAIT:
	LDI	R16, 2			; LDI - Load Immediate
WAIT1:	INC	R1
	BRNE	WAIT1
	INC	R2
	BRNE	WAIT1
	DEC	R16
	BRNE	WAIT1
	RET
	
COLOR1:
    SBI	PORTB, LED_X
	CBI	PORTB, LED_Y	; CBI - Clear Bit in I/O Register
	RET

COLOR2:
    SBI	PORTB, LED_Y
	CBI	PORTB, LED_X
	RET

COL3W:
	LDI	R16, 1
COL3X:
 	RCALL	COLOR1
	RCALL	SMALLWAIT
	RCALL	COLOR2
	RCALL	SMALLWAIT
	INC	R2
	BRNE	COL3X
	DEC	R16
	BRNE	COL3X

DARK:
    CBI	PORTB, LED_X
	CBI	PORTB, LED_Y
	RET
Tyden 5
; 
; example fan program for ATmega88
;
; P4 CPU fan Ucc pin is supposed to be connected 
; to +12 V, GND pin is supposed to be connected 
; to FET Drain, Source on GND, Gate on 
; pin 16 (PB2, FAN). Fan runs when FAN output is log. H.
;
; FAN is switched ON with switch between PC2 and PD2


	.EQU DDRB = $04
	.EQU PORTB = $05

	.EQU DDRC = $07
	.EQU PORTC = $08
	.EQU PINC = $06

	.EQU DDRD = $0A
	.EQU PORTD = $0B
	.EQU PIND = $09

;	.INCLUDE "m168def.inc"  ; replaces previous lines of the program

	.EQU FAN = 2


; Pin driving FAN is set as output:

	SBI	DDRB, FAN

; Basic keyboard init:

; One switch of matrix keyboard is connected between PINC 2 a PIND 2
; Zero values of DDRC, 2 and PORTB, 2 are implicit

	SBI DDRD, 2
	SBI PORTC, 2

    SBI DDRC,3
	SBI PORTC,3


; Init:
	RCALL   FAN_OFF

GO:	SBIS	PINC, 2
	RCALL	FAN3W   ; Simple PWM control of the FAN, if the key is pressed
	RJMP	GO


;;;
;;;
;;; P R O C E D U R E S
;;;
;;;
	
VERYSMALLWAIT:
	LDI R20, 0xFC
	MOV R1, R20
SMALLWAIT:
	INC	R1
	BRNE	SMALLWAIT
	RET

WAIT:
	LDI	R21, 4
WAIT1:
	INC	R1
	BRNE	WAIT1
	INC	R2
	BRNE	WAIT1
	DEC	R21
	BRNE	WAIT1
	RET
	
FAN_ON:
	SBI	PORTB, FAN
	RET

FAN_OFF:
	CBI	PORTB, FAN
	RET

FAN3W:
	LDI	R16, 0x20
FAN3X:
 	RCALL	FAN_ON
	RCALL	VERYSMALLWAIT  ; pulse ratio controlled by number of waits
	RCALL	VERYSMALLWAIT  ; 4:1 in this case
	RCALL	VERYSMALLWAIT
	RCALL	VERYSMALLWAIT
	RCALL	FAN_OFF
    
  
    

	RCALL	VERYSMALLWAIT 


	INC	R2
	BRNE	FAN3X
	DEC	R16
	BRNE	FAN3X
	RET

;ventilator - PWM,sleep.preruseni
           ;Ovladani ventilatoru klavesnici

.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 ; Reset Handler

.ORG 0x0008 
	jmp isr1 ; PCINT1 Handler



; Main program start

Main: 

; Stack pointer init:
	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 ; set inputs for keyboard (COL1-3)
	cbi DDRC, 3
	cbi DDRC, 4

	sbi PORTC, 2 ; set internal Pull-Ups for keyboard
	sbi PORTC, 3
	sbi PORTC, 4

	sbi DDRD, 0 ; set driving outputs for keyboard
	sbi DDRD, 1 ; (ROW1-ROW4)
	sbi DDRD, 2
	sbi DDRD, 3

	cbi PORTD, 0	; log. 0 on all rows
	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	; Fast PWM Mode, out on OC0B, non Inverting
	out TCCR0A, R17			; 
	ldi R17, 0b00001001	; WGM2:1 (Fast PWM), CS2..0:001 (internal clock, prescale=1)
	out TCCR0B, R17
	ldi R17, PWM_PULSES	; load number of clock pulses for 1 PWM period
	out OCR0A, R17   

	sbi DDRD, 5	; set pin 11 as PWM output OC0B (PD5 pin)

	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 ; Enable interrupts


; 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 ; Idle mode 
	out SMCR,r16 ; Sleep mode set


; Sleep loop, wake up by the Interrupt, return with RETI back to sleep loop

loop:
	sleep ; now AVR sleeps
	nop ; return from Interrupt to this instruction
	rjmp loop ; and sleep again


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


isr1:
	rcall KEYPRESS

	mov R17, R16
	lsl R17
	lsl R17	; multiply key number by 4 for 10 steps in 40 clock pulses of PWM
	out OCR0B, R17  ; output pulse "high" lenght to PWM compare unit 

	reti ; return from Interrupt


; Keyboard decoding:

KEYPRESS:
KEY0:
	sbi 	PORTD, 0
	sbi 	PORTD, 1
	sbi 	PORTD, 2
	cbi 	PORTD, 3	;log. 0 to the row with *, 0, #, D	
	sbic	PINC, 3
	rjmp	KEY1
	ldi	R16, 0		;pressed key 0
	rjmp	KEYRET
KEY1:
	cbi 	PORTD, 0	;log. 0 to the row with 1, 2, 3, A
	sbi 	PORTD, 1	;log. 1 on another three
	sbi 	PORTD, 2
	sbi 	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:
	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
	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:
	sbi 	PORTD, 0
	sbi 	PORTD, 1
	cbi 	PORTD, 2	;log. 0 to the row with 7, 8, 9, C
	sbi 	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 PORTD, 0	; log. 0 on all rows for next key press catch
	cbi PORTD, 1
	cbi PORTD, 2
	cbi PORTD, 3
	ret
Osobní nástroje