Timer1 phase correct PWM mode not generating square waveform on Nano

Hello everyone I am here looking for a bit of guidance on using Timer1 on the atmega328 to generate a 32khz square wave ive read the datasheet and written some code that successfully activates Phase Correct PWM mode and sets the correct frequency outputting the generated waveform on both OC1A and OC1B pins (PB1 & PB2) when the corresponding COM1A1 and COM1B1 bits are set in the TCCR1A register. I can then control the duty cycle by changing the value in OC1A and OC1B, This all works correctly but my problem is that when I actually look at the outputs with my oscilloscope they are not clean square waves they are kind of sloped and look closer to triangle waves or a horrible sine wave! this is definitely not what I'm going for as I'm going to be using the waveform to switch the MOSFETs of an ESC I'm building therefore I must have clean square waves. I have attached my code photos of the waveforms and a basic schematic to give an idea of the test circuit I used to obtain said waveform photos, if anyone has any ideas or knowledge about my situation and can maybe point out something I'm doing wrong it would be great to hear from you. I'm not sure where ive gone wrong in my code or if I'm completely misunderstand how the waveform generation on the atmega328 works, so any input is welcome. Thanks in advance Harry.

int duty = 0;

void setup() {

  Serial.begin(9600);
  pinMode(A7, INPUT);

  DDRB = (1<<PB1) + (1<<PB2); 

   //timer1 PWM pins: D9 and D10 / PB1 and PB2
  TCCR1A = 0; //clears register
  TCCR1B = 0; //clears register
  TCCR1A = (1<<COM1A1) + (1<<COM1B1) + (1<<WGM11); //phase correct pwm
  TCCR1B = (1<<WGM13) + (1<<CS10); // no pre scaler 
  ICR1 = 250; //set 32 kHz
  OCR1A = 0; //set no duty
  OCR1B = 0; //set no duty

}

void loop() {

  duty = analogRead(A7);
  duty = map(duty, 0, 1023, 0, 250);
  OCR1A = duty; //set duty
  OCR1B = duty; //set duty
  Serial.println(duty);
  
}

High duty:

Low duty:

Test Schematic:

What's the input impedance of your scope probe?

Those round edges are most likely a scope probe and/or bad connection artifact.

And these cheap 'Scopes' only have a bandwidth of 200kHz. That is too low to show a real squarewave with 32kHz.

Here you go. Just to show what @ MicroBahner is saying. Your program on an UNO. Slightly better scope (70MHz bandwidth, 10x probe).

Duty = 50

Duty = 200

I would say you have pretty clean square waves.

1 Like

50% duty cycle (as per definition)?
With complimentary (inverted) output?

32kHz @ 50% duty cycle - I would say close enough. However, not complimentary outputs.

Duty = 125

Edit: Just noticed something. The rise time in the above capture is given as 15.34 micro seconds, which is non-sense. That is given as (an average?) result over the full screen. If I measure just one rising edge it is given as 22ns (20% - 80%), for any of the edges, which I think is more correct.

Hey thanks for doing a test of the code on a much better scope than mine :slight_smile: i though it may have been the scope itself not the waveform and you confirming that is very much appreciated. Its bitter sweet though as i hoped the waveform was going to be the cause behind a larger issue I’m dealing with on this ESC. Anyway thanks for taking the time to help me out have a good one.

The waveform is for controlling the highside mosfets on a sensorless esc im making so the duty cycle will need to range from 10-90% and i dont think i need complementary outputs.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.