Uživatel:Trisktom

Z MAM wiki

(Rozdíly mezi verzemi)
Přejít na: navigace, hledání
Řádka 204: Řádka 204:
 +
 +
</pre>
 +
 +
 +
<pre>
 +
 +
;;
 +
; 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
 +
 +
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
</pre>
</pre>

Verze z 28. 3. 2013, 20:27






; 
; 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 DDRD = $17		; DDRB address
	.EQU PORTD = $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

; 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, 0
	SBI PORTB, 2
GO:
	RCALL   COLOR1
	RCALL	WAIT
	SBIS	PINB, 2
	RCALL	COLOR2
	RCALL	WAIT
	RJMP	GO
;;;
;;;
;;; 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, 4			; 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, 2
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

	



led:SBIS PINB,LED_X
	SBI	PORTB,LED_X
	CBI	PORTB,LED_X
	RET





; 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





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

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