Monday, August 18, 2014

Playing music on AVR with PWM

At first I tried to write code myself, but I failed many times.
So i searched for a working project and found it, AVR is using PWM and simple Piezo Buzzer.

Code taken from aquaticus.info
Sources on Github

void InitMusic()
{
  DDRB = 0xFF; //OCR1B как вывод

  // configure timer
  TCCR1A |= ( 1 << COM1B1);  // set 0 on OC1B when TCNT1 == OCR1B

  TCCR1B |= ( 1 << WGM13)|( 1 << CS11); 
  //mode 8, CTC, Phase and Frequency Correct (TOP value is ICR1)
  // clear timer and set 1 in OC1B when TCNT1 == ICR1

  //CS11 means that prescaler is 8 so timer counts at 1 MHz 
  //(MC frequency is 8 MHz)
}
I wrote about Timers and PWM on AVR.
void PlayMusic( const int* pMusicNotes, uint8_t tempo )
{
// pMusicNotes is a pointer on a table which keeps musical data
// tempo from 0 till 100 more == slower
 int duration;
 int note;
 int i;
 uint16_t delay = tempo * 1000;

 while( *pMusicNotes ) // until MUSIC_END == 0
 {
  note = *pMusicNotes;
//We are working with adresses, we take 1 array value and write in note
  pMusicNotes++;
//Array consist of integrers, so ++ means +4 (int size is 4 bytes) and now we get adress of
//our cell +4 wich is the adress of the next cell

  duration = *pMusicNotes;
  pMusicNotes++;

  if( note == PAUSE )
  {
   //pause, do not play anything
   OCR1B = 0;
  }
  else
  {
   //not a pause play sound
   OCR1B = DEFAULT_VOLUME;
//OCR1B determines impulse width, when TCNT1 == OCR1B
//OC1B pin changes to 0
//we set desired note frequency
   ICR1H = (note >> 8);
// at first we write high 8 bits of our 16 bits register (>> 8 means that we shift our bits by 8 to the right)
   ICR1L = note;
  }

  //note duration
  for(i=0;i<32-duration data-blogger-escaped-i="">//_delay_loop_2(); wait 4 ticks of MC, in our case 0.5 μs
    _delay_loop_2( tempo );


 }

 //turn off any sound
 OCR1B = 0;
}

Notes have different durations, maximum is 32, there are also 16, 8, 4, half and whole. (4-th note duration is 4 times less than whole).

Tempo is the same for all notes, it determines how much Bits Per Minute (BPM) we will have.

No comments :

Post a Comment