Tikovský Vojtěch, Tříska Tomáš, Řehák Ota: Kyvadlo

Z MAM wiki

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

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 kyv(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). Bohužel ho nelze urychlovat koncepčně, ale lze to provádět pouze náhodně.

[editovat] Kod(Cecko):

#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++;
}

[editovat] Kod(Assembler):

.INCLUDE "m88def.inc"

	.EQU PORTC = $17
	.EQU PORTC = $18	
	.EQU DDRD = $17	
	.EQU PORTD = $18	


Main: 
	cbi DDRC,0  
	cbi PORTC, 0 ;
	cbi DDRC,1; 
	cbi PORTC,1 ;

	sbi DDRD, 0 ;
	cbi PORTD, 0	
	ldi r16,high(RAMEND); Main program start
	out SPH,r16 ; Set Stack Pointer to top of RAM
	ldi r16,low(RAMEND)
	out SPL,r16

	ldi r16,0b01000000;
	out ADMUX,r16;
	ldi r16,0b11000001;
	out ADCSRA,r16;
	ldi r16,0b000;
	out ADCSRB,r16;
	ldi r16,0b00000001 ; 
	out SMCR,r16 ; 
	RCALL	hledanimaxima
	
	rjmp Main ; 



loop:
	sleep ; 
	nop ; 
	rjmp loop ; 


hledanimaxima:
	ldi r15,r16;
	ldi r16,ADCL ; 
	brge r15,r16 ;
	SBIC PORTC,1;
	out r12,TCNT0;

        SBIC PORTC,1;
        out TCCR0B,0b00000000;

	SBIC PORTC,1;
	cbi PORTC,1;

	SBIC PORTC,1;
	break;

	RCALL	casovac
	
	ret ; 

casovac:
	out TCCR0A,r14;
	ldi r14,0b100;
	out TCCR0B,r14;
	ldi r14,0b10;
	out TIMSK0,r14;
	sbi PORTC,1;
	ret;

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

Osobní nástroje