eduardoAvelar
Newbie level 6
- Joined
- Dec 11, 2017
- Messages
- 11
- Helped
- 0
- Reputation
- 0
- Reaction score
- 0
- Trophy points
- 1
- Location
- MG, Brazil
- Activity points
- 154
Hi all!
First of all, I want to tell that I've been facing this problem for a month and did a lot of things and search without any potential results.
I'm developing an sPWM voltage inverter using the AVR Atmega 328P with timer configuration.
There are two tables implemented. Table lookUp_1[] carries the values for the complementary side of the PWM and also implements the dead time for the lookUp_2[] that contain the active pulses to be applied at IR2110 Mosfet Drivers.
The sPWM was implemented using phase correct mode to maintain the pulses center aligned.
The other outputs (Yellow and fresh bold Blue) are just fundamental signals at 60Hz. The SPWM are applied on M1 and M3 (pink and blue waveforms)
I'm using the single topology for the inverter.
The control and power schematic, some photos, and algorithm are attached to this thread.
My main problem is with the shape of the waveform next to zero crossing.
Suggestions will be amazing.
Thanks.
First of all, I want to tell that I've been facing this problem for a month and did a lot of things and search without any potential results.
I'm developing an sPWM voltage inverter using the AVR Atmega 328P with timer configuration.
There are two tables implemented. Table lookUp_1[] carries the values for the complementary side of the PWM and also implements the dead time for the lookUp_2[] that contain the active pulses to be applied at IR2110 Mosfet Drivers.
The sPWM was implemented using phase correct mode to maintain the pulses center aligned.
The other outputs (Yellow and fresh bold Blue) are just fundamental signals at 60Hz. The SPWM are applied on M1 and M3 (pink and blue waveforms)
I'm using the single topology for the inverter.
The control and power schematic, some photos, and algorithm are attached to this thread.
Code:
My main problem is with the shape of the waveform next to zero crossing.
Suggestions will be amazing.
Thanks.
Code:
#include <avr/io.h>
#include <avr/interrupt.h>
volatile static char theTCCR1A = 0b10110010; //varible for TCCR1A
int analogValue = 0;
int storageAnalogValue = 0;
volatile char cycle = 1; // Variável que irá mudar de acordo com o ciclo para alterar o Dead-Time
volatile int value = 0;
// 200 values
int lookUp_1[] = {20, 24, 28, 31, 35, 39, 43, 46, 50, 54, 58, 61, 65, 69, 72, 76, 80, 83, 87, 91, 94, 98, 101, 105, 108, 112, 115, 119, 122, 126, 129, 132, 136, 139, 142, 145, 149, 152, 155, 158, 161, 164, 167, 170, 173, 176, 179, 182, 184, 187, 190, 192, 195, 198, 200, 202, 205, 207, 210, 212, 214, 216, 218, 221, 223, 225, 227, 228, 230, 232, 234, 236, 237, 239, 240, 242, 243, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 256, 257, 258, 258, 259, 259, 259, 260, 260, 260, 260, 260, 260, 260, 260, 260, 259, 259, 259, 258, 258, 257, 256, 256, 255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 243, 242, 240, 239, 237, 236, 234, 232, 230, 228, 227, 225, 223, 221, 218, 216, 214, 212, 210, 207, 205, 202, 200, 198, 195, 192, 190, 187, 184, 182, 179, 176, 173, 170, 167, 164, 161, 158, 155, 152, 149, 145, 142, 139, 136, 132, 129, 126, 122, 119, 115, 112, 108, 105, 101, 98, 94, 91, 87, 83, 80, 76, 72, 69, 65, 61, 58, 54, 50, 46, 43, 39, 35, 31, 28, 24};
int lookUp_2[] = {2, 4, 8, 11, 15, 19, 23, 26, 30, 34, 38, 41, 45, 49, 52, 56, 60, 63, 67, 71, 74, 78, 81, 85, 88, 92, 95, 99, 102, 106, 109, 112, 116, 119, 122, 125, 129, 132, 135, 138, 141, 144, 147, 150, 153, 156, 159, 162, 164, 167, 170, 172, 175, 178, 180, 182, 185, 187, 190, 192, 194, 196, 198, 201, 203, 205, 207, 208, 210, 212, 214, 216, 217, 219, 220, 222, 223, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 236, 237, 238, 238, 239, 239, 239, 240, 240, 240, 240, 240, 240, 240, 240, 240, 239, 239, 239, 238, 238, 237, 236, 236, 235, 234, 233, 232, 231, 230, 229, 228, 227, 226, 225, 223, 222, 220, 219, 217, 216, 214, 212, 210, 208, 207, 205, 203, 201, 198, 196, 194, 192, 190, 187, 185, 182, 180, 178, 175, 172, 170, 167, 164, 162, 159, 156, 153, 150, 147, 144, 141, 138, 135, 132, 129, 125, 122, 119, 116, 112, 109, 106, 102, 99, 95, 92, 88, 85, 81, 78, 74, 71, 67, 63, 60, 56, 52, 49, 45, 41, 38, 34, 30, 26, 23, 19, 15, 11, 8, 4};
void setup() {
// Register initilisation, see datasheet for more detail.
// Timer Counter Control Register 1 A
TCCR1A = theTCCR1A; // 0b10110010;
/*10 Desliga OC1A (D9) no valor de comparação, Liga OC1A em 0V (Modo Não Invertido) Tabela 15-3 Datasheet
11 Liga OC1B (D10) no valor de comparação, Desliga OC1B em 0V (Modo Invertido) Tabela 15-3 Datasheet
00 Bits 3 e 2 Não possuem função
10 WGM11=1 e WGM10=0 for waveform 10 - Phase Correct mode - Garante o tempo morto
*/
// Timer Counter Control Register 1 A
TCCR1B = 0b00010001;
/*000
10 WGM13=1 e WGM12=0 Para a forma de onda 10 Phase Corretc PWM mode
001 Sem preescale para o contador.
*/
// Timer Interrupt Mask Register 1
TIMSK1 = 0b00000001;
/*0000000
1 TOV1 Flag interrupt enable.
*/
ICR1 = 333;
sei(); // Enable global interrupts.
// Set outputs pins.
// Data Direction Register PORTB
// 1 -> Saída
// 0 -> Entrada
// Configura os pinos PB1(D9), PB2 (D10), PB3 (D11), PB4 (D12) como saidas
DDRB = 0b00011110;
// Inicialização das saídas
PORTB |= 0b00001000; // Escreve HIGH no PB3 (D11) sem afetar os outros pinos
PORTB &= 0b11101111; // Escreve LOW no bit PB4 (D12) sem afetar os outros pinos
}
void loop() {
value = (analogRead(A0) / 10);
}
// Interrupt Service Routine
ISR(TIMER1_OVF_vect) {
static int num;
static int i;
static int delay1;
static char trig;
if (num >= 200) {
TCCR1A ^= 0b01010000;
if (cycle) {
OCR1A = lookUp_2[192] + value; // PIN D9 (2HO) -> Canal 4 (AZUL ESCURO) do Ciclo 1, onde Amarelo está em ON e Azul Escuro Modula Junto ao Amarelo. Rosa é o complemento
OCR1B = lookUp_1[num] + value ; // PIN D10 (2LO) -> Canal 3 (ROSA) do cilco 1, onde Azul claro está em OFF e Rosa é o complemento do Azul escuro
//num ++;
} else {
OCR1A = lookUp_1[num] + value ; // PIN D9 (2HO) -> Canal 4 (AZUL ESCURO) do ciclo 2 onde Amarelo está em OFF e é o complemento de ROSA
OCR1B = lookUp_2[192] + value; // PIN D10 (2LO) -> Canal 3 (ROSA) do cliclo 2, onde Azul Claro está em ON e ROSA modula junto com Azul Claro.
//num ++;
}
// Delay for 2000 entries on table
// Just to sincronize
for ( int i = 0; i <= 43; i++ ) {
asm volatile ("nop");
}
if (cycle) {
PORTB ^= 0b00001000; //Faz um togle no pino PB3 (D11) e PB4 (D12) Sem afetar os outros Pinos
for ( int i = 0; i <= 6; i++ ) {
asm volatile ("nop");
}
PORTB ^= 0b00010000; //Faz um togle no pino PB3 (D11) e PB4 (D12) Sem afetar os outros Pinos
} else {
PORTB ^= 0b00010000; // Faz um togle no pino PB3 (D11) e PB4 (D12) Sem afetar os outros Pinos
for ( int i = 0; i <= 6; i++ ) {
asm volatile ("nop");
}
PORTB ^= 0b00001000; // Faz um togle no pino PB3 (D11) e PB4 (D12) Sem afetar os outros Pinos
}
cycle ^= 0b00000001;
num = 0;
}
if (cycle) {
OCR1A = lookUp_2[num] + value; // PIN D9 (2HO) -> Canal 4 (AZUL ESCURO) do Ciclo 1, onde Amarelo está em ON e Azul Escuro Modula Junto ao Amarelo. Rosa é o complemento
OCR1B = lookUp_1[num] + value ; // PIN D10 (2LO) -> Canal 3 (ROSA) do cilco 1, onde Azul claro está em OFF e Rosa é o complemento do Azul escuro
num ++;
} else {
OCR1A = lookUp_1[num] + value ; // PIN D9 (2HO) -> Canal 4 (AZUL ESCURO) do ciclo 2 onde Amarelo está em OFF e é o complemento de ROSA
OCR1B = lookUp_2[num] + value; // PIN D10 (2LO) -> Canal 3 (ROSA) do cliclo 2, onde Azul Claro está em ON e ROSA modula junto com Azul Claro.
num ++;
}
}