⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 example_5_ac.c

📁 CYGNAL单片机
💻 C
字号:
//-----------------------------------------------------------------------------
// Example 5
// AC Motor Control
//-----------------------------------------------------------------------------
// Copyright 2004 Silicon Laboratories Inc.
//
// AUTH: KAB
// DATE: 12MAR04
//
// This program provides AC Induction motor control using the PCA 8-bit
// PWM mode. Three PCA channels are used to generate three-phase PWM.
// The three PWMs are output on P0.0-0.2. The falling edge of the three
// PWM signals are edge-aligned. Each PWM has a frequency of 24 kHz and
// a low-time that varies independently from 160ns to 100%. These
// signals can be used to drive a induction motor using a three-phase
// bridge. A gate drive with built in dead-time is required.
//
// A potentiometer is connected to P0.6. The value of the Pot controls
// the speed of the motor. The speed is controlled using a constant V/
// Hz profile. The sine wave frequency varies from DC up to 60 Hz. The
// modulation depth varies from zero to 100%.
//
// Target: C8051F33x
//
// Tool chain: KEIL Eval 'c'
//
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------

#include <c8051f300.h>                 // SFR declarations
//-----------------------------------------------------------------------------
// Macros
//-----------------------------------------------------------------------------
#define DTIME 5981                     // delay time 1 ms update rate
                                       // 24500000/4/1024
//-----------------------------------------------------------------------------
// Typdefs
//-----------------------------------------------------------------------------
typedef union                          // union used for writing to TL0 & TH0
    {
        struct
        {
            unsigned char hi;
            unsigned char lo;
        } b;
        unsigned int w;
    }udblbyte;

//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------
void SYSCLK_Init (void);
void PORT_Init (void);
void PCA0_Init (void);
void ADC0_Init (void);
void Timer_Init(void);
unsigned char readVin(void);
unsigned char avgVin(void);
unsigned char sineWave(unsigned char);
void Timer_ISR (void);
void Update(void);
//-----------------------------------------------------------------------------
// Sine Wave Table
//-----------------------------------------------------------------------------

const signed char code sine[256]=
{
   0x00, 0x03, 0x06, 0x09, 0x0C, 0x10, 0x13, 0x16, 0x19, 0x1C, 0x1F, 0x22,
   0x25, 0x28, 0x2B, 0x2E, 0x31, 0x34, 0x36, 0x39, 0x3C, 0x3F, 0x42, 0x44,
   0x47, 0x49, 0x4C, 0x4E, 0x51, 0x53, 0x56, 0x58, 0x5A, 0x5C, 0x5E, 0x60,
   0x62, 0x64, 0x66, 0x68, 0x6A, 0x6C, 0x6D, 0x6F, 0x70, 0x72, 0x73, 0x74,
   0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7B, 0x7C, 0x7D, 0x7D, 0x7E, 0x7E,
   0x7E, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7E, 0x7E, 0x7D, 0x7D,
   0x7C, 0x7C, 0x7B, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x72, 0x71,
   0x70, 0x6E, 0x6C, 0x6B, 0x69, 0x67, 0x65, 0x63, 0x61, 0x5F, 0x5D, 0x5B,
   0x59, 0x57, 0x54, 0x52, 0x50, 0x4D, 0x4B, 0x48, 0x45, 0x43, 0x40, 0x3D,
   0x3B, 0x38, 0x35, 0x32, 0x2F, 0x2C, 0x29, 0x27, 0x24, 0x20, 0x1D, 0x1A,
   0x17, 0x14, 0x11, 0x0E, 0x0B, 0x08, 0x05, 0x02, 0xFE, 0xFB, 0xF8, 0xF5,
   0xF2, 0xEF, 0xEC, 0xE9, 0xE6, 0xE3, 0xE0, 0xDC, 0xD9, 0xD7, 0xD4, 0xD1,
   0xCE, 0xCB, 0xC8, 0xC5, 0xC3, 0xC0, 0xBD, 0xBB, 0xB8, 0xB5, 0xB3, 0xB0,
   0xAE, 0xAC, 0xA9, 0xA7, 0xA5, 0xA3, 0xA1, 0x9F, 0x9D, 0x9B, 0x99, 0x97,
   0x95, 0x94, 0x92, 0x90, 0x8F, 0x8E, 0x8C, 0x8B, 0x8A, 0x89, 0x88, 0x87,
   0x86, 0x85, 0x84, 0x84, 0x83, 0x83, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81,
   0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x83, 0x83, 0x84, 0x85, 0x85, 0x86,
   0x87, 0x88, 0x89, 0x8A, 0x8C, 0x8D, 0x8E, 0x90, 0x91, 0x93, 0x94, 0x96,
   0x98, 0x9A, 0x9C, 0x9E, 0xA0, 0xA2, 0xA4, 0xA6, 0xA8, 0xAA, 0xAD, 0xAF,
   0xB2, 0xB4, 0xB7, 0xB9, 0xBC, 0xBE, 0xC1, 0xC4, 0xC7, 0xCA, 0xCC, 0xCF,
   0xD2, 0xD5, 0xD8, 0xDB, 0xDE, 0xE1, 0xE4, 0xE7, 0xEA, 0xED, 0xF0, 0xF4,
   0xF7, 0xFA, 0xFD, 0x00
};

//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
unsigned char Volts;                   // output voltage

unsigned int Sum;                      // integral of omega

//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------


void main (void)
{

   PCA0MD &= ~0x40;                    // disable watchdog timer

   SYSCLK_Init ();                     // initialize system clock
   PCA0_Init ();                       // initialize PCA0 for 8-bit PWM
   PORT_Init ();                       // initialize crossbar and GPIO
   ADC0_Init();                        // initialize ADC for polled mode
   Timer_Init();                       // initialize T0 for update timebase
   EA = 1;                             // enable global interrupts

   Sum = 0;                            // clear 16-bit integral of omega

   while (1)
   {

      Volts = avgVin();                // set output voltage to pot setting
   }
}


//-----------------------------------------------------------------------------
// SYSCLK_Init
//-----------------------------------------------------------------------------
void SYSCLK_Init (void)
{
   OSCICN = 0x07;                      // configure for 24.5 MHz
   RSTSRC = 0x06;                      // enable missing clock detector
                                       // and VDD Monitor.
}

//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Configure the Crossbar and GPIO ports.
// P0.0 - !PWMA - phase A PWM signal - push-pull output
// P0.1 - !PWMB - phase B PWM signal - push-pull output
// P0.2 - !PWMC - phase C PWM signal - push-pull output
// P0.3 -
// P0.4 -
// P0.5 -
// P0.6 - Analog Input
// P0.7 -
//
void PORT_Init (void)
{
   XBR0    =  0x00;                    // skip nothing
   XBR1    =  0xc0;                    // enable CEX0-2
   P0MDOUT =  0x07;                    // P0.0-2 push-pull output
   P0MDIN  = ~0x40;                    // P0.6 analog input
   XBR2    =  0x40;                    // enable crossbar
}

//-----------------------------------------------------------------------------
// PCA0_Init
//-----------------------------------------------------------------------------

void PCA0_Init (void)
{

    PCA0MD = 0x02;                     // use SYSCLK/4 for 24kHz PWM
    PCA0L  = 0x00;                     // clear PCA Counter/Timer Low Byte
    PCA0H  = 0x00;                     // clear PCA Counter/Timer High Byte


    //Module 0
    PCA0CPM0 = 0x42;                   // module 0 8-bit PWM no interrupts
    PCA0CPL0 = 0x80;                   // initialize for 50%
    PCA0CPH0 = 0x80;                   // initialize for 50%

    //Module 1
    PCA0CPM1 = 0x42;                   // module 1 8-bit PWM no interrupts
    PCA0CPL1 = 0x80;                   // initialize for 50%
    PCA0CPH1 = 0x80;                   // initialize for 50%

    //Module 2
    PCA0CPM2 = 0x42;                   // module 2 8-bit PWM no interrupts
    PCA0CPL2 = 0x80;                   // initialize for 50%
    PCA0CPH2 = 0x80;                   // initialize for 50%

    PCA0CN   = 0x40;                   // enable PCA0

}



//-----------------------------------------------------------------------------
// Timer_Init
//-----------------------------------------------------------------------------

void Timer_Init (void)
{
   CKCON = 0x01;                       // T0 uses sysclk/4
   TMOD =  0x01;                       // T0 mode 1
   TR0 = 1;                            // enable timer
   ET0 = 1;                            // enable interrupts
   TF0 = 1;                            //force interrupt

}

//-----------------------------------------------------------------------------
// Timer_ISR
//-----------------------------------------------------------------------------

void Timer_ISR(void) interrupt 1
{
   udblbyte t;
   TR0 = 0;                            // stop Timer0
   t.w =  -DTIME;                      // 2s complement delay-time
   TL0 = t.b.lo;                       // write lo byte first
   TH0 = t.b.hi;                       // write hi byte second
   TF0 = 0;                            // clear overflow flag
   TR0 = 1;                            // start Timer0
   Update();                           // update sinewave
}

//-----------------------------------------------------------------------------
// Update function
//-----------------------------------------------------------------------------

void Update (void)
{
      unsigned int omega;              // angular frequency
      unsigned char theta;             // sine wave angle

      omega = Volts;                   // constant V/Hz control

      omega <<=4;                      // scale omega for 1 ms update rate

      Sum += omega;                    // integrate omega

      theta = Sum >>8;                 // theta is upper byte

      PCA0CPH0 = sineWave(theta);      // output sinewaves

      PCA0CPH1 = sineWave(theta + 0x55);

      PCA0CPH2 = sineWave(theta + 0xaa);
}

//-----------------------------------------------------------------------------
// sineWave function
//-----------------------------------------------------------------------------

unsigned char sineWave(unsigned char q)
{
      signed char s;                   // signed sine
      unsigned char o;                 // output value
      unsigned int p;                  // 16 bit product

      s = sine[q];                     // get value from table

      p = Volts * (signed int)s;       // multiply by v

      o = p>>8;                        // throw away low byte

      o += 0x80;                       // center sinewave at 50%

      return o;                        // return sinewave value
}

//-----------------------------------------------------------------------------
// ADC functions
//-----------------------------------------------------------------------------
void ADC0_Init (void)
{
   ADC0CN = 0x40;                      // Low-power tracking mode;
                                       // ADC0 conversions are initiated
                                       // on writes to AD0BUSY;
   AMX0SL = 0xf6;                      // select P0.6, single-ended
   ADC0CF = 0x81 ;                     // AD0SC=4 gain =1
   REF0CN = 0x0a;                      // ADC uses Vdd for full scale
   EIE1 &= ~0x04;                      // disable ADC0 EOC interrupt
   AD0EN = 1;                          // enable ADC
}

unsigned char readVin(void)
{
   AD0INT = 0;                         // clear ADC0 end-of-conversion
   AD0BUSY = 1;                        // initiate conversion
   while (!AD0INT);                    // wait for conversion to complete
   return ADC0;
}

unsigned char avgVin(void)
{
   unsigned char i, result;
   unsigned int sum;

   sum = 0;
   for (i = 64; i != 0; i--)           // repeat 64 times
   {
      sum += readVin();                // read ADC and add to sum
   }
   result = (unsigned char)(sum>>6);   // divide by 64 and cast to uchar
   return result;                      // return average reading
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -