Monotone Generator Using piezo electric buzzer

It is very easy to generate tones with the ZDev library and the ZKit-51. This project shows how to generate tones of various frequencies using the PWM controller.

Theory & Design

Tones can be generated by rapidly toggling the pin connected to the buzzer. Alternatively, the on-chip PCA (Programmable Counter Array) of the P89v664 can be used to generate a PWM signal to the buzzer. Using PWMs allow us to generate high frequency tones.

The PWM signal is a stream of pulses whose width and frequency can be controlled through software. An important parameter of a PWM signal is the duty cycle. The duty cycle is defined as the ratio between the pulse duration and pulse period of a rectangular waveform. PWM signals with 20% and 60% duty cycle are shown in the following diagram.


The buzzer on the ZKit-51 is connected to signal PWM3 of the 8051, and hence can be fed a PWM signal. The ZDev PWM API controls the on-chip PCA and allows us to generate PWM signals, with a specific frequency and duty cycle. To generate tones, the duty cycle is to 50%, and the frequency is set to the required frequency of the tone.

What You Need

  • ZKit-51 Motherboad

  • ZDev library


Ensure that the switch 1 on the INTR/BUZZ DIP switch is in ON position.


The following code implements a generic function tone_gen() for generating tones and main() invokes tone_gen() to generate a 80KHz tone.

  • /static/code/test-tone.c[Download the source file]

  • /static/code/test-tone.ihx[Download the hex file for ZKit-51!]

#include <board.h>
#include <pwm.h>
#include <delay.h>

 * tone_gen - to generate required frequency
 * @freq: required frequency in Hz
 * @duration: time delay for the frequency in milliseconds
 * To generate required frequency for the particular time period.
void tone_gen(long freq, unsigned int duration)
        long period;

        period = 1000000 / freq;
        pwm_set_period(PWM_CH3, period);
        pwm_set_duty(PWM_CH3, 50);


int main()

        tone_gen(80000, 3000); /* 80000 Hz frquency for 1 sec */

        return 0;