www.pudn.com > 25811253examples_of_SPWM@C.rar > laowai.c


*****************************************************************************  
* Filename: MAIN.C  
******************************************************************************  
*  
* Author: Dave Karipides  
* Company: APS, Inc.  
* Date: 3-3-97  
* Compiled Using MPLAB-C Rev 1.21  
*  
******************************************************************************  
 
******************************************************************************  
*  
* Description: The main routine calls all the functions for generating  
* an OPEN_LOOP or FEEDBACK sine wave of either 50 or 60 Hz.  
*  
******************************************************************************  
*  
 
*  
*  
******************************************************************************/  
 
/*****************************************************************************  
* main()  
*  
* Description: The main routine initializes the registers and loops  
* forever.  All control is handled in the TMR0 INT  
* routine.  
*  
*  
* Input Variables: NONE  
*  
* Output Variables: NONE  
*  
*  
******************************************************************************/  
 
//#define OPEN_LOOP  
#define FEEDBACK  
//#define 50Hz  
#define 60Hz  
 
#pragma option v  
#include <17c43.h>  
#include  
#include  
 
#ifdef OPEN_LOOP  
// This table yields Full VRMS input  
unsigned char const pwmtab[32]={0,25,50,74,98,120,142,162,180,197,212,  
225,235,244,250,254,255,254,250,244,235,  
225,212,197,180,162,142,120,98,74,50,25};  
#endif  
#ifdef FEEDBACK  
// This table yields slightly less than Full VRMS input  
unsigned char const pwmtab[32]={0,20,40,60,79,97,114,131,145,159,171,  
181,189,197,202,205,206,205,202,197,189,  
181,171,159,145,131,114,97,79,60,40,20};  
#endif  
 
long read_ad(unsigned char); // Prototype for A/D converter function  
 
unsigned char index; // Index into the sinewave reference table  
unsigned char sign; // Flag used to unfold sinewave reference table  
long reference; // Value of the sinewave refrence after unfolding  
unsigned char reference_lo  @ reference; // V1.21 of Compiler does not type cast unsigned  
// char to long so we will write to low byte separately  
long out_volt; // Magnitude of the output voltage;  
long y; // Variables used in compensation routine  
long yold;  
long x;  
long xold;  
long ad_value; // A/D Converter Value  
 
void main(void)  
{  
CLRWDT();  
PORTC = 0; // Zero out portc latches  
DDRC = 0x22; // Set up Data direction register for C  
DDRB = 0; // Set up Data direction register for B  
PR1 = 0xFF; // Setup PR1 register (24.4Khz @ 25Mhz clk)  
PW1DCL = 0; // Set low bits of PWM to 0  
PW1DCH = 0; // Init PWM duty cycle to 0  
 
T0STA = 0x20; // Configure Timer0 prescaler  
INTSTA.T0IE = 1; // Enable Timer 0 interrupt  
TCON1.TMR1CS = 0;  
TCON1.T16 = 0;  
TCON2.TMR1ON = 1; // Start timer 1 (PWM timer)  
TCON2.PWM1ON = 1; // Turn on the PWM  
CPUSTA.GLINTD = 0; // Unmask the interrupts  
 
index = 0; // Initialize variables  
sign = 0;  
y = 0;  
yold = 0;  
x = 0;  
xold = 0;  
PORTC.0 = 1; // Enable the Inverter  
while(1); // Loop forever, execute in INT Routine  
}  
 
#ifdef FEEDBACK  
__TMR0() // Timer  interrupt  
{  
T0STA.T0CS = 0; // Stop timer  
PORTB.7=1;  
#ifdef 60Hz  
TMR0L=0xA5;  
TMR0H=0xF9; // Make Timer0 interrupt at 3.84KHz for 60Hz output  
#endif  
#ifdef 50Hz  
TMR0L=0x5F; // Make Timer0 interrupt at 3.20KHz for 50Hz output  
TMR0H=0xF8;  
#endif  
T0STA.T0CS = 1; // Start timer  
CLRWDT();  
 
reference = 0; // Clear Reference Value  
reference_lo = pwmtab[index]; // Lookup the value of the sinewave reference  
 
if (!index) // Toggle Sign Every Cycle Through table  
sign = ~sign;  
++index; // Increment index  
if (index == 32) // If end of table, reset counter  
index = 0;  
if (sign) // If negative going wave  
{  
reference = ~reference; // V1.21 of Compiler negate (-ref) doesn't work for  
reference = reference + 1;// ref<=0  
}  
ad_value = read_ad(0);  
out_volt = ad_value - 512; // Read output voltage (512 counts=0 volts out)  
 
// Form the expression y = yold + (0.09261 * (x + xold))  
// Where yold, xold is the value of y, x from the previous sample  
// x is the , formed by the difference between the output  
// of the inverter and the reference signal.  
x = out_volt - reference;  
y = ((x + xold) * 24);  
y = y / 256;  
y = y + yold;  
if (y >= 0)  
{  
PORTC.2 = 0; // Set positive going cycle  
} else  
{  
PORTC.2 = 1; // Set negative going cycle  
y = ~y;  
y = y + 1;  
}  
if (y > 255)  
y = 255; // Limit y  
PW1DCH = y; // Update duty cycle  
xold = x; // Store previous sample's state  
yold = y;  
PORTB.7=0;  
}  
#endif  
 
#ifdef OPEN_LOOP  
// The inverter runs in an open loop mode with OPEN_LOOP defined.  
__TMR0() // Timer interrupt  
{  
T0STA.T0CS = 0; // Stop timer  
#ifdef 60Hz  
TMR0L=0xA5;  
TMR0H=0xF9; //Make Timer0 interrupt at 3.84KHz for 60Hz output  
#endif  
#ifdef 50Hz  
TMR0L=0x5F; //Make Timer0 interrupt at 3.20KHz for 50Hz output  
TMR0H=0xF8;  
#endif  
T0STA.T0CS=1; //Start timer  
CLRWDT();  
 
PW1DCH = pwmtab[index];  
if (!index)  
{  
PORTC.0 = 0; // Gate Drive off  
PORTC.2 = ~PORTC.2; // Flip Pos/Neg bit  
PORTC.0 = 1; // Gate Drive on  
}  
++index;  
if (index == 32)  
index = 0;  
PORTC.3 = ~PORTC.3; // Toggle bit to test freq.  
}  
#endif  
 
long read_ad(unsigned char channel)  
{  
long result;  
 
PORTC.6 = 1; // Write bit high  
PORTC.7 = 1; // Read bit high  
PORTC.4 = 1; // Chip select high  
DDRD = 0; // Make PORTD an output  
PORTD = 0x04; // Single ended mode signed 10 bit chan 0 Right justified  
PORTC.4 = 0; // Select chip  
PORTC.6 = 0; // latch command word int A/D  
PORTC.6 = 1; // Start conversion  
PORTC.4 = 1; // Deselect chip  
while (PORTC.5); // Wait for conversion to complete  
DDRD = 0xFF; // Make PORTD an input  
PORTC.4 = 0; // Select chip  
PORTC.7 = 0; // Read high byte  
*( ((unsigned char*)&result) + 1) = PORTD;  
PORTC.7 = 1;  
PORTC.4 = 1;  
PORTC.4 = 0;  
PORTC.7 = 0; // Read low byte  
*( ((unsigned char*)&result) ) = PORTD;  
PORTC.7 = 1;  
PORTC.4 = 1; // Reset chip select lines  
return (result); // Return data  
}