Go Down

Topic: SPWM (Read 254 times) previous topic - next topic

junikels

Jul 10, 2014, 02:25 pm Last Edit: Jul 10, 2014, 02:33 pm by AWOL Reason: 1
I came across a good website and found out a nice program about inverter I understand how the program flow a little bit. What I don't know is how am I going to convert this into arduino code. This is the code:

Code: [Select]
//----------------------------------------------------------------------------------------
//Programmer: Syed Tahmid Mahbub
//Target Microcontroller: ATMEGA16
//Compiler: mikroC PRO for AVR (Can easily port to any other compiler)
//-----------------------------------------------------------------------------------------  


unsigned int sin_table[32]={0, 100, 199, 296, 390, 480, 566, 645, 718,
783, 840, 889, 928, 958, 979, 989, 989, 979, 958, 928, 889, 840, 783,
718, 645, 566, 480, 390, 296, 199, 100,0};

#define MOSA PORTD0_bit
#define MOSB PORTD1_bit
#define MOSC PORTD2_bit
#define MOSD PORTD3_bit

unsigned char FlagReg;
#define Direction FlagReg.B0
//0 -> MOS A + D
//1 -> MOS B + C

unsigned int TBL_POINTER_NEW, TBL_POINTER_OLD, TBL_POINTER_SHIFT, SET_FREQ;
unsigned int TBL_temp;
unsigned char DUTY_CYCLE;

void interrupt() org IVT_ADDR_TIMER1_OVF{
    TBL_POINTER_NEW = TBL_POINTER_NEW + SET_FREQ;
        if (TBL_POINTER_NEW < TBL_POINTER_OLD){
          if (Direction == 0){
             MOSA = 0;
             MOSD = 0;
             MOSB = 1;
             MOSC = 1;
             Direction = 1;
          }
          else{
               MOSB = 0;
               MOSC = 0;
               MOSA = 1;
               MOSD = 1;
               Direction = 0;
          }
       }
       TBL_POINTER_SHIFT = TBL_POINTER_NEW >> 11;
       DUTY_CYCLE = TBL_POINTER_SHIFT;
       TBL_POINTER_SHIFT = sin_table[DUTY_CYCLE];
       OCR1AH = TBL_POINTER_SHIFT >> 8;
       OCR1AL = TBL_POINTER_SHIFT & 0x0F;
       TBL_POINTER_OLD = TBL_POINTER_NEW;
}

void main() {
    SET_FREQ = 410;
    TBL_POINTER_SHIFT = 0;
    TBL_POINTER_NEW = 0;
    TBL_POINTER_OLD = 0;
    DUTY_CYCLE = 0;
    DDRC = 0xFF;
    DDRD = 0XFF;
    OCR1AH = 0;
    OCR1AL = 0;
    TCCR1A = 0x82;
    ICR1H = 0x03;
    ICR1L = 0xE7;
    //ICR1 = 999 -> TOP -> 16kHz
    TIMSK = 0x04;
    TCCR1B = 0x19;
    SREG_I_bit = 1;
    while(1);
}

I'm totally noob in programming. much of my projects are just copy paste and modify a small portion of the code.
(to moderator, If i'm posting in wrong section please kindly delete this.  :( )
any help will be much appreciated. ;) thank you.

Moderator edit: Code tags. { sigh }

CrossRoads

Something close to this for Arduino:
Code: [Select]

//----------------------------------------------------------------------------------------
//Programmer: Syed Tahmid Mahbub
//Target Microcontroller: ATMEGA16
//Compiler: mikroC PRO for AVR (Can easily port to any other compiler)
//-----------------------------------------------------------------------------------------

// Revised for Arduino by CrossRoads

#define MOSA PORTD0_bit
#define MOSB PORTD1_bit
#define MOSC PORTD2_bit
#define MOSD PORTD3_bit
#define Direction FlagReg.B0

unsigned int sin_table[32]={0, 100, 199, 296, 390, 480, 566, 645, 718,
783, 840, 889, 928, 958, 979, 989, 989, 979, 958, 928, 889, 840, 783,
718, 645, 566, 480, 390, 296, 199, 100,0};

unsigned char FlagReg;

//0 -> MOS A + D
//1 -> MOS B + C
byte MOSA;
byte MOSB
byte MOSC;
byte MOSD;

unsigned int TBL_POINTER_NEW = 0;
unsigned int TBL_POINTER_OLD = 0
unsigned int TBL_POINTER_SHIFT = 0
unsigned int SET_FREQ = 410;
unsigned int TBL_temp;
unsigned char DUTY_CYCLE = 0;

// DDRx bits = 1 indicate outputs
DDRC = 0xFF; // data direction register PORTC = D14,15,16,17,18,19 - 20,21 not available
DDRD = 0XFF; // data direction register PORTD = D0,1,2,3,4,5,6,7 on a '328P Arduino

// set up timers, interrupt mask - may need tweaking here still:
OCR1AH = 0;
OCR1AL = 0;
TCCR1A = 0x82;
ICR1H = 0x03;
ICR1L = 0xE7;
//ICR1 = 999 -> TOP -> 16kHz
TIMSK = 0x04;
TCCR1B = 0x19;
SREG_I_bit = 1;

void setup(){
}
void loop(){
}
// All the action happens in the interrupt:

void interrupt() org IVT_ADDR_TIMER1_OVF{             <<< This line needs fixing - what is "org"?

TBL_POINTER_NEW = TBL_POINTER_NEW + SET_FREQ;
if (TBL_POINTER_NEW < TBL_POINTER_OLD){
if (Direction == 0){
MOSA = 0;
MOSD = 0;
MOSB = 1;
MOSC = 1;
Direction = 1;
}
else{
MOSB = 0;
MOSC = 0;
MOSA = 1;
MOSD = 1;
Direction = 0;
}
}
TBL_POINTER_SHIFT = TBL_POINTER_NEW >> 11;
DUTY_CYCLE = TBL_POINTER_SHIFT;
TBL_POINTER_SHIFT = sin_table[DUTY_CYCLE];
OCR1AH = TBL_POINTER_SHIFT >> 8;
OCR1AL = TBL_POINTER_SHIFT & 0x0F;
TBL_POINTER_OLD = TBL_POINTER_NEW;
}

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

junikels

thank you for your reply... i'll try it if it will work. thank you so much.  :)

junikels

about this line

void interrupt() org IVT_ADDR_TIMER1_OVF{             <<< This line needs fixing - what is "org"?

i feel its like PIC thing.. i always see org in there code but dont know its function

CrossRoads

Look up interrupts at the Reference page.
You need to fix the syntax of the interrupt service routine, where I had the question about "org".
Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

TahmidMahbub

Org is used in mikroC to notify the compiler of the specific interrupt vector. In this case, it means that this is the ISR for the Timer 1 interrupt.

Go Up