Hello buddies,
I have to implement a soft starter in my AC/AC converter driver. The code that I did is above.
#define F_CPU 1000000UL // variavel de frequencia de clock para funcao delay
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <util/delay.h>
int i=0;
int k=0;
int j=0;
int ganho = 0;
int soft = 1;
int ciclo = 0;
int ALTO;
int BAIXO;
void ataque() {
i++;
if (i>3) {
PORTG = 0x1;
_delay_us(10);
PORTG = 0x0;
TCCR1B = 0x8;
i=0;
}
}
void ataque1() {
k++;
if (k>3) {
PORTG = 0x2;
_delay_us(10);
PORTG = 0x0;
TCCR3B = 0x8;
k=0;
}
}
void ataque2() {
j++;
if (j>3) {
PORTG = 0x4;
_delay_us(10);
PORTG = 0x0;
TCCR4B = 0x8;
j=0;
}
}
void conversao() {
PORTC = 0x0;
_delay_us(2);
PORTC = 0x2;
_delay_us(10);
ALTO = PINB;
BAIXO = PINA;
}
void fasea() {
if (soft == 1) {
OCR1A = 0x3ff - (0x78*ganho);
TCCR1B = 0x9; // inicia o timer da fase A
ciclo++;
if (ciclo == 10) {
ganho++;
ciclo = 0;
}
conversao();
if (ALTO > OCR1AH) {
if (BAIXO > OCR1AL) {
soft = 0;
}
}
}
else {
conversao();
OCR1AH = ALTO;
OCR1AL = BAIXO;
}
OCR3A = OCR1A;
OCR4A = OCR1A;
TCCR1B = 0x9; // inicia o timer da fase A
}
ISR(INT0_vect)
{
fasea();
}
ISR(INT1_vect)
{
TCCR3B = 0x9; // inicia o timer da fase B
}
ISR(INT2_vect) {
TCCR4B = 0x9; // inicia o timer da fase C
}
ISR(TIMER1_COMPA_vect) {
ataque();
}
ISR(TIMER3_COMPA_vect) {
ataque1();
}
ISR(TIMER4_COMPA_vect) {
ataque2();
}
int main(void)
{
sei();
EICRA = 0x15; // habilita as interrupções 0 1 e 2 por borda
EIMSK = 0x7; // habilita interrupção externa 0 1 e 2
DDRB = 0x0;
DDRG = 0x07; // PG0 PG1 PG2 definidas como saída
DDRC = 0x2; // PC1 definida como saida
TCCR1A = 0x0; // configuracoes dos timers
TCCR1B = 0x8;
TCCR1C = 0x0;
TCCR3A = 0x0;
TCCR3B = 0x8;
TCCR3C = 0x0;
TCCR4A = 0x0;
TCCR4B = 0x8;
TCCR4C = 0x0;
TIMSK1 = 0x2;
TIMSK3 = 0x2;
TIMSK4 = 0x2; // fim das configuracoes
PORTC = 0x2;
while(1)
{
}
}
As you can see, the drivers starts in soft starter condition. The OCRxA is set to maximum ADC value (0x3FF) and keeps decreasing after 5 cicles of AC Source, and gets out of soft starter when ADC value is bigger than the decreasing value.
When I tried to simulate it, it didn't work as I supposed. The comparation between the decreasing variable and ADC value isn't working well.
Before someone asks why i'm not using atmega adc converter, is because i couldn't use the ADC in C programmation (i need to generate a .hex to simulate at Proteus, so I can't use Arduino Compiler).
So, I wanna know how can get ALTO and BAIXO values (two 8 bits variables) and make it a 16 bits variable to make a better condition?
how can get ALTO and BAIXO values (two 8 bits variables) and make it a 16 bits variable to make a better condition?
int ALTOandBAIXO = ALTO<<8 ;
ALTOandBAIXO += BAIXO;
You mean can't use analogread? Try something like this:
ADCSRA |= (1<<ADSC); // do single conversion
// wait for conversion done, ADIF flag active
while(!(ADCSRA & 0x10));
ADC_temp = ADCL; // read out ADCL register
ADC_temp += (ADCH << 8); // read out ADCH register
I still don't understand why you don't use a board...
If it is only a simulation you'll be running and you have a board, why not wire up some 555 to get your AC cycles and a potmeter for your analog reading and ACTUALLY test the firmware, instead of trusting simulation software?
Hey man I changed it, but the program still don't enter in if condition to get off soft starter.
the condition is ALTOandBAIXO > OCR1A
#define F_CPU 1000000UL // variavel de frequencia de clock para funcao delay
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <util/delay.h>
int i=0;
int k=0;
int j=0;
int ganho = 0;
int soft = 1;
int ciclo = 0;
int ALTO;
int BAIXO;
int ALTOandBAIXO;
void ataque() {
i++;
if (i>3) {
PORTG = 0x1;
_delay_us(10);
PORTG = 0x0;
TCCR1B = 0x8;
i=0;
}
}
void ataque1() {
k++;
if (k>3) {
PORTG = 0x2;
_delay_us(10);
PORTG = 0x0;
TCCR3B = 0x8;
k=0;
}
}
void ataque2() {
j++;
if (j>3) {
PORTG = 0x4;
_delay_us(10);
PORTG = 0x0;
TCCR4B = 0x8;
j=0;
}
}
void conversao() {
PORTC = 0x0;
_delay_us(2);
PORTC = 0x2;
_delay_us(10);
ALTO = PINB;
BAIXO = PINA;
}
void fasea() {
conversao();
if (soft == 1) {
ciclo++;
if (ciclo == 10) {
ganho++;
ciclo = 0;
}
OCR1A = 0x3ff - (0x78*ganho);
ALTOandBAIXO = ALTO<<8;
ALTOandBAIXO += BAIXO;
if (ALTOandBAIXO > OCR1A) {
soft = 0;
}
}
else {
OCR1AH = ALTO;
OCR1AL = BAIXO;
}
OCR3A = OCR1A;
OCR4A = OCR1A;
TCCR1B = 0x9; // inicia o timer da fase A
}
ISR(INT0_vect)
{
fasea();
}
ISR(INT1_vect)
{
TCCR3B = 0x9; // inicia o timer da fase B
}
ISR(INT2_vect) {
TCCR4B = 0x9; // inicia o timer da fase C
}
ISR(TIMER1_COMPA_vect) {
ataque();
}
ISR(TIMER3_COMPA_vect) {
ataque1();
}
ISR(TIMER4_COMPA_vect) {
ataque2();
}
int main(void)
{
sei();
EICRA = 0x15; // habilita as interrupções 0 1 e 2 por borda
EIMSK = 0x7; // habilita interrupção externa 0 1 e 2
DDRB = 0x0;
DDRG = 0x07; // PG0 PG1 PG2 definidas como saída
DDRC = 0x2; // PC1 definida como saida
TCCR1A = 0x0; // configuracoes dos timers
TCCR1B = 0x8;
TCCR1C = 0x0;
TCCR3A = 0x0;
TCCR3B = 0x8;
TCCR3C = 0x0;
TCCR4A = 0x0;
TCCR4B = 0x8;
TCCR4C = 0x0;
TIMSK1 = 0x2;
TIMSK3 = 0x2;
TIMSK4 = 0x2; // fim das configuracoes
PORTC = 0x2;
while(1)
{
}
}
bubulindo:
I still don't understand why you don't use a board...
If it is only a simulation you'll be running and you have a board, why not wire up some 555 to get your AC cycles and a potmeter for your analog reading and ACTUALLY test the firmware, instead of trusting simulation software?
It's a project for university and it must have a software simulation.