📄 main_natural_pwm.c
字号:
/**
* @file main.c
*
* Copyright (c) 2004 Atmel.
*
* @brief Ce fichier permet de commander un moteur asynchrone par une loi en U/f
*
* This file is included by all source files in order to access to system wide
* configuration.
* @version 1.0 (CVS revision : $Revision: 1.3 $)
* @date $Date: 2005/11/16 17:18:43 $ (created on 06/04/2004)
* @author $Author: raubree $ (created by Emmanuel David)
*****************************************************************************/
#include "config.h"
#include "inavr.h"
#pragma vector = TIMER0_COMPA_vect
__interrupt void Tech(void);
#pragma vector = ADC_vect
__interrupt void Read_measure(void);
#define MAX_THETA 120 // one quarter of the circle
#define MAX_THETAx2 240
#define MAX_THETAx3 360
#define MAX_THETAx4 480
#define MAX_PWM 2666
// 64MHz (PLL frequency) / 2666 / 2 = 12 kHz (PWM frequency)
#define K_scal 16 // used for the angle integrator
U8 Flag_IT_timer0=0, Flag_IT_ADC=0 ;
U16 Softcounter = 0 ;
S16 Omega_meas;
S16 Omega_ref = -160;
S16 Command = 0;
U16 theta1=0, theta2=160, theta3=320 ;
U16 amplitude , OmegaTe = 64 ;
U8 direction = 0 ;
U16 PWM0, PWM1, PWM2, DeadTime = 254 ; // 254 => temps mort = 4 祍
// U16 DACoutput;
void ADC_Init(void);
void ADC_start_conv(void);
void DAC_Init(void);
void init(void);
void PSC_Init(unsigned int ot0, unsigned int ot1);
void PSC0_Load (unsigned int dt0, unsigned int dt1);
void PSC1_Load (unsigned int dt0, unsigned int dt1);
void PSC2_Load (unsigned int dt0, unsigned int dt1);
S16 mc_control_speed_16b(S16 speed_ref , S16 speed_measure);
U16 controlVF(U16 wTs);
S16 read_acquisition() ;
U16 duty_cycle(U16 theta, U16 Vm) ;
/**
* @brief main
*/
void main(void)
{
init();
// DAC_Init();
ADC_Init();
PSC_Init(0x00, MAX_PWM);
// Set_PC7();
while(1)
{
if (Flag_IT_timer0) /* 1 mS */
{
ADC_start_conv();
Flag_IT_timer0 = 0;
// generates speed reference steps in the software
Softcounter += 1 ;
if (Softcounter == 2500) {
Omega_ref = -320 ;
} //-128; }
if (Softcounter == 5000)
{
Omega_ref= -160 ;
}
if (Softcounter == 7500)
{
Omega_ref= 160 ;
}
if (Softcounter == 10000)
{
Omega_ref= 320 ;
Softcounter = 0 ;
}
}
if (Flag_IT_ADC)
{
// get the measured speed from the ADC
Omega_meas = read_acquisition();
// compute the stator frequency (PI controller)
// Command = mc_control_speed_16b(Omega_ref,Omega_meas);
Command = Omega_ref ; // for use in open loop
// direction management : extract sign and absolute value
if (Command > (S16)(0) ) {
direction = 0 ;
OmegaTe = Command;
}
else {
direction = 1 ;
OmegaTe = (~Command) + 1;
}
//direction = 0 ;
if ( OmegaTe > K_scal )
{
// ------------------------ V/f law --------------------------
amplitude = controlVF(OmegaTe);
// ------------------ natural PWN algorithm ------------------
PWM0 = duty_cycle(theta1,amplitude);
PWM1 = duty_cycle(theta2,amplitude);
PWM2 = duty_cycle(theta3,amplitude);
}
else /* null speed */
{
PWM0 = 0;
PWM1 = 0;
PWM2 = 0;
}
// -------- load the PSCs with the new duty cycles -----------
PSC0_Load (PWM0, PWM0+DeadTime);
if (direction==0) {
PSC1_Load (PWM1, PWM1+DeadTime);
PSC2_Load (PWM2, PWM2+DeadTime);
}
else {
PSC1_Load (PWM2, PWM2+DeadTime);
PSC2_Load (PWM1, PWM1+DeadTime);
}
// 3 integrators for the evolution of the angles
theta1 = (K_scal*theta1 + OmegaTe) / K_scal ;
theta2 = theta1 + 160 ;
theta3 = theta1 + 320 ;
if (theta1>=MAX_THETAx4) theta1 -= MAX_THETAx4;
if (theta2>=MAX_THETAx4) theta2 -= MAX_THETAx4;
if (theta3>=MAX_THETAx4) theta3 -= MAX_THETAx4;
Flag_IT_ADC=0;
}
}
}
// interrupt vector for the sampling period (Ts=1 ms)
__interrupt void Tech(void) {
Flag_IT_timer0 = 1;
}
// interrupt vector for the ADC (end of conversion)
__interrupt void Read_measure(void) {
Flag_IT_ADC = 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -