Uživatel:Kacermar

Z MAM wiki

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

Obsah

[editovat] Blikajici LEDKA

2. cv.

   .EQU DDRB = $17		; DDRB address
	.EQU PORTB = $18	; PORTB address

	.EQU LED_X = 0		; LED_X is on PB0, pin 12 of ATtiny2313
			

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

	SBI	DDRB, LED_X	; SBI - Set Bit in I/O Register
HOP:	
	SBI PORTB, LED_X
    RCALL CEKEJ
	CBI PORTB, LED_X
	RCALL CEKEJ
    RJMP HOP

CEKEJ: 
	LDI	R16, 4			; LDI - Load Immediate
WAIT1:	INC	R1
	BRNE	WAIT1
	INC	R2
	BRNE	WAIT1
	DEC	R16
	BRNE	WAIT1
	RET
	

[editovat] LED show program

3.cv.

; Color1 shines when LED_X is high and LED_Y is low
; Color2 shines when LED_Y is high and LED_X is low
;.EQU DDRB=$17
;.EQU PORTB=$18 ;addresses

.include "tn2313def.inc"

.EQU LED_X=0 ; LED_X is on PB0
.EQU LED_Y=1 ; LED_Y is on PB1

;Pins connected to LED are outputs:
SBI DDRB, LED_X
SBI DDRB, LED_Y
CBI DDRD, 5
SBI PORTD, 5

SHOW:
        RCALL COLOR1 ; 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

	SBIS PIND,5 
	RCALL	COL3W
	
	RCALL	WAIT
	RCALL	WAIT
	RCALL	WAIT

	RCALL	DARK
	RCALL	WAIT
	
	RJMP SHOW		; RJMP - Relative Jump 

; PROCEDURES

SMALLWAIT:
        INC R1 ; increment
	BRNE SMALLWAIT ; Branch if not equal
	RET ; return from subroutine

WAIT:
	LDI R16,4 ; 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
	RET
COLOR2:
	SBI PORTB, LED_Y
	CBI PORTB, LED_X
	RET
COL3W:
        LDI R16,2
COL3X:
        RCALL	COLOR1
	RCALL	SMALLWAIT
	RCALL	COLOR2
	RCALL	SMALLWAIT
	RCALL	SMALLWAIT
	RCALL	SMALLWAIT
	INC	R2
	BRNE	COL3X
	DEC	R16
	BRNE	COL3X
DARK:
    CBI	PORTB, LED_X
    CBI	PORTB, LED_Y
    RET

[editovat] Maticova klavesnice

4.cv.

    .EQU DDRC = $07
	.EQU PORTC = $08
	.EQU PINC = $06
.include "tn2313def.inc"
.EQU LED_X=0 ; LED_X is on PB0
.EQU LED_Y=1 ; LED_Y is on PB1	
	
	
TLAC1:  SBI DDRD, 0 ;testujeme c.1
	SBI PORTC, 2 ;enables pull-up rezistor on this pin
	
	SBIS	PINC, 2
	RJMP TLAC5
	RJMP GO

TLAC5:	SBI DDRD, 1 ; testujeme c.5
	SBI PORTC, 3 ;enables pull-up rezistor on this pin
	
	SBIS	PINC, 3
	RJMP TLAC1
	RJMP GO
GO:
	RCALL   COLOR1
	RCALL	WAIT
	SBIS	PINC, 2
	RCALL	COLOR2
	RCALL	WAIT
	RJMP	GO
WAIT:
	LDI R16,4 ; 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
	RET
COLOR2:
	SBI PORTB, LED_Y
	CBI PORTB, LED_X
	RET

[editovat] Regulace ventilátoru 1

cv.5

Popis:
Při stisku tlacitka 1 na maticové klávesnici běží větráček naplno, při stisknutí 3 je vypnutý a při stisku 2 je regulován.
Zdrojový kód:

        .EQU DDRB = $17		; DDRB odkaz na konfiguracní registr (Nastaveni portu I/O)
	.EQU PORTB = $18	; PORTB odkaz na konfiguracní registr (Nastaveni hodnoty na danem portu)
	.EQU PINB = $16       

	.EQU DDRD = $11         ; DDRD odkaz na konfiguracní registr (Nastaveni portu I/O)
	.EQU PORTD = $12

	.EQU PD0=0
	.EQU PD1=1
	.EQU PD2=2
	.EQU PD3=3


	.EQU PB0=0
	.EQU PB1=1
	.EQU PB2=2
	.EQU PB3=3
	
	.EQU PB7=7



	SBI	DDRB, PB7       ; Nastavení portu PB7 jako vystup


	CBI	DDRD, PD0       ;Porty D vstupní
	CBI	DDRD, PD1
	CBI	DDRD, PD2
	CBI	DDRD, PD3

	CBI PORTD, PD0          ;Bez pull up resistoru
	CBI PORTD, PD1
	CBI PORTD, PD2
	CBI PORTD, PD3

        CBI	DDRB, PB0       ;Porty D vstupni
	CBI	DDRB, PB1
	CBI	DDRB, PB2
	CBI	DDRB, PB3

	SBI PORTB, PB0          ;Pull up resistory
	SBI PORTB, PB1
	SBI PORTB, PB2
	SBI PORTB, PB3


;*******************************************
MAIN:
	RCALL ROW1
	SBIS PINB, PB0
	RCALL PLNA

	RCALL ROW1
	SBIS PINB, PB1
	RCALL PULKA
	
	RCALL ROW1
	SBIS PINB, PB2
	RCALL VYP


RJMP MAIN

ROW1:
	SBI DDRD, PD0       ;Port PD0 vystup
	CBI PORTD, PD0      ;0 na portu PD0
	CBI DDRD, PD1       ;Ostatni vstupni (Stav velke impedance)
	CBI DDRD, PD2
	CBI DDRD, PD3
RET

ROW2:
	CBI DDRD, PD0
	SBI DDRD, PD1
	CBI PORTD, PD1
	CBI DDRD, PD2
	CBI DDRD, PD3
RET

ROW3:
	CBI DDRD, PD0
	CBI DDRD, PD1
	SBI DDRD, PD2
	CBI PORTD, PD2
	CBI DDRD, PD3
RET

ROW4:
	CBI DDRD, PD0
	CBI DDRD, PD1
	CBI DDRD, PD2
	SBI DDRD, PD3
	CBI PORTD, PD3
RET

PLNA:
	SBI PORTB, PB7
RET

VYP:
	CBI PORTB, PB7
RET

PULKA:
	SBI PORTB, PB7
	RCALL VERYSMALLWAIT
	RCALL VERYSMALLWAIT
	CBI PORTB, PB7
	RCALL VERYSMALLWAIT
	RCALL VERYSMALLWAIT
	RCALL VERYSMALLWAIT
	RCALL VERYSMALLWAIT
	RCALL VERYSMALLWAIT


	SBIS PINB, PB0
	RCALL MAIN

	SBIS PINB, PB2
	RCALL MAIN


RJMP PULKA

VERYSMALLWAIT:
	LDI R20, 0xFC
	MOV R1, R20
RET

[editovat] Vetracek s prerusenim

cv.6

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


; 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

        	
	.EQU PB7=7



	SBI	DDRB, PB7       ; Nastavení portu PB7 jako vystup


	
;*******************************************
MAIN:
	RCALL ROW1
	SBIS PINB, PB0
	RCALL PLNA

	RCALL ROW1
	SBIS PINB, PB1
	RCALL PULKA
	
	RCALL ROW1
	SBIS PINB, PB2
	RCALL VYP


RJMP MAIN

ROW1:
	SBI DDRD, PD0       ;Port PD0 vystup
	CBI PORTD, PD0      ;0 na portu PD0
	CBI DDRD, PD1       ;Ostatni vstupni (Stav velke impedance)
	CBI DDRD, PD2
	CBI DDRD, PD3
RET

ROW2:
	CBI DDRD, PD0
	SBI DDRD, PD1
	CBI PORTD, PD1
	CBI DDRD, PD2
	CBI DDRD, PD3
RET

ROW3:
	CBI DDRD, PD0
	CBI DDRD, PD1
	SBI DDRD, PD2
	CBI PORTD, PD2
	CBI DDRD, PD3
RET

ROW4:
	CBI DDRD, PD0
	CBI DDRD, PD1
	CBI DDRD, PD2
	SBI DDRD, PD3
	CBI PORTD, PD3
RET

PLNA:
	SBI PORTB, PB7
RET

VYP:
	CBI PORTB, PB7
RET

PULKA:
	SBI PORTB, PB7
	RCALL VERYSMALLWAIT
	RCALL VERYSMALLWAIT
	CBI PORTB, PB7
	RCALL VERYSMALLWAIT
	RCALL VERYSMALLWAIT
	RCALL VERYSMALLWAIT
	RCALL VERYSMALLWAIT
	RCALL VERYSMALLWAIT


	SBIS PINB, PB0
	RCALL MAIN

	SBIS PINB, PB2
	RCALL MAIN


RJMP PULKA

VERYSMALLWAIT:
	LDI R20, 0xFC
	MOV R1, R20
RET

[editovat] 1.DU(nejsem autor)

cv.10

.NOLIST
.INCLUDE "m88def.INC"
.LIST

;PORTC
.EQU Button = 0				; na PC0 tlacitko, spina pull-up rezistor na zem.
.EQU Trimmer = 1 			; vstup z trimru, komparator ADC1

;PORTD
.EQU Light = 0				; port PD0 ovlada osvetleni interieru
.EQU Board = 1				; port PD1 ovlada osvetleni palubovky

;NADEFINOVANI REGISTRU
.DEF Temp = r16				; docasny registr pro prenos hodnot		
.DEF PWM_In = r17			; hodnota PWM pro osvetleni interieru
.DEF PWM_Board = r18		; hodnota PWM pro palubni desku
.DEF Symptoms = r19			; registr priznaku
.DEF T5 = r20				; citac pro 5s osvetleni interieru
.DEF T2 = r21				; citac pro postupne zhasinani behem 2s

;SYMPTOMS
.EQU S_Timer1 = 0			; bit0 registru Symptoms rika, zda doslo k preruseni od Timer1
.EQU S_In_ON = 1			; bit1, zda sviti svetlo interieru
.EQU S_Second = 2			; bit2, zda probiha druhy cyklus citani registru T5 
.EQU S_Twilight = 3			; bit3, zda probiha 2s proces stmivani

;KONSTANTY PRO PWM
.EQU PWM_In_Pulse = 40		; PWMfreq 25 kHz pro osvetleni interieru
.EQU PWM_Board_Pulse = 36	; PWMfreq 27,8kHz pro osvetleni palubi desky
	
;RESET A INTERUPTION VEKTORY
.ORG 0x000 
	RJMP START 				; reset vektor
.ORG 0x00D
	RJMP Timer1_Over		; preruseni pri preteceni Timer1

;PORTY
	LDI Temp, 0b11111100	; PC0 je vstup ADC a PC0 je vstup pro Button
	OUT DDRC, Temp			; 
	LDI Temp, 0b00000001	; vystupy do 0 a interni pull-up pro PC0
	OUT PORTC, Temp			; 
	SER Temp				; PORTD a PORTB jako vystupy 
	OUT DDRD, Temp			; 
	OUT DDRB, Temp			; 
	CLR Temp				; PORTD a PORTB nastavit do 0
	OUT PORTD, Temp			; 
	OUT PORTB, Temp			


;----------------------------------------------------------------------------------------------------

START:

;inicializace zasobniku 
	LDI Temp,high(RAMEND)		 
	OUT SPH, Temp			
	LDI Temp,low(RAMEND)		
	OUT SPL, Temp	
			 

;----PWM----PWM----PWM----PWM----PWM----PWM----PWM----PWM----PWM----PWM----

;INTERIER

	LDI Temp, 0b00100011		; Fast PWM Mode, OUT on OC0B, non Inverting
	OUT TCCR0A, Temp		 
	LDI Temp, 0b00001001		; WGM2:1 (Fast PWM), CS2..0:001 (internal clock, prescale=1)
	OUT TCCR0B, Temp
	LDI Temp, PWM_In_Pulse		; load number of clock pulses for 1 PWM period
	OUT OCR0A, Temp

	IN  Temp, TCCR0A			; odpojeni vystupu od PWM generatoru (standartni vystup v 0) 
	CBR Temp, 0x10		
	OUT TCCR0A, Temp			; 

;BOARD

	LDI Temp, 0b00100011		; Fast PWM Mode, OUT on OC0B, non Inverting
	STS TCCR2A, Temp			; 
	LDI Temp, 0b00001001		; WGM2:1 (Fast PWM), CS2..0:001 (internal clock, prescale=1)
	STS TCCR2B, Temp			; 
	LDI Temp, PWM_Board_Pulse	; load number of clock pulses for 1 PWM period
	STS OCR2A, Temp				; 

;ADC			
	LDI Temp, 0b11100000		; Vniřtní reference 1,1V, kapacitor na AREF,zarovnání Left, ADC0
	STS ADMUX, Temp				; 
	LDI Temp, 0b10000100		; ADC enabled, int. off, autotriger off, prescaler 16 (62,5kHz)
	STS ADCSRA, Temp			; 
	CLR Temp					; deaktivace autotrigeru
	STS ADCSRB, Temp			; 
	LDI Temp, 0x02				; disable digital input buffer for pin ADC1 (snizeni spotreby)
	STS DIDR0, Temp				; 

;PRERUSENI OD Timer1
	LDI Temp, 0xD8				; nastavi Timer1 na 10000 (10E+4 * 1us = 10ms)
	STS TCNT1H, Temp		
	LDI Temp, 0xF0		
	STS TCNT1L, Temp			; 	
	CLR Temp					; CLR TCCR1A
	STS TCCR1A, Temp			; 
	LDI Temp, 0b00000001		; Clock Select -> CLKio/1 (no prescaler)
	STS TCCR1B, Temp			; 
	STS TIMSK1, Temp			; povoleni preruseni pri preteceni Timer1
	SEI							; povoleni preruseni	
	CLR Temp					; vynulovani hodnoty T2
	MOV T2, Temp				; 

;-----MAIN PROGRAM------------------------------------------------------------------------------

Main:
	SBRS  Symptoms, S_Timer1	; bylo preruseni od Timer1?
	RJMP  Main					; NE preskoc testovani tlacitka a ADC, hodnoty PWM se nemeni
	CLT							; ANO, zrus priznak preruseni od Timer1 
	BLD   Symptoms, S_Timer1	; 
	RCALL Butt					; otestuj, zda je stisknute tlacitko
	SBRC  Symptoms, S_In_ON		; sviti interier?
	RCALL Watcher				; ANO, dekrementuj hodnotu T5 nebo T2
	OUT   OCR0B, PWM_In			; nastav PWM interieroveho svetla podle aktualni hodnoty
	RCALL AD_Convert			; zjisti hodnotu napeti z potenciometru
	STS   OCR2B, PWM_Board		; nastav PWM svetla palubni desky podle aktualni hodnoty
	RJMP  Main


;-----SECONDARY FUNCTIONS---------------------------------------------------------------------------------------------

Timer1_Over:					; ulozeni Status registru do zasobniku
	PUSH Temp					;
	IN   Temp, SREG				;
	PUSH Temp					; reinicializace Timer1
	LDI  Temp, 0xD8				; nastav Timer1 na hodnotu 10000 (10E+4 * 1us = 10ms)	
	STS  TCNT1H, Temp		
	LDI  Temp, 0xF0			
	STS  TCNT1L, Temp			; 
	SET							; nastav priznak, ze doslo k preruseni od Timer1 
	BLD  Symptoms, S_Timer1		; 								
	POP  Temp					; obnoveni Status registru ze zasobniku pro navrat z preruseni
	OUT  SREG, Temp		
	POP  Temp		 			; 
	RETI

Butt:							; testovani tlacitka
	SBIC PINC, Button			; je tlacitko stisknute?
	RET							; NE, ukonci testovani tlacitka
	SET				  			; ANO, nastav priznak, ze interier sviti
	BLD Symptoms, S_In_ON	;
	LDI PWM_In, PWM_In_Pulse 	; PWM na nejvetsi stridu	
	IN  Temp, TCCR0A		  	; pripojeni PWM generatoru na vystup
	SET				
	BLD Temp, 5			
	OUT TCCR0A, Temp		  	; 
	LDI Temp, 0xFF			  	; ulozi do T5 hodnotu 255
	MOV T5, Temp		  		; 
	CLT				 			; 
	BLD Symptoms, S_Second 		; vynuluj priznak Second - nedoslo k druhemu pricitani T2
	BLD Symptoms, S_Twilight	; neprobiha proces stmivani
	RET

Watcher:
	SBRC Symptoms, S_Twilight	; bezi proces Twilight?
	RJMP Twilight				; ANO, prejdi na Twilight
	DEC  T5						; NE, bezi 5s plneho svitu, dekrementuj T5
	BRNE Return 				; kdyz neni nula, konec
	SBRC Symptoms, S_Second		; kdyz je nula, bezel uz druhy cyklus?
	RJMP Twilight				; ANO, skoncilo 5s plneho svitu, zacni stmivat
	SET							; NE, nastav priznak, ze T5 jde znovu
	BLD  Symptoms, S_Second		; 
	RJMP Return					; 

Twilight: 	
	SET							; nastaveni priznaku, ze odted dochazi ke stmivani
	BLD Symptoms, S_Twilight	; 		
	INC  T2						; zvys hodnotu T2, hodnota 10 -> 100ms
	MOV  Temp, T2				; T2 nejde porovnat primo instrukci CPI (r1)
	CPI  Temp, 0x0A				; testuj na 10
	BRNE Return					; kdyz neni 10, nic se nedeje
	CLR  Temp					; kdyz je 10, zacni znova
	MOV  T2, Temp				; 
	SUBI PWM_In, 0x02			; odecti hodnotu 2 od aktualniho svitu (20 kru)
	TST  PWM_In					; otestuj, zda doslo k nule?
	BRNE Return					; NE, vrat se zpet
	CLT							; ANO, stmivani dokonceno (interier je zhasnuty)
	BLD  Symptoms, S_In_ON		; zrus priznak stmivani 

	IN  Temp, TCCR0A			; odpojeni vystupu od PWM generatoru (standartni vystup v 0)
	CLT				
	BLD Temp, 5 				; CLR 5.bit
	OUT TCCR0A, Temp			; 

AD_Convert:
	CLR Temp					; odstran vysledek posledniho prevodu
	STS ADCH, Temp				; 
	LDS Temp, ADCSRA			; prekopiruj ADCSRA do Temp
	SET							; nastav 6.bit, tj. zacatek AD prevodu
	BLD Temp, 6					; 
	STS ADCSRA, Temp			; spusteni AD prevodu

AD_Run:
	LDS  Temp, ADCSRA			; prekopiruj ADCSRA do Temp
	SBRC Temp, 6				; je ADSC nastaven?
	RJMP AD_Run					; ANO, testuj znovu
								; NE, prevod skoncil, vysledek ulozen do ADCH

; uprava vysledku pro pouziti v PWM
	LDS Temp, ADCH				; hodnotu H bytu z AD prevodu do Temp
	LSR Temp					; /2
	LSR Temp					; /2
	LSR Temp					; /2
	MOV PWM_Board, Temp			; hodnota ADCH/8 do PWM_Board
	LDI Temp, 0x04				;
	ADD PWM_Board, Temp			; pricte k PWM_Board 4
	RET

Return:
	RET

cv11

#include <avr/io.h>
  /*20b adresy; 2 na 20; 20=15+5->PB4...0
  AND &
  OR | */
zapis(long int adresa,unsigned char data){
PORTB=(adresa & 0xF0000L) >> 15;	/* posun doprava */
/*PORTB = (adresa) >> 16; 	z logiky veci muzeme i takto - nulujeme 16 spodnich bitu */
*(unsigned char *)(int)(adresa & 0x7FFF | 0x800)=data;
/* 0xFFFF je inverzni k 0xF0000 */
}

main(){
unsigned char d=zapis(45545, 1);
}

//posunuti pameti

//#include <avr/io.h>

//zapis(long int adresa, unsigned char data) {	
	//PORTB = (adresa & 0xF0000L) >> 15;	/* posun doprava */
	/*PORTB = (adresa) >> 16; 	z logiky veci muzeme i takto - nulujeme 16 spodnich bitu */ 
	//*(unsigned char *)(int)(adresa & 0x7FFF | 0x800) = data;  /* 0xFFFF je inverzni k 0xF0000 */
//}

[editovat] Semestrální práce - Kyvadlo

[editovat] Zadání:

Připojte k AVR cívku, která bude detekovat kyv magnetu zavěšeného nad ní a ve vhodných okamžicích magnet urychlovat. Zvažte možnost použít místo magnetu jen kousek železa.


[editovat] Postup:

Takže cívku připojíme na vstupní porty procesoru ATMega168. A budeme sledovat napětí na jednom vstupu. Při kyvu magnetu se v cívce indukuje napětí a to se mění po dobu kyvu. A/D převodníkem budu sledovat průběh napětí a hledat maximum. Až A/D převodník dosáhne maxima budu časovačem měřit čas a až dosáhne znovu maxima hodnotu uložím do proměnné a budu znovu měřit čas až do dosažení dalšího maxima, tuto hodnotu sečtu s předchozí a uložím do proměnné. A mám dobu kyvu. Pokud budu chtít urychlovat magnet, pošlu log.1 na jeden vstup cívky, tím bude cívkou procházet proud a vyvolá se magnetické pole, které magnet přitáhne. Log.1 by se měla poslat na vstup když bude magnet klesat z jedné krajní polohy k maximu a v maximu by se měla zrušit.

Když použiji kus železa místo magnetu tak ho budu moci urychlovat protože cívka vytváří mag. pole a železo by bylo tímto polem přitahováno, ale nezjistím jeho dobu kyvu, čili ani maximum, protože železo nevytváří mag. pole a cívka tedy nemá co snímat, nic se v ní nebude indukovat a tedy ho nemůžu ani urychlovat, protože bych nevěděl kdy poslat log.1 na cívku a tento proces by byl náhodný. Jinou možností by bylo použít cívku s fm. jádrem, železo by tedy uzavíralo mag. obvod cívky a tudíž by vytvořilo malou změnu protékajícího DC proudu. Předpokládám, že změna by byla pod hranicí rozlišitelného napětí ADC převodníkem.


[editovat] Popis nožiček ATMega168:

Soubor:ATMEGA168.png

[editovat] Schéma zapojení sondy kyvadla

Soubor:kacermar-kyvadlo.png

[editovat] Kód v C

#include "avr/io.h"
#include "util/delay.h"
#include "avr/interrupt.h"

unsigned char minula, stoupam, klesam, nic, casovac, doba, kopancu;

int main() {
DDRD |= (1<<PD1);//napajeni civky
PORTD&= ~(1<<PD1);
ADMUX= 0b01000000;
ADCSRA=0b11000001;
ADCSRB=0b000;
//nastaveni prevodniku

  while(1){

	if(kopancu<10){
	  _delay_ms(5);
	  continue;
	  }

    if(minula<ADCL){
	  stoupam=1;
	  minula=ADCL;
	}
    if(minula==ADCL){
	  nic=1;
	  minula=ADCL;
	}
    if(minula>ADCL){
	  klesam=1;
	  minula=ADCL;
	}
    if ((klesam==1)&&(nic==1)){ //klesani /zaporna derivace
	  klesam=0;
	  stoupam=0;
	  nic=0;
	  kmit();
	}

  }//while

}


void kmit(){
  if (casovac==0){ //zapnout casovac
    TCCR0A=0b10;//nastaveni casovace bit c.2 do 1
    TCCR0B=0b100;
	TIMSK0=0b10;
    casovac=1;
  } else { //vypnout casovac
    TCCR0B=0;
    doba=TCNT0;
    casovac=0;
	OCR0A=doba;
	kopni();    
  }
}

void kopni(){
  ;//zapni casovac 0
  PORTD|= (1<<PD1);
  _delay_ms(1);
  PORTD&= ~(1<<PD1);
  OCR0A=OCR0A-1;
}

ISR(TIMER0_COMP_vect){
  kopni();
  TCNT0=0;
  kopancu++;//pocitam kolikrat urychlim magnet
}

Osobní nástroje