Uživatel:Ladysmar

Z MAM wiki

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

Obsah

[editovat] Semestrální práce s Štych Marek[1]


[editovat] Zadání

Našim úkolem bylo navrhnout solární LED lapičku s ochranou proti úplnému vybití akumulátoru - náhrada elektroniky lampičky se 2 NiCd akumulátory v sérii, nebo i s jediným, dobíjenými solárním článkem (další inspirace). AVR řešení má mít co nejlepší účinnost, rozsvítit se po (téměř úplném) setmění - měřeno napájecím solárním článkem nebo LED použitou jako fotodioda, zhasnout při vybití napájecích článků pod 1,1 V/článek, potom ho rozsvěcet vždy pouze na několik minut následujících po osvětlení a následném zhasnutí vnějšího osvětlení (orientační světlo).


[editovat] Schhéma

Soubor:LED lampička.png

[editovat] Program

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;            SEMESTRALNI PRACE , LED LAMPICKA           ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



.include "tn13Adef.inc"

.ORG 0x0000 
	rjmp Main ; Reset Handler

.ORG 0x0002
	rjmp probuzeni ; PCINT0, pokud nastane preruseni 0x0008 skoci se na probuzeni



; Main program start

Main: 
	clr r17;
	out OSCCAL, r17;    vyber pomalejsiho modu interniho oscilatoru 128 kHz



	sei;  povoleni interuptu



;;;;;;;;;;;;;;;;;;;;;;;;;;;; inicializace vstupu / vystupu (pinu)  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	; 1,2,3,5 bit portu B budou vstupy
	; 0 bit portu B bude vystup	


	cbi DDRB, 2 ; vstupy
	cbi DDRB, 3
	cbi DDRB, 5
	cbi DDRB, 1

	sbi DDRB, 0 ; vystup
	

	sbi PORTB, 2 ; aktivovani pull up resistoru u vstupu
	sbi PORTB, 3 
	sbi PORTB, 5 
	sbi PORTB, 1 




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; VYBER MODU SPANKU ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; povoleni sleep modu + nastaveni sleep modu na Power down mod
; bity 3-5 registru MCUCR jsou nastaveny pomoci log or a log and aby nebyli ovlivneny jine hodnoty v registru

 	clr r17;
 	ldi r17,48 ;( 4 a 5 bit nastaveny do 1 )
			; 5 bit => povoleni sleepu,  4bit v 1 a 3 bit v 0 => power down mode

  	OUT MCUCR, r17;



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;  SMYCKA VE KTERE PROCESOR SPI A CEKA NA PRERUSENI ;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


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


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;






;;;;;;;;;;;;;;;;;; CAST PROGRAMU SPOUSTENA POKUD NASTANE PRERUSENI 0x0002  ;;;;;;;;;;;;;;;


probuzeni:
        cli;
	rjmp testbaterie;  skoc na test baterie

baterievporadku:	
	in r17, PORTB;

 	ldi r16,44; 2,3,5 bity v log 1

 	and r17, r16; takto zanechame v r17 pouze bity ktere meli vahu vstupu PB2,PB3 a PB5
 	cp r17, r16 ;porovna obsah registru r17 s hodnotou 00101100b, tzn. testujeme jestli jsou vsechny vstupy v log 1r17, 00101100b	;porovna obsah registru r17 s hodnotou 00101100b, tzn. testujeme jestli jsou vsechny vstupy v log 1
				
	breq rozsvitsvetlo;  pokud jsou vsechny vstupy v log 1 rozsvit svetlo

baterievybita:
	ldi r16,44; 2,3,5 bity v log 1
 	OUT ACSR, R16

        sei;
	reti ; ukonci obsluhu preruseni, vrat se a uspi MCU






;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   CEKAci METODY   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; tento cyklus trva na frekvenci 128 Mhz priblizne 1 min

svit: 	LDI	R16, 30			
WAIT1:	INC	R1
	BRNE	WAIT1
	INC	R2
	BRNE	WAIT1
	DEC	R16
	BRNE	WAIT1
	DEC	R20
	BRNE	WAIT1
	RET


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ROZSVICENI LAMPICKY ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	

rozsvitsvetlo:
	sbi PORTB, 0; prvni bit v PORTB ( na ktery je pripojeno svetlo, dame do 1, svetlo sviti )
	rjmp svit;  spust cekaci metodu ( tzn nech svetlo cca minutu svitit )
	cbi PORTB, 0; zhasni svetlo
	ret



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ANALOGOVA KOMPARACE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 
testbaterie:
	ldi     r16,44; 2,3,5 bity v log 1
 	OUT     ACSR, R16 ; misto AIN0 je referencni napeti ( 1,1V ) porovnava se s AIN1 ( PB1 )
 
	SBIS    ACSR, ACO	; preskoc dalsi instrukci pokud ACO = 1 tzn. na baterce je mene nez 1,1V
	rjmp 	baterievporadku 
	rjmp 	baterievybita  








7.3.2013


[editovat] Tlačítko

http://noel.feld.cvut.cz/vyu/a2m99mam/index.php/Maticov%C3%A1_kl%C3%A1vesnice

CV 4. detekce tlacitka blikanim diody
-----------------------------------------------------------
        .EQU DDRB = 0x17
	.EQU PORTB = 0x18
	.EQU PINB = 0x16

	.EQU DDRD = 0x11
	.EQU PORTD = 0x12
	.EQU PIND = 0x10






	.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, 2
	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
---------------------------------------------------------------------------------------


[editovat] Klavesnice snad funguje

Pozn. Horčík: Asi nefunguje, spousta chyb - porty B i D nastaveny jako výstupní, při přechodu mezi řádky klávesnice nedeaktivujete předchozí řádek a rovnou aktivujete další, takže nakonec budou aktivní všechny, ...


	.EQU DDRB = 0x17
	.EQU PORTB = 0x18
	.EQU PINB = 0x16

	.EQU DDRD = 0x11
	.EQU PORTD = 0x12
	.EQU PIND = 0x10

SBI DDRD, 2    ; nastaveni ctyr vstupu
SBI DDRD, 3
SBI DDRD, 4
SBI DDRD, 5
SBI PORTD,2
SBI PORTD,3
SBI PORTD,4
SBI PORTD,5

SBI DDRB, 2    
SBI DDRB, 3
SBI DDRB, 4
SBI DDRB, 5
SBI PORTB, 2    ; nastaveni pull-up rezistoru
SBI PORTB, 3
SBI PORTB, 4
SBI PORTB, 5

JEDNAW:
	CBI PORTD,2  ; 
	SBIC PINB,2 
	RJMP DVE 
	LDI R17,1 
	RET
DVE:
	SBIC PINB,3
	RJMP TRI 
	LDI R17,2 
	RET
TRI:
	SBIC PINB,4 
	RJMP ACKO 
	LDI R17,3 
	RET
ACKO:
	SBIC PINB,5 
	RJMP CTYRI 
	LDI R17,11 
	RET
CTYRI: 
	CBI PORTD,3 
	SBIC PINB,2 
	RJMP PET 
	LDI R17,4 
	RET
PET:
	SBIC PINB,3 
	RJMP SEST 
	LDI R17,5 
	RET
SEST:
	SBIC PINB,4 
	RJMP BECKO 
	LDI R17,6 
	RET
BECKO:
	SBIC PINB,5 
	RJMP SEDM 
	LDI R17,12 
	RET
SEDM:
	CBI PORTD,4 
	RJMP OSM 
	LDI R17,7 
	RET
OSM:
	SBIC PINB,3 
	RJMP DEVET 
	LDI R17,8 
	RET
DEVET:
	SBIC PINB,4 
	RJMP CECKO 
	LDI R17,9 
	RET
CECKO:
	SBIC PINB,5
	RJMP HVEZDICKA
	LDI R17,13
	RET
HVEZDICKA:
	CBI PORTD,5 
	SBIC PINB,2 
	RJMP NULA 
	LDI R17,15 
	RET
NULA:
	SBIC PINB,3 
	RJMP KRIZEK 
	LDI R17,0 
	RET
KRIZEK:
	SBIC PINB,4
	RJMP DECKO
	LDI R17,16 
	RET
DECKO:
	SBIC PINB,5
	RJMP JEDNA
	LDI R17,14
	RET

[editovat] 5. Výkonové spínací prvky, úloha na regulaci ventilátoru, přerušení, uspání procesor

; 
; example fan program for ATmega168 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 "m88def.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	; rezim PWM, 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


[editovat] CV 6 klavesnice, vetracek, PCM

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

.INCLUDE "m88def.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)

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

[editovat] CV 7 - dodělávání programu na větráku, práce spolu s kolegou Markem Štychem

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


[editovat] Domácí úkol 1 - tváří se jako funkční.

Nejsem žádný programátor v AVR se na mě rozsvítilo zelené světýlko, tak to snad bude fungovat tak jak má, ale ruku do ohně za to nedám.

inspiroval jsme se zde na MAM WIKI a i jinde :)

.INCLUDE "m88def.inc"

.equ PWM_interier = 100	; PWMfreq 25  kHz pro osvetleni interieru
.equ PWM_palubka = 64	; PWMfreq 14.3kHz pro osvetleni palubi desky

.org 0x000 
	rjmp zacatek 				; reset vektor
.org 0x00D
	rjmp Time1			; preruseni pri preteceni TMR1
.org 0x001A
	rjmp svetlo_palubka


zacatek: 

	ldi r17,high(RAMEND); Main program start
	out SPH,r17 ; Set Stack Pointer to top of RAM
	ldi r17,low(RAMEND)
	out SPL,r17
	
	cbi DDRC,0		;nastavení vstupu pro dveře
	sbi PORTC,0

	sbi DDRD, 5	        ; PWM output OC0B (PD5 pin)
	sbi DDRD, 6	        ; PWM output OC0B (PD6 pin)	


PWM_inter:
 	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_interier	; load number of clock pulses for 1 PWM period
	out OCR0A, R17 

	
PWM_palub:

	ldi r26, PCICR 
	clr r27 
	ldi r17,0b00000010 
	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, PWM_palubka	; load number of clock pulses for 1 PWM period
	st X, R17

spozdeni_inter:

	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_interier: 

	ldi	r16,0b10000011	
	sts	ADCSRA,r16
	ldi	r16,0b01100000	
	sts	ADMUX,r16
	ldi	r16,0b00000000	
	sts	ADCSRB,r16		
	ldi	r16,0b00000001	
	sts	DIDR0,r16

	sei    
	
;nastavení časovače   

	ldi r26, TIMSK1 
	clr r27 
	ldi r16,0b00000001 
	st X, r16               

;nastaveni kontaktu

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

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

	sei 
;sleep setup

	ldi r16,0b00000001 ; Idle mode 
	out SMCR,r16 ; Sleep mode set

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


Time1:
	rcall KEYDOOR
	ldi	r24, 0x2F  

svetlo_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

	ret
	                 

KEYDOOR:
	sbis PINC,0			
	rjmp POHASINANI	
	ldi R16,100			
	mov R17, R16
	sbi DDRD,5
	out OCR0B, R17  ; output pulse "high" lenght to PWM compare unit 

ret

POHASINANI:

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

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


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


[editovat] 7dmi segmentovka v Cčku

#include <avr/interrupt.h>
#include <avr/sleep.h>

#define SER		PD5
#define SRCLK	PD6
#define RCLK	PD7
#define SRCLR	PB0

// global constants and variables
// static code table used for 7-segment led display decoding (common anode)
/*unsigned char code [] = { 0xC0, 0xF9, 0xA4, 0xB0, 0x9B, 0x92, 0x93, 0xF8, 0x80, 0x98,
				 		  0x88, 0x80, 0xC6, 0xC0, 0x86, 0x8E };*/
unsigned char code [] = { 0x3F, 0x06, 0x5B, 0x4F, 0x64, 0x6D, 0xFC, 0x07, 0x7F, 0x67,
				 		  0xF7, 0x7F, 0x39, 0x3F, 0x79, 0x71 };

// character to show on display
static volatile unsigned char anumber = 0;
// Interrupt vector table is created by compiler
// the ISR macro defines interrupt service handlers

// Pin change interrupt 1
// keyboard handler
ISR(PCINT1_vect)
{
	unsigned char keys[10];
	unsigned char nkeys = 0;
	register unsigned char column;

//    DDRD 	&= 0b00000001;
	DDRD	&= 0b11110001;
	PORTD	&= 0b11110000;		// set keyboard rows at port D to zero
	if (!(PINC & 4))
		keys[nkeys++] = 1;
	if (!(PINC & 8))
		keys[nkeys++] = 2;
	if (!(PINC & 16))
		keys[nkeys++] = 3;

	DDRD	&= 0b11110000;
	DDRD	|= (1 << PD1);
	PORTD	&= 0b11110000;		// set keyboard rows at port D to zero
	if (!(PINC & 4))
		keys[nkeys++] = 4;
	if (!(PINC & 8))
		keys[nkeys++] = 5;
	if (!(PINC & 16))
		keys[nkeys++] = 6;

	DDRD	&= 0b11110000;
	DDRD	|= (1 << PD2);
	PORTD	&= 0b11110000;		// set keyboard rows at port D to zero
	if (!(PINC & 4))
		keys[nkeys++] = 7;
	if (!(PINC & 8))
		keys[nkeys++] = 8;
	if (!(PINC & 16))
		keys[nkeys++] = 9;

	DDRD	&= 0b11110000;
	DDRD	|= (1 << PD3);
	PORTD	&= 0b11110000;		// set keyboard rows at port D to zero
	if (!(PINC & 8))
		keys[nkeys++] = 0;

	DDRD 	|= 0b00001111;		// configure rows as outputs
	PORTD 	&= 0b11110000;		// set keyboard rows at port D to zero

	if (nkeys > 0) {
		OCR1A = keys[0] * 100;
		TCNT1 = 0;
	}
}

// Timer/Counter1 Compare Match A
// the value shown on the display will be updated here
ISR(TIMER1_COMPA_vect)
{
	unsigned char tmp = code[anumber];
	volatile char loopcounter = 8;

	do {
		PORTD &= ~(1 << SRCLK);			// assert 0 on serial clock line
		if (tmp & 0x80)					// test LSB
			PORTD |= (1 << SER);		// if 1, assert 1 on serial data line
		else
			PORTD &= ~(1 << SER);		// assert 0 otherwise
		PORTD |= (1 << SRCLK);			// assert 1 on serial clock line - rising edge writes bit into the serial shift register
		tmp <<=  1;					// shift right to proceed next bit
		loopcounter--;
	} while (loopcounter > 0); 
	PORTD &= ~(1 << RCLK);				// toggle parallel register clock 0-1 to make a rising edge
	PORTD |= (1 << RCLK);
	
	// update value to display for next time
	if (anumber < 15)
	    anumber++;
	else
		anumber = 0;
}

void main(void)
{
	// keyboard (and serial shift register connection) ports init
	DDRD 	|= 0b11101111;		// configure rows as outputs (PD0 ... PD3), serial shift register pins PD5 .. PD7
	PORTD 	= 0;				// set port D to zero
	DDRC	= 0;				// configure port C as input port
	PORTC	|= 0b00011100;		// activate pul-up resistors on three columns

	DDRB	|= (1 << SRCLR);	// configure PB0 as output - serial shoft register clear
	PORTB	|= (1 << SRCLR);	// toggle PB0 1-0-1 to clear the serial shift register
	PORTB	&= ~(1 << SRCLR);
	PORTB	|= (1 << SRCLR);

	// an interrupt masking must be here
	// keyboard interrupt
	PCICR 	= (1 << PCIE1);		// Pin change interrupt control register, Pin change interrupt enable 1
	PCMSK1 	= 0b00011100;		// allow pin change interrupt on portC bits 2,3,4

	// timer configuration
	TCCR1A	= 0;				// OC1A/OC1B disconnected, CTC bits WGM11, WGM10
	TCCR1B 	= (1 << CS12) | (1 << CS10) | (1 << WGM12);
								// CTC mode, prescaler division factor 1024
	OCR1A 	=  976;				// timer compare value

	TIMSK1 = (1 << OCIE1A);		// enable timer interrupt

	set_sleep_mode(SLEEP_MODE_IDLE);
	sei();						// set Global Interrupt Enable!!!

	while (1) {
		sleep_cpu();
	}
}

funkční i ukazuje :)

Osobní nástroje