Uživatel:Krctomas

Z MAM wiki

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

Cvičení 4

ATtiny 2313 - Při stisku tlačítka 1 svítí červená LED, jinak zelená


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

	.EQU DDRD = $11
	.EQU PORTD = $12
	.EQU PIND = $10

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

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

	SBI DDRD, 4
	SBI PORTB, 2
GO:
	RCALL COLOR1
	RCALL WAIT
	SBIS PINB, 2
	RJMP GOP
	RCALL WAIT
	RJMP GO

GOP:
	RCALL COLOR2
	SBIC PINB, 2
	RJMP GO
	RJMP GOP

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

WAIT:
	LDI R16, 4	; LDI - Load Immediate
WAIT1:	INC R1          ; Bezi az do R1=255, dalsi krok - preteceni, R1=0
	BRNE WAIT1	; Pokud v R1 neni 0, skoc na 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, 2
COL3X: 	RCALL COLOR1
	RCALL SMALLWAIT
	RCALL COLOR2
	RCALL SMALLWAIT
	;INC R2
	;BRNE COL3X
	DEC R16
	BRNE COL3X
	RET

DARK:
        CBI PORTB, LED_X
	CBI PORTB, LED_Y
	RET

Cvičení 5

ATmega88 - Při stisku tlačítka 0-7 se větrák roztočí s rychlostí odpovídající 8 stupňové PWM. (Resp. prvních pár rychlostí bude zřejmě příliš malých, aby se větrák vůbec roztočil.)

;; 
; 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 numbers 0-7
; Keyboard: Rows PD0 to PD3, columns PC1 to PC3 


	.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

; Init:
	RCALL   FAN_OFF

; Keyboard init:
	CBI DDRC, 2 ;
	CBI DDRC, 3
	CBI DDRC, 4

	SBI PORTC, 2 ; set internal Pull-Ups for keyboard
	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

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


;;;
;;;
;;; P R O C E D U R E S
;;;
;;;


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	KEYRET
	LDI 	R16, 7		;pressed key 7

KEYRET:
	CBI PORTD, 0	; log. 0 on all rows for next key press catch
	CBI PORTD, 1
	CBI PORTD, 2
	CBI PORTD, 3
	RET
	
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

PWM:
	MOV 	R17, R16
	INC		R17
	LDI		R18, 0xF8
	OR		R18, R16
PWM_ON:
	DEC		R17
	BREQ	PWM_OFF
	SBI		PORTB, FAN
	RCALL 	VERYSMALLWAIT
	RJMP	PWM_ON
PWM_OFF:
	INC		R18
	BREQ	PWM_RET
	CBI		PORTB, FAN
	RCALL 	VERYSMALLWAIT
	RJMP	PWM_OFF
PWM_RET:
	RET

Cvičení 6

Atmega88 - napsat chytrejsi klavesnici + vylepseni

; 
; example fan program for ATmega88 with Timer controlled PWM&Interrupt&Sleep
;
; Rotation speed  is controlled by keyboard, 
; keys 0-9 represent the speed between 0 and 100 %
;
; Fan starts to rotate with the first valid key press
;
; To do: *** Catch only the key press, not key release
;
; To do: *** Set higher value of PWM (=higher fan rpm) for 
; a few first periods to start the fan reliably
;
;
; P4 CPU fan Ucc pin is supposed to be connected 
; to +15 V, GND pin is supposed to be connected 
; to NMOS Drain,, Source on GND, Gate on 
; pin 11 (OC0B, PD5). Fan runs when pin 11 is high.


.INCLUDE "m188def.inc"

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


.ORG 0x0000 
	rjmp Main ; Reset Handler

.ORG 0x0008 
	rjmp 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)


; 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

	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 
        
        rcall PWM

	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

PWM:
	MOV 	R17, R16
	INC		R17
	LDI		R18, 0xF0
	OR		R18, R16
PWM_ON:
	DEC		R17
	BREQ	PWM_OFF
	SBI		PORTB, FAN
	RCALL 	VERYSMALLWAIT
	RJMP	PWM_ON
PWM_OFF:
	INC		R18
	BREQ	PWM_RET
	CBI		PORTB, FAN
	RCALL 	VERYSMALLWAIT
	RJMP	PWM_OFF
PWM_RET:
	RET	


VERYSMALLWAIT:
	LDI R20, 0xEC
	MOV R1, R20
SMALLWAIT:
	INC	R1
	BRNE	SMALLWAIT
	RET
Osobní nástroje