So my code here generates a PWM wave of 38Khz on Port B pin 7 of arduino Mega 2560 . For that I have used a prescaler of 8 and then set the ICR1 register value to 51 . I have also set the WGM10 ,WGM11, WGM12 and WGM13 bits to 1 , to enable fast PWM mode with Top reference value as ICR1 contents . Similarly , COM1A1 is set , to enable clear output on compare equal else high . CS11 is set to high to enable the prescaler 8 .

My code is as follows -

#include <avr/iomxx0_1.h>
void pwm_init()
        // Configure PB.7 as output pin
        DDRB |= (1<<PB7);
        TCCR1A =  (1<<WGM11) | (1<<WGM10) | (1<<COM1A1);
        TCCR1B =(1<<WGM12) | (1<<WGM13) | (1<<CS11);
        ICR1 = 51;

void pwm_generate()
    OCR1A = (50 * 52)/100 ;
int main()

What I require from the program is that , it should stop producing pwm pulses once a sufficient number of pulses are transmitted . For example - The program should output 7 pwm pulses of 38Khz and then it should give logic 0 as output for specified time period . And then after that specified period , it should produce 38 Khz pwm wave again of say, 5 pulses and then again logic 0 for certain duration . And so on ... How do i achieve this ?

PS- This program is actually being written to simulate a pwm wave required by the IR transmitters in TV remote . The PWM pulses represent the ON period and the Logic 0 conditions would represent the gap in between two successive train of PWM pulses.

Picture of waveform for reference -

  • 1
    There's a whole IRremote library to do that for you.
    – Majenko
    May 19, 2017 at 18:06
  • I don't want to use any libraries. May 19, 2017 at 20:03
  • It's not the number of carrier cycles that matters but the time the pulses are on or off for _ and that not accurate to a pulse. The carrier is just to get the signal through a band-pass filter at the receiver end.
    – Majenko
    May 19, 2017 at 20:07

2 Answers 2


One way to get a fixed number of pulses is to set up an interrupt handler that is invoked once per toggle (or, once per cycle, whichever is appropriate). It can decrement a counter, and shut off an output pin when the counter gets to zero. Or could set the output pin low and the CS bits to 0 to stop the counter. For example, if timer 1 is in use:

volatile byte TogCounter;
// In setup():
TIMSK1 = 1<<TOIE1;  // Enable timer 1 overflow interrupt at TOP
// Define a timer 1 ISR
ISR(TIMER1_OVF_vect) {      // ISR for timer 1 overflows
  if (TogCounter) {         // Don't decrease if not counting
    if (!TogCounter) {
      pinMode (TogPin, INPUT); // Disable output when count runs out
      // If desired, set a volatile wavetrain-is-done flag here

To output a specified number of cycles n, set the mode of TogPin to OUTPUT and set TogCounter to 2·n (or to n if counting cycles instead of toggles). Note, waveforms will be of more-consistent length if you also clear the counter register just before starting any pulse train.

To generate a sequence like m1 cycles on, n1 off, m2 cycles on, n2 off, etc, you could set up an array containing m1, n1, m2, n2, etc; then each time TogCounter runs down, toggle TogPin from INPUT to OUTPUT or vice versa, and load the next array entry into TogCounter.

  • Thank you. I have used the CS reg to set the port to normal and forced logic 0 through it after specific number of pulses were generated . Though I haven't used interrupt , your explanation was helpful . May 20, 2017 at 7:50


1) generate a pulse train of 38Khz -> many ways to do that;

2) put a resistor on the pulse train -> something like 1K will do it;

3) on the other end of the resistor, put a GPIO pin on it; configure it as input, but write a '0' to it;

4) route the clock input of a timer to that GPIO pin; set it to trigger an isr on a given number of pulses -> many ways to do that;

5) in the isr set up in 4), turn the gpio pin in 3) to output to disable the pulse train; input to enable the pulse train.

6) done.

  • 1
    Can you elaborate with the isr code example ? May 19, 2017 at 20:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.