PWM with dead Time using Timer 1

Hi Al,

I am programming Arduino uno for a Induction Cooker - Resonant Half Bridge

here following my code

#include <avr/io.h>
#include <avr/interrupt.h> 
#include <Wire.h>
#include <TwoWireLCD.h>
#include <Bounce2.h>

int Frequency = 250;                              // default value pver 31 kKz switching Frequency
int DeadTime = 18;                                // 1,1 us dead time
int DutyCycle_A = (Frequency+DeadTime)/2;         //Duty Cycle High Side
int DutyCycle_B = (Frequency-DeadTime)/2;         //Duty Cycle Low Side

//Analog pin
int voltage_pin = A0;                             // This pin is the voltage sensing of the bus capacitor
int current_pin = A1;                             // This pin is the input current sensing
int temp_pin = A2;                                // This pin is the temperature sensing
//Button Pin
int Button_0 =0;                                  //Button 0
int Button_1 =1;                                  //Button 1
int Button_2 =2;                                  //Button 2
int Button_3 =3;                                  //Button 3
//Led Pin
int Led_3 = 4;                                    //Led Button 3 
int Led_2 = 5;                                    //Led Button 2
int Led_1 = 6;                                    //Led Button 1
int Led_0 = 7;                                    //Led Button 0

char text[] ="XXX-IH";         //String Diplay
unsigned char pos = 0;                            //Temperature 
int val_0 = 0;                                    //Button 0 Inizialization 
int val_1 = 0;                                    //Button 1 Inizialization
int val_2 = 0;                                    //Button 2 Inizialization 
int val_3 = 0;                                    //Button 3 Inizialization
Bounce debouncer_0 = Bounce();                    // Instantiate a Bounce object 0 
Bounce debouncer_1 = Bounce();                    // Instantiate a Bounce object 1
Bounce debouncer_2 = Bounce();                    // Instantiate a Bounce object 2
Bounce debouncer_3 = Bounce();                    // Instantiate a Bounce object 3

void InitPort1(void){
                      DDRB|=(1<<PORTB1)|(1<<PORTB2);                //Init PB1/OC1A and PB2/OC1B pins as output
                      }

void InitLCD(void){
                   Wire.begin();                                   //Begin of the function Wire -I2C comunication  
                   LCD.begin();                                    //Begin of the function LCD -I2C comunication
                   }

void InitButton(void){
                      pinMode(Led_0, OUTPUT);                         //Set Led 0 as output pin 
                      pinMode(Led_1, OUTPUT);                         //Set Led 1 as output pin
                      pinMode(Led_2, OUTPUT);                         //Set Led 2 as output pin
                      pinMode(Led_3, OUTPUT);                         //Set Led 3 as output pin
                      pinMode(Button_3, INPUT_PULLUP);                //Set Button 3 as input with pull up resistor
                      pinMode(Button_2, INPUT_PULLUP);                //Set Button 2 as input with pull up resistor
                      pinMode(Button_1, INPUT_PULLUP);                //Set Button 1 as input with pull up resistor
                      pinMode(Button_0, INPUT_PULLUP);                //Set Button 0 as input with pull up resistor
                      debouncer_0.attach(Button_0);                   // After setting up the button 0, setup debouncer 0
                      debouncer_1.attach(Button_1);                   // After setting up the button 1, setup debouncer 1
                      debouncer_2.attach(Button_2);                   // After setting up the button 2, setup debouncer 2 
                      debouncer_3.attach(Button_3);                   // After setting up the button 3, setup debouncer 3
                      debouncer_0.interval(5);
                      debouncer_1.interval(5);
                      debouncer_2.interval(5);
                      debouncer_3.interval(5);
                      }
  

void Interrupt(void){                                 // Set up the digital pin 2 to an Interrupt and Pin 4 to an Output
                      SREG = 0x80;                                   // Enable the interrupt SPI Control Register
                      EICRA  = (1 << ISC00) & (1 << ISC10);          // Any change INT0, INT1
                      EIMSK  = (1 << INT0) & (1 << INT1);            // External Interrupt Mask Register
                      EIFR = (1 << INTF0) & (1 << INTF1);
                      }
                
void InitTimer1(void){
                      TCNT1=0;                                        //Set Initial Timer value
                      //set non inverted PWM on OC1A pin and inverted on OC1B
                      TCCR1A|=(1<<COM1A1)|(1<<COM1B1)|(1<<COM1B0);
                      //set top value to ICR1
                      ICR1=Frequency;                                 //0x00FF equivale a 255                                              
                      TCCR1B|=(1<<WGM13);                             //set corrcet phase and frequency PWM mode
                      //set compare values
                      OCR1A=DutyCycle_B;                              //OCR1A=0x0064; half of ICR1=0x00FF
                      OCR1B=DutyCycle_A;                              //OCR1B=0x0096; half of ICR1=0x00FF
                      }

void StartTimer1(void){                         //Start timer1 without no prescaller
                      TCCR1B=(1<<CS10);
                     }


// Interrupt to stop
ISR(INT0_vect){                                     //synchronization of the analog reading with the zero crossing
               OCR0A=0;
               TIFR0=0;
              }

ISR(INT1_vect){                                        //If the Interrupt on the PIN 1 is trigger all the Control signals go to 0
               digitalWrite(10, LOW);
               digitalWrite(9, LOW);
               }
               
//Update the LCD
int LCD_update(){               
                  LCD.print(&text[pos], 4);
                  LCD.update();
                  delay(500);
                 pos++;
                 if(pos >= (sizeof(text)/sizeof(text[0])) - 4)
                pos = 0;
               }
                
int Button_LED(){
                 val_3 = digitalRead(Button_3);  // read input value
                 if (val_3 == LOW){         // check if the input is HIGH (button released)
                 digitalWrite(Led_3, LOW);  // turn LED OFF
                 }else{digitalWrite(Led_3, HIGH);  // turn LED ON
                 }
  
                 val_2 = digitalRead(Button_2);  // read input value
                 if (val_2 == LOW) {         // check if the input is HIGH (button released)
                 digitalWrite(Led_2, LOW);  // turn LED OFF
                 }else{digitalWrite(Led_2, HIGH);  // turn LED ON
                 }
 
                 val_1 = digitalRead(Button_1);  // read input value
                 if (val_1 == LOW){         // check if the input is HIGH (button released)
                 digitalWrite(Led_1, LOW);  // turn LED OFF
                 }else{digitalWrite(Led_1, HIGH);  // turn LED ON
                 }
  
                 val_0 = digitalRead(Button_0);  // read input value
                 if (val_0 == LOW){         // check if the input is HIGH (button released)
                 digitalWrite(Led_0, LOW);  // turn LED OFF
                 }else{digitalWrite(Led_0, HIGH);  // turn LED ON
                 }
                 }
 
void setup(){
            
            IntitPort0();
            InitPort1();
            InitLCD();
            Interrupt();
            InitButton();
            InitTimer1();
            StartTimer1();
            }

void loop() {
              LCD_update();
              Button_LED();
               }

this code partially works.

I would like to change ICR1 in order to change frequency keeping the duty cycle always constant.

This in principle works when I use the following code:

#include <avr/io.h>
int Frequency = 255;
int DeadTime = 20;
int DutyCycle_A = (Frequency+DeadTime)/2;
int DutyCycle_B = (Frequency-DeadTime)/2; 
void InitPort(void)
{
//Init PB1/OC1A and PB2/OC1B pins as output
DDRB|=(1<<PORTB1)|(1<<PORTB2);
}
void InitTimer1(void)
{
//Set Initial Timer value
TCNT1=0;
//set non inverted PWM on OC1A pin
//and inverted on OC1B
TCCR1A|=(1<<COM1A1)|(1<<COM1B1)|(1<<COM1B0);
//set top value to ICR1
//ICR1=0x00FF;
ICR1=Frequency; //0x00FF equivale a 255

//set corrcet phase and frequency PWM mode
TCCR1B|=(1<<WGM13);
//set compare values
OCR1A=DutyCycle_B; //OCR1A=0x0064; half of ICR1=0x00FF

OCR1B=DutyCycle_A; // OCR1B=0x0096; half of ICR1=0x00FF

}
void StartTimer1(void)
{
//Start timer without no prescaller
TCCR1B|=(1<<CS10);
}
int main(void)
{
InitPort();
InitTimer1();
StartTimer1();
    while(1)
    {
        //do nothing
    }
}

so when I use the structure main I am able to set different frequencies. But when I use the main the other function does not work.

I would appreciate if someone can help me

Thank you

regards

Can you clarify why one example is an Arduino sketch and the other isn’t and uses main() -
are you trying to port Arduino code to bare AVR or the other way round?

Hi

Both are arduino.

If you use the code with the int main in the Arduino it does work.

Reagrds,

Vittorio