OCR comparation - What am I missing?

I’m trying to generate a pwm on D9 and D10
it is working on D9, but not on D10, I’m using an Arduino Nano
Maybe I’m confusing Channels and PINs
I’m assuming OCR1A = PIN D9 and OCR1B = PIN D10

#include <avr/interrupt.h>
#include <avr/io.h>

/*
Input Frequency → CLK=16MHz

Timer Resolution = (1 / (Input Frequency / Prescale)) = (Prescale / Input Frequency)

Prescaler Value | Resolution at 16MHz
1 | 62.5nS
8 | 0.6uS
64 | 4uS
256 | 16uS
1024 | 64uS

Target Timer Count = (1 / (Target Frequency * 2)) / (Prescale / Input Frequency) - 1
= (Target Period / 2) / Timer Resolution - 1

If: Target Period = 125nseg. → Target frequency = 8MHz
With prescaler = 1
Target Timer Count = (125nS/2)/62.5nS - 1 = 0
*/

#define TMR1 0 //for 8MHz: TMR1 = 0 , for 10kHz: TMR1 = 799

void setup() {
// put your setup code here, to run once:
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);

//*********************************************************************
//TIMER1 (16 bits) in mode TOP

TCCR1B |= (1 << CS10); //selecting prescaler 0b001 (Tclk/1)
TCCR1B &= ~((1<<CS11) | (1<<CS12)); // turn off CS12 and CS11 bits
TCCR1A |= ((1<<WGM11) | (1<<WGM10)); //Configure timer 1 for TOP mode (with TOP = OCR1A)
TCCR1B |= ((1<<WGM13) | (1<<WGM12));
TCCR1A |= (1 << COM1A0); // Enable timer 1 Compare Output channel A in toggle mode
TCCR1A &= ~(1 << COM1A1);
TCCR1A |= (1 << COM1B0); // Enable timer 1 Compare Output channel B in toggle mode
TCCR1A &= ~(1 << COM1B1);
TCNT1 = 0;
OCR1A = TMR1;
OCR1B = TMR1;

//*********************************************************************

}

void loop() {
}

What are you missing?
[​code]code tags[​/code]

It is generating the PWM on D9, but it's NOT generating the PWM on D10

Let me put in a different way:
It’s generating the PWM in D9
What do I have to change to make the PWM on D10?

#include <avr/interrupt.h>
#include <avr/io.h>

#define TMR1 0 //for 8MHz: TMR1 = 0 , for 10kHz: TMR1 = 799

void setup() {
// put your setup code here, to run once:
pinMode(9, OUTPUT);

//*********************************************************************
//TIMER1 (16 bits) in mode TOP

TCCR1B |= (1 << CS10); //selecting prescaler 0b001 (Tclk/1)
TCCR1B &= ~((1<<CS11) | (1<<CS12)); // turn off CS12 and CS11 bits
TCCR1A |= ((1<<WGM11) | (1<<WGM10)); //Configure timer 1 for TOP mode (with TOP = OCR1A)
TCCR1B |= ((1<<WGM13) | (1<<WGM12));
TCCR1A |= (1 << COM1A0); // Enable timer 1 Compare Output channel A in toggle mode
TCCR1A &= ~(1 << COM1A1);
TCNT1 = 0;
OCR1A = TMR1;

//*********************************************************************

}

void loop() {
}

I think you have it backwards, its working on D10 and not on D9

D10 – OC1B
D9 – OC1A

  TCCR1A |= ((1<<WGM11) | (1<<WGM10));  //Configure timer 1 for TOP mode (with TOP = OCR1A)
  TCCR1B |= ((1<<WGM13) | (1<<WGM12));

With the mode you have, the TOP is OCR1A so you can’t generate a PWM on the D9 (OC1A) pin

If you want PWM on D9 (OC1A), change your mode to

WGM 13:10 to (1 1 1 0)

Change WGM10 to 0

This will make ICR1 your TOP

Then set the duty cycle of OC1A using OCR1A

make sure you have

DDRB |= (1<<1) | (1<<2) (D10 and D9 as outputs)

And then use ICR1 as the TOP

If you are doing direct register access, it’s easier to read using one-liners

void timer1_init(void)
{
	// use Fast PWM with TOP of ICR1
	TCCR1A = 1<<COM1A1 | 0<<COM1A0 | 1<<COM1B1 | 0<<COM1B0 | 1<<WGM11 | 0<<WGM10;

	// zero out counter
	TCNT1 = 0;

        // set TOP
        ICR1 = 25000;

	// set OC1A duty cycle
	OCR1A = 10000 - 1;

	// set OC1B duty cycle
	OCR1B = 5000 - 1;

	// no interrupts
	TIMSK1 = 0<<OCIE1B | 0<<OCIE1A | 0<<TOIE1;

        // start timer
	TCCR1B = 0<<ICNC1  | 0<<ICES1  | 1<<WGM13  | 1<<WGM12  | 1<<CS12  | 0<<CS11 | 0<<CS10;

	return;
}

Warning: The Arduino library sets some bits in the Timer1 control registers before your setup() is called. It is best to set the control registers to zero before you start setting bits:

  TCCR1A = 0;
  TCCR1B = 0;

Once you set any of the CS (Clock Select) bits in TCCR1B the timer will start running. It might be best to save those for last.

	TCCR1A = 1<<COM1A1 | 0<<COM1A0 | 1<<COM1B1 | 0<<COM1B0 | 1<<WGM11 | 0<<WGM10;

Although you can do this, be aware that the 0<< are only “place holders” and don’t actually do anything. So you can use:

	TCCR1A = 1<<COM1A1 | 1<<COM1B1 | 1<<WGM11;

If you prefer to add more later instead of editing the 0’s. You can also use the _BV macro:

	TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM11);

if you prefer the style.

Those 0<<XXX are purely mnemonics, and it makes it easier to copy-paste when I need to re-use them.

Thank you all, but I still didn’t realize what a need change to generate the PWM on D10, steady of D9
i double check and it is generating on D9, with this code:
I tired to set both 9 and 10 as output, but it’s generating only in D9 … I have a Scope to measure
If I’m reading correct I’m setting the prescaler and is correct, I can see on the scope
I’m setting all WGM to 1, and should be correct because I’m getting the wave correct on D9
I set the COM1A to toggle and I’m using OCR1A, what seems correct because PWM is on D9

But why only D9 generate the PWM, even when D9 and D10 is set to output?

void setup() {
// put your setup code here, to run once:
pinMode(9, OUTPUT);

//*********************************************************************
//TIMER1 (16 bits) in mode TOP

TCCR1B |= (1 << CS10); //selecting prescaler 0b001 (Tclk/1)
TCCR1B &= ~((1<<CS11) | (1<<CS12)); // turn off CS12 and CS11 bits
TCCR1A |= ((1<<WGM11) | (1<<WGM10)); //Configure timer 1 for TOP mode (with TOP = OCR1A)
TCCR1B |= ((1<<WGM13) | (1<<WGM12));
TCCR1A |= (1 << COM1A0); // Enable timer 1 Compare Output channel A in toggle mode
TCCR1A &= ~(1 << COM1A1);
TCNT1 = 0;
OCR1A = TMR1;

Still missing code tags from your posts.
Notice how everyone else’s replies are neatly formatted?
After 12 posts you really shoul know better.
There’s even a helpful </> bouton on the forum toolbar to add them and a “copy sketch for forum” menu item in the IDE…

Sorry to offend the community. I’m just starting, let me try:
here is the current code, I reduced the speed just to be easy to diagnistocs

#include <avr/interrupt.h>
#include <avr/io.h>

/*
Input Frequency -> CLK=16MHz

Timer Resolution = (1 / (Input Frequency / Prescale)) = (Prescale / Input Frequency)

Prescaler Value | Resolution at 16MHz
              1 |  62.5nS
              8 |  0.6uS
             64 |  4uS
            256 |  16uS
           1024 |  64uS

Target Timer Count = (1 / (Target Frequency * 2)) / (Prescale / Input Frequency) - 1
                   = (Target Period / 2) / Timer Resolution - 1

If: Target Period = 125nseg.  ->  Target frequency = 8MHz
With prescaler = 1
Target Timer Count = (125nS/2)/62.5nS - 1 = 0
*/

#define TMR1 31250  //for 8MHz: TMR1 = 0 , for 10kHz: TMR1 = 799

void setup() {
  // put your setup code here, to run once:
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);


//********************************************************************* 
//TIMER1 (16 bits) in mode TOP

//  TCCR1B |= (1 << CS10);  //selecting prescaler 0b001 (Tclk/1)
//  TCCR1B &= ~((1<<CS11) | (1<<CS12));    // turn off CS12 and CS11 bit
  TCCR1B |= (1 << CS12);  //selecting prescaler 0b001 (Tclk/1)
  TCCR1B &= ~((1<<CS10) | (1<<CS11));    // turn off CS12 and CS11 bit
  TCCR1A |= ((1<<WGM11) | (1<<WGM10));  //Configure timer 1 for TOP mode (with TOP = OCR1A)
  TCCR1B |= ((1<<WGM13) | (1<<WGM12));
  TCCR1A |= (1 << COM1A0); // Enable timer 1 Compare Output channel A in toggle mode
  TCCR1A &= ~(1 << COM1A1);
  TCNT1 = 0;
  OCR1A = TMR1;

//*********************************************************************

}

void loop() {
}

Read reply #6. Clear the presets from the ide before setting up the timer. The |= preserves them.

I’m setting all WGM to 1

As stated from my previous reply, you can’t use OC1A when all the WGM bits are 1

Here’s what the datasheets says

Using the ICR1 register for defining TOP works well when using fixed TOP values. By using ICR1, the OCR1A register is free to be used for generating a PWM output on OC1A

To use both OC1A and OC1B outputs for PWM, you have to change your WGM bits to

1<<WGM13 | 1<<WGM12

1<<WGM11 | 0<<WGM10

The ICR1 then become the TOP value for the PWM timer

Cleared the registers and change WGM10 to 0
Neither D9 nor D10 do the waveform generation with the attached code

#include <avr/interrupt.h>
#include <avr/io.h>

/*
Input Frequency -> CLK=16MHz

Timer Resolution = (1 / (Input Frequency / Prescale)) = (Prescale / Input Frequency)

Prescaler Value | Resolution at 16MHz
              1 |  62.5nS
              8 |  0.6uS
             64 |  4uS
            256 |  16uS
           1024 |  64uS

Target Timer Count = (1 / (Target Frequency * 2)) / (Prescale / Input Frequency) - 1
                   = (Target Period / 2) / Timer Resolution - 1

If: Target Period = 125nseg.  ->  Target frequency = 8MHz
With prescaler = 1
Target Timer Count = (125nS/2)/62.5nS - 1 = 0
*/

#define TMR1 31250  //for 8MHz: TMR1 = 0 , for 10kHz: TMR1 = 799

void setup() {
  // put your setup code here, to run once:
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);

TCCR1B = 0;
TCCR1A = 0;

//********************************************************************* 
//TIMER1 (16 bits) in mode TOP

//  TCCR1B |= (1 << CS10);  //selecting prescaler 0b001 (Tclk/1)
//  TCCR1B &= ~((1<<CS11) | (1<<CS12));    // turn off CS12 and CS11 bit
  TCCR1B |= (1 << CS12);  //selecting prescaler 0b001 (Tclk/1)
  TCCR1B &= ~((1<<CS10) | (1<<CS11));    // turn off CS12 and CS11 bit
  TCCR1A |= ((1<<WGM11) | (1<<WGM10));  //Configure timer 1 for TOP mode (with TOP = OCR1A)
  TCCR1A &= ~(1<<WGM10); // just add here to not change the previous line
  TCCR1B |= ((1<<WGM13) | (1<<WGM12));
  TCCR1A |= (1 << COM1A0); // Enable timer 1 Compare Output channel A in toggle mode
  TCCR1A &= ~(1 << COM1A1);
  TCCR1A |= (1 << COM1B0); // Enable timer 1 Compare Output channel B in toggle mode
  TCCR1A &= ~(1 << COM1B1);
  TCNT1 = 0;
  OCR1A = TMR1;
  OCR1B = TMR1;

//*********************************************************************

}

void loop() {
}

You haven't set your TOP value yet, which is now on the ICR1 register

Also, you should only start the Timer after setting all the configuration parameters to avoid glitching