Uživatel:Trisktom

Z MAM wiki

(Rozdíly mezi verzemi)
Přejít na: navigace, hledání
 
Řádka 1 019: Řádka 1 019:
unsigned char casovac;
unsigned char casovac;
unsigned char doba;
unsigned char doba;
 +
unsigned char poceturychleni;
int main() {
int main() {
Řádka 1 027: Řádka 1 028:
ADCSRB=0b000;
ADCSRB=0b000;
-
while(1){
+
  while(1){
-
if(kopancu<10){
+
    if(poceturychleni<10){
-
_delay_ms(5);
+
  _delay_ms(5);
-
continue;
+
  continue;
 +
  }
 +
    if(predeslahodnota<ADCL){
 +
  vzestup=1;
 +
  predeslahodnota=ADCL;
 +
}
 +
    if(predeslahodnota==ADCL){
 +
  vzestup=1;
 +
  predeslahodnota=ADCL;
 +
}
 +
    if(predeslahodnota>ADCL){
 +
  vzestup=1;
 +
  predeslahodnota=ADCL;
 +
}
 +
    if ((pokles==1)&&(pomocna==1)){
 +
  pokles=0;
 +
  vzestup=0;
 +
  pomocna=0;
 +
  kmit();
 +
}
 +
  }
 +
 
}
}
-
if(predeslahodnota<ADCL){
+
 
-
vzestup=1;
+
void kmit(){
-
predeslahodnota=ADCL;
+
  if (casovac==0){  
-
}
+
    TCCR0A=0b10;
-
if(predeslahodnota==ADCL){
+
    TCCR0B=0b100;
-
vzestup=1;
+
    TIMSK0=0b10;
-
predeslahodnota=ADCL;
+
    casovac=1;
-
}
+
  } else {  
-
if(predeslahodnota>ADCL){
+
    TCCR0B=0;
-
vzestup=1;
+
    doba=TCNT0;
-
predeslahodnota=ADCL;
+
    casovac=0;
-
}
+
    OCR0A=doba; 
-
if ((pokles==1)&&(pomocna==1)){
+
    urychleni();  
-
pokles=0;
+
  }
-
vzestup=0;
+
-
pomocna=0;
+
-
kmit();
+
}
}
 +
void urychleni(){
 +
  PORTD|= (1<<PD0);
 +
  _delay_ms(1);
 +
  PORTD&= ~(1<<PD0);
 +
  OCR0A=OCR0A-1;
}
}
 +
ISR(TIMER0_COMP_vect){
 +
  urychleni();
 +
  TCNT0=0;
 +
  poceturychleni++;
}
}
-
void kmit(){
 
-
if (casovac==0){
 
-
TCCR0A=0b10;
 
-
TCCR0B=0b100;
 
-
TIMSK0=0b10;
 
-
casovac=1;
 
-
} else {
 
-
TCCR0B=0;
 
-
doba=TCNT0;
 
-
casovac=0;
 
-
OCR0A=doba;
 
-
}
 
-
}
 
</pre>
</pre>
Čerpáno od kolegy z minulého roku.([http://noel.feld.cvut.cz/vyu/a2m99mam/index.php/U%C5%BEivatel:Kacermar Kacerma])
Čerpáno od kolegy z minulého roku.([http://noel.feld.cvut.cz/vyu/a2m99mam/index.php/U%C5%BEivatel:Kacermar Kacerma])

Aktuální verze z 16. 5. 2013, 07:02

Blikání LEDky + klávesnice






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



PWM ventilátor s klávesnicí ze cvičení


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

Ventilátor s klávesnicí 2


 .include "m88def.inc"

  .org 0x0000 
  rjmp start             
  .org 0x0004 
  rjmp klavesa		   
	
start:
	cbi DDRC,0					
	cbi DDRC,1				
	cbi DDRC,2				
	cbi DDRC,3					

	sbi PORTC,0 
	sbi PORTC,1
	sbi PORTC,2
        sbi PORTC,3
	
	sbi DDRD,0					
	sbi DDRD,1					
	sbi DDRD,2			
	sbi DDRD,3
	 
	cbi PORTD,0		 
	cbi PORTD,1
	cbi PORTD,2
	cbi PORTD,3			

	ldi R26,PCICR 		
	clr R27		  		
	ldi R16,0b00000011 	
	st X, R16 			

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

	sei 				
						

	ldi R16,0b00110011  	
							
	out TCCR0A,R16      	
	
	ldi R16,0b00000001  	
	out TCCR0B,R16      	
	ldi R16,0x7F        		                    	
	out OCR0B,R16
	sbi DDRD,5          	

smycka:
	nop
	out OCR0B,R16
	rjmp smycka


klavesa:					
	in R17,OCR0B  
							
key0:
	;sbi PORTD,0							
	;sbi PORTD,1
	;sbi PORTD,2
	;cbi PORTD,3
	
	cbi DDRD,0				
	cbi DDRD,1
	cbi DDRD,2
	sbi DDRD,3
	cbi PORTD,3
			
	sbic PINC,1     		
	rjmp key1		   		
	ldi R16,0				
	rjmp keyret     		
								
				
key1:
	;cbi PORTD,0	
	;sbi PORTD,1	
	;sbi PORTD,2
	;sbi PORTD,3

	cbi DDRD,1			
	cbi DDRD,2
	cbi DDRD,3
	sbi DDRD,0
	cbi PORTD,0

	sbic PINC,0
	rjmp key2
	ldi R16,28
	rjmp keyret
				
key2:	
        sbic PINC,1
	rjmp key3
	ldi R16,59
	rjmp keyret

				
key3:
	sbic PINC,3
	rjmp key4
	ldi R16,87
	rjmp keyret

key4:
	;sbi PORTD,0
	;cbi PORTD,1	
	;sbi PORTD,2
	;sbi PORTD,3	

	cbi DDRD,0				
	cbi DDRD,2
	cbi DDRD,3
	sbi DDRD,1
	cbi PORTD,1

	sbic PINC,0
	rjmp key5
	ldi R16,115	
	rjmp keyret

					
key5:
	sbic PINC,1
	rjmp key6
	ldi R16,143
	rjmp keyret

					
key6:
	sbic PINC,2
	rjmp key7
	ldi R16,171
	rjmp keyret

key7:
	;sbi PORTD,0
	;sbi PORTD,1
	;cbi PORTD,2	
	;sbi PORTD,3
	
	cbi DDRD,0		
	cbi DDRD,1
	cbi DDRD,3
	sbi DDRD,2
	cbi PORTD,2
		
	sbic PINC,0
	rjmp key8
	ldi R16,199
	rjmp keyret

					
key8:
	sbic PINC,1
	rjmp key9
	ldi R16,227
	rjmp keyret

key9:
	sbic PINC,2
	rjmp keyret
	ldi R16,255
	rjmp keyret
	
keyret:
					
	
	sbi DDRD,0				
	sbi DDRD,1
	sbi DDRD,2
	sbi DDRD,3
	
	cbi PORTD,0				
	cbi PORTD,1
	cbi PORTD,2
	cbi PORTD,3


	out OCR0B,R16         		

	;pop r16               		
	reti 		     		


Sedmisegmentovka

;-----------INICIALIZACE----------

.INCLUDE "m88def.inc"

.EQU RES = 0
.EQU OUT_ENABLE = 1
.EQU INPUT = 2
.EQU SHIFT_CLK = 3
.EQU STORE_CLK = 4

.ORG 0x000 
	rjmp main ; 

.ORG 0x003 
	rjmp stisk ; přerušení vyvolané klávesnicí


main: 
	ldi r16,high(RAMEND)  ;nastavení zásobníku??
	out SPH,r16
	ldi r16,low(RAMEND)
	out SPL,r16

;aktivace sleep modu
	ldi r16,0b00000001
	out SMCR,r16
	
	clr r16  ;vynulvání používaných registrů - pro jistotu
	ldi r17,0b00001000 ;osmicka pro dekrementaci při sériovém plnění posuvného reg.
	clr r18  ;pro porovnávání předchozího registru



;---------NASTAVENÍ PŘERUŠENÍ--------------


;nastavim přerušení PCINT0, piny PCINT0-7, vektor 003
	ldi r26, PCICR 		
	clr r27 			
	ldi r16,0b00000001 	
	st X, r16 			

;aktivuju pin PB1 jako aktivní pro přerušení klávasnicí
	ldi r26, PCMSK0
	clr r27
	ldi r16,0b00000010  
	st X, r16
	sei 

; na pinu B1 čtení, na pinu B0 buzení nulou
	cbi DDRB,1
	sbi PORTB,1
	sbi DDRB,0
	cbi PORTB,0



;---------NASTAVENÍ KOMUNIKACE S SHIFT REGISTREM---------------


; nastavení bitů komunikujících s registrem
	sbi DDRC,0
	sbi DDRC,1
	sbi DDRC,2
	sbi DDRC,3
	sbi DDRC,4

	CBI PORTC,RES
	SBI PORTC,RES
	CBI PORTC,OUT_ENABLE
	CBI PORTC,INPUT
	CBI PORTC,SHIFT_CLK
	CBI PORTC,STORE_CLK



;---------STAV DISPLEJE PO RESETU----------------

	ldi r16,0b11000000 ;nula na sedmisegmentovce (spol. anoda = inverzní)
	rcall zapis_znak

;----------- ...TADY JÁ BUDU SKORO FURT... ---------------

spat:
	sleep 
	nop 
	rjmp spat


;-------------PROCEDURY---------------

;prohození nuly a jedničky na 7segmentovce v registru r16
urci_znak:
	ldi r19,0b11000000
	cpse r16,r19
	rjmp zmen_znak1
	rjmp zmen_znak2
zmen_znak2:
	ldi r16,0b11111001
	ret
zmen_znak1:
	ldi r16,0b11000000
	ret

	
; zapsání znaku 7segmentovky do posuvného registru a zobrazení
zapis_znak:
	cbi PORTC,OUT_ENABLE
	ror r16
	brcs jedna ;podprogram pro zápis 1 do shift
	brcc nula  ;podprogram pro zápis 0 do shift
zpet:
	dec r17		;Dekrementuje registr kde je 9
	cpse r17,r18  ;až proběhne 8krát, bude R17 = 0 (=r18) a přestane se opakovat zápis
	rjmp zapis_znak
	sbi PORTC,STORE_CLK
	cbi PORTC,STORE_CLK	
	sbi PORTC,OUT_ENABLE
	ror r16
	ldi r17,0b00001000
	ret
jedna:
	SBI PORTC,INPUT
	SBI PORTC,SHIFT_CLK
	CBI PORTC,SHIFT_CLK
	rjmp zpet
nula:
	CBI PORTC,INPUT
	SBI PORTC,SHIFT_CLK
	CBI PORTC,SHIFT_CLK
	rjmp zpet


;----------------OBSLUHA PŘERUŠENÍ-----------

stisk:
	rcall urci_znak
	rcall zapis_znak
	reti


1. domácí úkol

.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

Obsah

[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] Schéma:

Soubor:schemakyvadlo.jpg

[editovat] Komentář k programu:

V návrhu využíváme A/D převodník ke sledování napětí na portu PC0(neboli ADC0). Hledáme maximum tohoto napětí. V okamžiku, kdy je nalezeno maximum je spuštěn časovač a v okamžiku, kdy je opět nalazeno maximum, je tento časovač vypnut. Výstupem je časový údaj charakterizující jeden kyvy(tzn. polovinu periody).

Pokud chceme magnet urychlovat je nutné, abychom ve vhodném okamžiku(pokles z maxima) poslali skrze port PD0 logickou 1, a tím indukovali magnetické pole v cívce. To způsobí urychlení kyvu magnetu.


Při použití kusu železa nelze detektovat kyv, protože železo samo o sobě neprodukuje magnetické pole. Lze ho však urychlovat stejně jako v minulém případě(PD0 do logické 1).

[editovat] Kód:

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

unsigned char predeslahodnota;
unsigned char vzestup;
unsigned char pokles;
unsigned char pomocna;
unsigned char casovac;
unsigned char doba;
unsigned char poceturychleni;

int main() {
DDRD |= (1<<PD0);
PORTD&= ~(1<<PD0);
ADMUX= 0b01000000;
ADCSRA=0b11000001;
ADCSRB=0b000;

  while(1){
    if(poceturychleni<10){
	  _delay_ms(5);
	  continue;
	  }
    if(predeslahodnota<ADCL){
	  vzestup=1;
	  predeslahodnota=ADCL;
	}
    if(predeslahodnota==ADCL){
	  vzestup=1;
	  predeslahodnota=ADCL;
	}
    if(predeslahodnota>ADCL){
	  vzestup=1;
	  predeslahodnota=ADCL;
	}
    if ((pokles==1)&&(pomocna==1)){ 
	  pokles=0;
	  vzestup=0;
	  pomocna=0;
	  kmit();
	}
  }

}

void kmit(){
  if (casovac==0){ 
    TCCR0A=0b10;
    TCCR0B=0b100;
    TIMSK0=0b10;
    casovac=1;
  } else { 
    TCCR0B=0;
    doba=TCNT0;
    casovac=0;
    OCR0A=doba;  
    urychleni(); 
  }
}
void urychleni(){
  PORTD|= (1<<PD0);
  _delay_ms(1);
  PORTD&= ~(1<<PD0);
  OCR0A=OCR0A-1;
}

ISR(TIMER0_COMP_vect){
  urychleni();
  TCNT0=0;
  poceturychleni++;
}

Čerpáno od kolegy z minulého roku.(Kacerma)

Osobní nástroje