Dale Gregg
Junior Member level 3
- Joined
- Jul 23, 2013
- Messages
- 29
- Helped
- 2
- Reputation
- 4
- Reaction score
- 2
- Trophy points
- 3
- Location
- Leeds, United Kingdom
- Activity points
- 263
unsigned char sinedc[39]={ 0, 20, 60, 79, 98, 116, 134, 150, 166, 180,
194, 206, 217, 226, 234, 240, 245, 248, 250, 250,
248, 245, 240, 234, 226, 217, 206, 194, 180, 166,
150, 134, 116, 98, 79, 60, 40, 20, 0
};
unsigned char a; //Loop counter
unsigned char di; //Number of divisions
void interrupt() //Interrupt Function
{
if(TMR2IF_bit==1) //At PWM period end
{
if(a>=di) //when counter reaches end of string
{
a=0; //reset counter
}
else
{
CCPR1L = sinedc[a]; //Loads values from sine char string
//to DC
a++; //increment counter
}
TMR2IF_bit = 0; //TMR2IF reset
}
}
void main() {
/*DC Loading*/
a=0;
di=38;
}
if(TMR2IF_bit==1) //At PWM period end
{
if([COLOR="#FF0000"]a>=di[/COLOR]) //when counter reaches end of string
{
a=0; //reset counter
}
[COLOR="#FF0000"]else[/COLOR]
{
CCPR1L = sinedc[a]; //Loads values from sine char string
//to DC
a++; //increment counter
}
TMR2IF_bit = 0; //TMR2IF reset
}
if(a>di)
if(a>=di)
if(TMR2IF_bit==1) //At PWM period end
{
if(a>di) //when counter reaches end of string
{
a=0; //reset counter
}
CCPR1L = sinedc[a]; //Loads values from sine char string
//to DC
a++; //increment counter
TMR2IF_bit = 0; //TMR2IF reset
}
Code C - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 unsigned char sinedc[40]={ 0, 20, 40, 60, 79, 98, 116, 134, 150, 166, 180, 194, 206, 217, 226, 234, 240, 245, 248, 250, 250, 248, 245, 240, 234, 226, 217, 206, 194, 180, 166, 150, 134, 116, 98, 79, 60, 40, 20, 0 }; unsigned char a; //Loop counter unsigned char di; //Number of divisions void interrupt() //Interrupt Function { if(TMR2IF_bit==1) //At PWM period end { if(a>=di) //when counter reaches end of string { a=0; //reset counter } else { CCPR1L = sinedc[a]; //Loads values from sine char string //to DC a++; //increment counter } TMR2IF_bit = 0; //TMR2IF reset } } void main() { /*DC Loading*/ a=0; di=39; }
void sinecalc(int amp)
{
mag=PR2-amp;
while(id<39)
{
spt=sineperc[id];
dclrg=spt*mag;
dcsml=dclrg/100;
sinebuff[id]=dcsml;
id++;
}
id=0;
for(idd=0;idd<39;idd++)
sinedc[idd]=sinebuff[idd];
}
void interrupt() //Interrupt Function
{
if(TMR2IF_bit==1) //At PWM period end
{
if(a>di) //when counter reaches end of string
{
if(tog==1) //Toggle H bridge switches
{
tog = 0;
togn = 1;
}
else
{
tog = 1;
togn = 0;
}
a=0; //reset counter
}
else
{
CCPR1L = sinedc[a]; //Loads values from sine char string
//to DC
a++; //increment counter
TMR2IF_bit = 0; //TMR2IF reset
}
}
}
void interrupt() //Interrupt Function
{
if(TMR2IF_bit==1) //At PWM period end
{
CCPR1L = sinedc[a]; //Loads values from sine char string
//to DC
a++; //increment counter
if(a>di) //when counter reaches end of string
{
if(tog==1) //Toggle H bridge switches
{
tog = 0;
togn = 1;
}
else
{
tog = 1;
togn = 0;
}
a=0; //reset counter
}
TMR2IF_bit = 0; //TMR2IF reset
}
}
unsigned char sinedc[40]={ [COLOR="#FF0000"]0[/COLOR], 20, 40, 60, 79, 98, 116, 134, 150, 166, 180,
194, 206, 217, 226, 234, 240, 245, 248, 250, 250,
248, 245, 240, 234, 226, 217, 206, 194, 180, 166,
150, 134, 116, 98, 79, 60, 40, 20, [COLOR="#FF0000"]0[/COLOR]
};
0, 20, 40, 60, 79, 98, 116, 134, 150, ... 150, 134, 116, 98, 79, 60, 40, 20, 0, 0, 20, 40, 60, 79, 98, 116, 134, 150, ... 150, 134, 116, 98, 79, 60, 40, 20, 0, 0, 20, 40, 60, 79, 98, 116, 134, 150, ...
/*
Project: Pure Sine Wave SPWM
Version: 7.1
Target: Re-arrange code, comment and tidy
Sub-Target:
Revisions: 7 - Set for 16MHz selection
Coded by: Dale Gregg
Comments:
Result: Amplitude rises and falls as programmed. Spike at either end of half
wave - possible simulation fault.
*/
#define AMP_TRANS_TEST
//#define HI_FREQ
/*Function Definition*/
void sinecalc(int amp);
void init(void);
/*Variable Definition*/
unsigned char sineperc[39]={ 0, 8, 24, 32, 39, 46, 53, 60, 66, 72,
77, 82, 87, 90, 94, 96, 98, 99, 100, 100,
99, 98, 96, 94, 90, 87, 82, 77, 72, 66,
60, 53, 46, 39, 32, 24, 16, 8, 0
};
unsigned char sinebuff[39];
unsigned char sinedc[39];
/*DC Loading variables*/
unsigned char a; //Loop counter
unsigned char di; //Number of divisions
unsigned char b; //Loop counter
/*Sine Calc Variables*/
unsigned char id; //counter for main sine calc loop
unsigned char idd; //counter for buffer loading loop
unsigned int amp; //amplitude value input to function
unsigned int mag; //resulting amp magnitude
unsigned int spt; //sine percentage table variable
unsigned int dcsml; //calculated duty cycle value
/*Test Code Variables*/
unsigned char testcount; //test counter
unsigned char testamp; //amplitude value
unsigned char dir; //direction bit
sbit tog at RB1_bit; //toggle output for logic control
sbit togn at RB2_bit; //negative toggle (inverted tog)
void interrupt() //Interrupt Function
{
if(TMR2IF_bit==1) //At PWM period end
{
#ifdef HI_FREQ
if(b>3)
{
#endif
CCPR1L = sinedc[a]; //Loads values from sine char string
//to DC
a++; //increment counter
#ifdef HI_FREQ
b=0; //reset b counter
}
else
{
b++; //increment counter
}
#endif
if(a>di) //when counter reaches end of string
{
if(tog==1) //Toggle control logic gates
{
tog = 0;
togn = 1;
}
else
{
tog = 1;
togn = 0;
}
a=0; //reset counter
}
TMR2IF_bit = 0; //TMR2IF reset
}
}
void main()
{
init(); //initialisation function
while(1) //continuous loop
{
#ifdef AMP_TRANS_TEST
/*Test change in AMP Value*/
testcount++; //Test counter
if(testcount>10) //After 10 cycles
{
if(testamp>254) //If greater than max value for amp
{
dir=0; //change direction of increment
}
if(testamp<1) //If less than min value for amp
{
dir=1; //change direction of increment
}
switch(dir)
{
case 0: testamp--; break; //if direction is 0, decrement
case 1: testamp++; break; //if direction is 1, increment
};
sinecalc(testamp); //send amp value to function
testcount=0; //reset test counter
}
#endif
}
}
/*Initialization Function*/
void init(void)
{
/*DC Loading*/
a=0; //pointer for dc value loading
di=38; //number of divisions minus 1 for counter
/*Test code variables*/
testcount=0;
testamp=0;
/*Initialize Ports*/
TRISC = 0; //Set all Port C to outputs (O/Ps)
PORTC = 0; //Clear all Port C O/Ps
TRISA = 0; //Set all Port A to outputs (O/Ps)
PORTA = 0; //Clear all Port A O/Ps
TRISD = 0; //Set all Port D to outputs (O/Ps)
PORTD = 0; //Clear all Port D O/Ps
TRISB = 0; //Set all Port B to outputs (O/Ps)
PORTB = 0; //Clear all Port B O/Ps
/*Initialize Interrupts*/
INTCON = 0b11000000; //<7> Global Intrpt En (GIE), <6> Perip.
//Intrpt En (PEIE)
PIE1 = 0b00000010; //<1> TMR2IE: TMR2/PR2 Match Intrpt En
TMR2IF_bit = 0; //Set TMR2/PR2 Match flag low
/*Initialize PWM*/
PR2 = 255; //Timer2 Period Register - Period of PWM (MAX 255)
CCP1CON = 0b00111100; //<5:4> DC LSBs, <3:2> PWM Mode
T2CON = 0b00000100; //<2> enables Timer2, <1:0> prescaler = 1
sinecalc(0);
}
/*Sine Calculation Function*/
void sinecalc(int amp)
{
while(id<39) //loop for amount of divisions/value in array
{
spt=sineperc[id]; //load spt with % of DC from sineperc
dcsml=(spt*amp)/100; //calculate DC for value of amplitude
sinebuff[id]=dcsml; //load DC value into buffer
id++; //increment counter
}
id=0; //reset counter
for(idd=0;idd<39;idd++) //transfer values from buffer to DC array
sinedc[idd]=sinebuff[idd];
}
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?