Generating Sound with PIC Microcontroller – MikroC
The ability to generate sound is very important in embedded applications. A small buzzer could be used to generate specific sounds or beeps for audible alarms or status. In an electronic piano or electronic toys for example, different tones and melodies could be generated electronically. There are countless of electronic applications that can require sound or just a small beep.
Any alternating signal can generate sound, but the frequency of this sound has to be within a specific range for it to be audible to humans or animals. Humans have a range of hearing from 20 Hz (low) to 20,000 Hz (high), frequencies beyond this range exist, but they are inaudible to humans. Normally, buzzers are excited using square wave signals (Pulse Width Modulated (PWM) signals to generate different tones). The frequency of the signal determines the pitch of the generated sound, and duty cycle of the signal can be used to increase or decrease the volume. Most buzzers operate in the frequency range 2–4 kHz which is within the human audible range. When playing a melody, each note is played for a certain duration and with a certain frequency and a certain gap between two successive notes.
Most microncontrollers have a CCP module which stands for Capture/Compare/PWM, this peripheral is used to time and control different events and generate PWM signals. This article explains the concept behind generating sound from the PIC microcontroller using MikroC Pro for PIC Sound Library which simplifies everything.
A small piezoelectric device can be driven directly from the microcontroller output pin, but for high current buzzers, always use a transistor to drive them as a microcontroller output pin can only source a maximum of 20mA. Figure 1 and figure 2 below show how buzzers can be interfaced to a microcontroller.
Figure 1: Interfacing a Piezo Sounder to a PIC Figure 2: Interfacing a Buzzer to a PIC
MikroC Pro for PIC Sound Library
The mikroC PRO for PIC Sound Library provides users with routines necessary for sound signalization. This library has two routines, the Sound_Init and the Sound_Play.
This function is used to specify to which port and which pin the sound device is connected to
// Initialize the pin RC2 for playing sound
This function generates a square wave signal with the specified frequency (hertz) and duration (milliseconds) from the port pin specified by the initialization function. This function accepts only integer frequencies for decimal values, an approximated rounded value can be used.
// Play sound of 1KHz in duration of 90ms
Generating “Happy Birthday” melody
To be able to generate the “Happy Birthday” melody, we need to know the notes and their duration. Two arrays are used to store the notes and their corresponding duration. The Sound_Play function is called in a loop to play all the notes. The melody repeats after a 3-s delay.
#define Notes_Index 25
unsigned char i;
unsigned int Notes[Notes_Index] =
unsigned char Notes_Duration[Notes_Index] =
ANSELC = 0; //Configure PORTC as digital
Sound_Init(&PORTC,2); //Initialize sound library
for (i=0,i < Notes_Index; i++) //Loop for all notes
Sound_Play(Notes[i],400*Notes_Duration[i]; //Play the note. The notes are multiplied by 400 just to get the correct values of notes
Delay_ms(100); //A short gap between notes
Delay_ms(3000) //Repeat melody after 3 s