Arduino - vlastné tóny cez timer2

From DT^2
Jump to: navigation, search
  1 #define SIRENE_PORT  PORTB
  2 #define SIRENE_DDR   DDRB
  3 #define SIRENE_PIN   4
  4 
  5 void setup() {
  6   init_tone2();
  7 }
  8 
  9 void loop() {
 10 
 11   delay(2000);
 12   for (int i = 0; i < 2; i++)
 13   {
 14     tone2(262, 200);
 15     delay(200);
 16     tone2(330, 200);
 17     delay(200);
 18   
 19     tone2(262, 200);
 20     delay(200);
 21     tone2(330, 200);
 22     delay(200);
 23   
 24     tone2(392, 400);
 25     delay(400);
 26   
 27     tone2(392, 400);
 28     delay(400);
 29   }
 30 }
 31 
 32 void init_tone2()
 33 {
 34   TCCR2A = 2;
 35   TCCR2B = 0;
 36   TIMSK2 = 2;
 37   SIRENE_DDR |= (1 << SIRENE_PIN);  
 38 }
 39 
 40 static volatile uint8_t tone2_state;
 41 static volatile uint32_t tone2_len;
 42 
 43 ISR(TIMER2_COMPA_vect)
 44 {
 45   if (tone2_state) 
 46   {
 47     SIRENE_PORT |= (1 << SIRENE_PIN);
 48     tone2_state = 0;
 49   }
 50   else 
 51   {
 52     SIRENE_PORT &= ~(1 << SIRENE_PIN);
 53     tone2_state = 1;
 54   }
 55   if ((--tone2_len) == 0) TCCR2B = 0;
 56 }
 57 
 58 void tone2(uint16_t freq, uint16_t duration)
 59 {
 60   uint32_t period = 1000000 / freq;
 61 
 62   if (freq >= 977)  // prescaler 32
 63   {
 64     tone2_state = 0;
 65     tone2_len = ((uint32_t)duration * (uint32_t)1000) * 2 / period;
 66     TCNT2 = 0;
 67     OCR2A = (uint8_t) (250000 / (uint32_t)freq);
 68     TCCR2B = 3;
 69   }
 70   else if (freq >= 488) // prescaler 64
 71   {
 72     tone2_state = 0;
 73     tone2_len = ((uint32_t)duration * (uint32_t)1000) * 2 / period;
 74     TCNT2 = 0;
 75     OCR2A = (uint8_t) (125000 / (uint32_t)freq);
 76     TCCR2B = 4;    
 77   }
 78   else if (freq >= 244) // prescaler 128
 79   {
 80     tone2_state = 0;
 81     tone2_len = ((uint32_t)duration * (uint32_t)1000) * 2 / period;
 82     TCNT2 = 0;
 83     OCR2A = (uint8_t) (62500 / (uint32_t)freq);
 84     TCCR2B = 5;
 85   }
 86   else if (freq >= 122) //prescaler 256
 87   {
 88     tone2_state = 0;
 89     tone2_len = ((uint32_t)duration * (uint32_t)1000) * 2 / period;
 90     TCNT2 = 0;
 91     OCR2A = (uint8_t) (31250 / (uint32_t)freq);
 92     TCCR2B = 6;
 93   }
 94   else if (freq >= 30) //prescaler 1024
 95   {
 96     tone2_state = 0;
 97     tone2_len = ((uint32_t)duration * (uint32_t)1000) * 2 / period;
 98     TCNT2 = 0;
 99     OCR2A = (uint8_t) (7813 / (uint32_t)freq);
100     TCCR2B = 7;
101   }
102 }