Operácie

Kuchynské minutky

Z SensorWiki

Záverečný projekt predmetu MIPS / LS2024 - Ján Ulej


Zadanie

Zostrojte kuchynské minútky. Cez sériovú linku načítajte čas. Po uplynutí času bzučiak zahrá melódiu.

Vývojová doska Arduino Nano.

Literatúra:


Analýza a opis riešenia

Kladný pól reproduktora (bzučiaka) som pripojil na mikroprocesor pin PD6. Ešte som medzi pin PD6 a kladný pól bzučiaka pripojil 220 ohm odpor ktorí slúži na odrušenie šumov ktoré potom vidno na sériovej komunikácii. Tlačidlo som pripojil tiež cez 220 ohm odpor na pin PD7.

Súčiastky.

Schéma zapojenia

Schéma zapojenia bzučiaka a tlačidla.


Algoritmus a program

Použil som knižnicu <uart.h> kde som si dodefinoval funkcie aby mi fungovalo načítavanie a výpis cez sériovú linku. Na načítavanie som použil 'scanf' a na výpis 'printf'. Tiež som použil knižnice <avr/interrupt.h> na prerušenia a <until/delay.h> na oneskorenie. Premenné ktoré som použil v prerušení som zadefinoval ako static volatile. Vytvoril som si prerušenie kde sa mi odčítaval čas. Realizoval som to pomocou 16-bitového počítadla T1. Vytvoril som funkciu 'hudba()' v ktorej som zadefinoval frekvencie a dĺžku jednotlivých tónov. Na generovanie frekvencií na výstupe som použil počítadlo 'Timer0' v režime generátora frekvencie 'CTC'. V hlavnom programe som nastavil tlačidlo ako vstup a zapol pull-up rezistor. Na ukladanie stavu tlačidla som použil dátový typ Enumerate. V hlavnej slučke načítam pomocou sériovej komunikácie čas vo formáte minúty:sekundy. Následne minúty premením na sekundy. Pomocou 'printf' vypisujem čas tiež vo formáte minúty:sekundy. Po uplynutí zvoleného času je zavolaná funkcia 'hudba()'. Skončenie prehrávania hudby a opätovné načítanie času je zabezpečené zatlačením tlačidla.


#include <avr/io.h>
#include "uart.h"
#include <avr/interrupt.h>
#include <util/delay.h>

FILE uart_output = FDEV_SETUP_STREAM(uart_putc, NULL, _FDEV_SETUP_WRITE);
FILE uart_input  = FDEV_SETUP_STREAM(NULL, uart_getc, _FDEV_SETUP_READ); 

static volatile int vstup_minuty = 0;
static volatile int vstup_sekundy = 0;
static volatile int cas = 0;
static volatile int vystup_min = 0;
static volatile int vystup_sek = 0;
static volatile int stop = 0;


#define SW1 PD7		// tlacitko

#define set_bit(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
#define clear_bit(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))


enum states { Off, Down, On, Up };		// stavy tlacitka

ISR (TIMER1_OVF_vect)          
 {
   TCNT1 = 0xC2F7;		// nastavenie pocitadla  
   
   if (cas>=0)
   {
	   cas--;
   }
 }
 
void tone(int note, int delay)
{
	OCR0A = note;
	
	for (int i=1; i<=delay; i++)
     _delay_ms(1);
}

 
void hudba()		// funkcia prehravania melodie
{
	int c = 78;
    int h = 104;
    int p = 0;
		  
    tone(c,250);
	tone(p,50);
	tone(h,250);
	tone(p,250);	  
  
}

                              
int main(void)
{
  uart_init();
  stdout = &uart_output;           // teraz funguje printf()
  stdin = &uart_input;            // teraz funguje scanf()
  
  set_bit(PORTD,SW1);       // zapnutie pull-up rezistora
  clear_bit(DDRD,SW1);     //  nastavenie pinu SW1 ako vstup
  
  enum states Tlacitko = Off;
  
  
  //************************** T1 ***********************//
  
  TCNT1 = 0xC2F7;    
  TCCR1B = 0b00000101;		// externy zdroj hodin na pin T1 reagujuci na nabeznu hranu
  
  
  // konfiguracia prerusovacieho systemu
   PCMSK2 |= (1<<PCINT21);
   PCICR |= (1<<PCIE2);		
   sei();					// povolenie preruseni
	
  // pretecenie
   TIMSK1 = (1<<TOIE1);    // povolenie pretecenia Timer 1
   sei();                  // povolenie preruseni
  
  
 //********************* hudba *************************//
 
   DDRD   |= (1 << PD6);                      // port D.6 pin ako vystup
   TCCR0A =  (1 << COM0A0) | (1 << WGM01);    // Timer 0 v rezime CTC
   TCCR0B = (1 << CS02);                      // nastavenie preddelicky na 256
   
   
   
  while(1)
  {	
	 puts("Zadaj cas (min:sek)\r");
     scanf("%d:%d",&vstup_minuty,&vstup_sekundy); // nacitanie casu
     cas = vstup_minuty * 60 + vstup_sekundy;     // prepocitanie na sekundy
	 
	 while(cas>=0)
	 {
		 vystup_min = cas / 60;
		 vystup_sek = cas % 60;
		 printf("%d:%d\r", vystup_min, vystup_sek);
		 delay(1000);
		 if(cas !=-1)
		 {
			 printf("     \r");
		 }
		 
	 }
	 stop = 0;
     while(stop == 0)
	 {
		 hudba();
		if ( (Tlacitko == Off) &&  bit_is_clear(PIND,SW1)  )
	     {
			 
		    Tlacitko = Down;
				           	  
	     }
	     else if ( (Tlacitko == Down) &&  bit_is_clear(PIND,SW1)  )
	     {
			 
  		     _delay_ms(10);                 
		    if ( bit_is_clear(PIND,SW1) )  	
		     Tlacitko = On;
			 
	     }
	     else if  ( (Tlacitko == On) &&  bit_is_set(PIND,SW1) ) 	  
	     {
	   	  
	   	    Tlacitko = Up;
			
	     }
	     else if (  (Tlacitko == Up) &&  bit_is_set(PIND,SW1) )
	     {
			 
		     _delay_ms(10); 
		    if ( bit_is_set(PIND,SW1) )	
		    Tlacitko = Off;
			
	     }
		 
		 if(Tlacitko == Down)
		 {
			 
			stop = 1;
			Tlacitko = Off;
			
		 }
	 }
  }
  return(0);
}
#include <avr/io.h>
#include <util/delay.h>
#include "uart.h"


void uart_init( void ) 
{
//  for different BAUD rate change the project settings, or uncomment 
//  following two lines:	
//	#undef  BAUD           // avoid compiler warning
//  #define BAUD 115200
	
   #include <util/setbaud.h>  // requires defined BAUD
   
   UBRR0H = UBRRH_VALUE;
   UBRR0L = UBRRL_VALUE;
   #if USE_2X                 // defined in setbaud.h 
    UCSR0A |= (1 << U2X0);
   #else
    UCSR0A &= ~(1 << U2X0);
   #endif


    UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); /* 8-bit data */
    UCSR0B = _BV(RXEN0) | _BV(TXEN0);   /* Enable RX and TX */	
}


int uart_putc( char c, FILE *stream )
{
   if (c == '\n') 
      uart_putc('\r',stream);
   
   loop_until_bit_is_set(UCSR0A, UDRE0); /* Wait until data register empty. */
   UDR0 = c;
   return 0;
}


char uart_getc(void) 
{
    //loop_until_bit_is_set(UCSR0A, RXC0); /* Wait until data exists. */
    //return UDR0;
	while (!(UCSR0A & (1<<RXC0)));
	return UDR0;
	
}

void delay(int delay)      // vlastna funkcia pre dlhsie casy 
{
  for (int i=1; i<=delay; i++)
  _delay_ms(1);
}
#define set_bit(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
#define clear_bit(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))

#ifndef UART_H_
#define UART_H_

#include <stdio.h>

#define BAUD_PRESCALE  (((F_CPU / (BAUDRATE * 16UL))) - 1)  // vzorcek z datasheetu

void hw_init( void );
void uart_init( void );
     	 
int uart_putc( char c, FILE *stream );
void uart_puts( const char *s );

char uart_getc( void );

void delay(int delay); 

#endif /* UART_H_ */


Zdrojový kód: zdrojaky.zip

Overenie

Na používanie treba zapojiť zariadenia podľa schémy vyššie. Na sériovú komunikáciu je potrebný niektorý terminálový program napr. PuTTY.


Aplikácia.

Video: