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: