📄 dtc_3.c
字号:
/****dtc_3.c********************************************************
* Direct Torque Control- with speed loop for DS1102 controller *
* Board from dSPACE, GmbH. *
* Written by Nik Rumzi Nik Idris *
* *
*******************************************************************/
#include <brtenv.h> /* basic real-time environment */
#include <math.h>
#include <dtc_3.h>
/*-------------------------------------------------------------*/
#define DT 55e-6 /* sampling step size */
#define DT2 10e-3 /* sampling step size for speed*/
/* error flag for CHKERR at last dual-port memory location */
volatile int *error = (int *) (DP_MEM_BASE + DP_MEM_SIZE - 1);
/* timer0 interrupt service routine */
void isr_t0()
{
int I, angint, angint1, mask3, mask5;
float upl=0.08; /* upper band for torque */
float uplf=0.0173; /* upper band for flux */
float upll=0; /* upper band for torque */
float lol=0; /* lower band for torque */
float lolf=-0.0173; /* lower band for flux */
float loll=-0.08; /* lower band for flux */
float ie_count=0;
unsigned int IO_port_read; /* I/O-port status */
begin_isr_t0(*error); /* overload check */
service_mtrace("0"); /*Starting mtrace for DS1102 board */
input(u);
/*Offsets for the sensed phase current */
u3= u3 - offs1;
u4 = u4 - offs2;
u5=(-u3 - u4);
/*3-phase to 2-phase transformation*/
id = (0.6666667*u4)-(0.3333333*(u5+u3));
iq = (0.5773503*(u5-u3));
/* read I/O-port of the switching pattern from Xilinx*/
IO_port_read = ds1102_p14_pin_io_in();
for(i=0; i<=2; i++){
/* evaluate I/O-port pin status */
port_pin_read[i] = ( (IO_port_read & (0x2000 << i)) != 0 );}
/* Stator d-q voltages with DC link of 120V DC */
vd = (80*port_pin_read[0])-(40*(port_pin_read[1]+port_pin_read[2]));
vq = 69.282*(port_pin_read[1]-port_pin_read[2]);
/* Stator flux estimation using the voltage model with LP filter */
flxd = (flxd + (vd - id*10.9)*DT)*0.9989;
flxq = (flxq + (vq - iq*10.9)*DT)*0.9989;
/* The following is to estimate the operating frequency, wsp ******/
vxd = (vd - id*10.9);
vxq = (vq - iq*10.9);
ws1=(vxq*flxde-vxd*flxqe);
ws2=Flx*Flx;
ws=ws1/ws2;
/*Low pass filtering to smooth out wsp */
wsp = (wsp + 2.5*ws*DT)* 0.99986;
/******************************************************************/
/* Check for the flag to initiate the compensation ***************/
if(flag>5){
flag=7;
flxde = delflxd; /* Initiate the compensation */
flxqe = delflxq;}
else {
flag=0;
flxde = flxd; /* No compensation */
flxqe = flxq;}
/******************************************************************/
/* Torque calculation */
T=1.5*(flxde*iq-flxqe*id);
/* Calculates the flux magnitude*/
Flx=sqrt(flxde*flxde + flxqe*flxqe);
/* Determine the stator flux orientation to be passed to pin 17, 18
and 19 of Xilinx FPGA*/
flxq_ = 0.57735027*flxde;
if(flxde >= 0){
if(flxqe >= 0){
if(flxqe >= flxq_)angint = 0xfe02; /* sector=3 */
else angint=0xfe01;} /* sector=2 */
else {if(flxqe <= -flxq_)angint = 0xfe00; /* sector=1 */
else angint=0xfe01;}} /* sector=2 */
else {
if(flxqe >=0){
if(flxqe >= -flxq_)angint = 0xfe03; /* sector=4 */
else angint=0xfe04;} /* sector=5 */
else {if(flxqe <= flxq_)angint=0xfe05; /* sector=6 */
else angint=0xfe04;}} /* sector=5 */
angint= angint | 0xfe00;
/* Closed loop speed control system ******************************/
speed_error=speed_ref-speed;
Propd=(speed_error)*Kp;
speed_error_int = speed_error_int + (speed_error)*DT*Ki;
Tstat= Propd + speed_error_int; /*PI controller output */
/******************************************************************/
if(Tstat>1)Tstat=1;/* To limit the torque reference to 1 N-m */
else if(Tstat<-1)Tstat=-1;
else Tstat=Tstat;
/* Torque error */
Terr_old = Terr;
Terr = Tstat - T;
/******** Three-level torque hysterisis: *************************/
/* Error increasing and 1*/
if((Terr_old < Terr)&& (mask1==0xfbff))
{mask1=0xfbff; flagm=1;}
/* Error increasing and 0 */
if((Terr_old < Terr)&& (mask1==0xf9ff)){
if(Terr >= upl){mask1=0xfbff;flagm=1;}
else {mask1=0xf9ff;flagm=0;}}
/* Error decreasing and 0 */
if((Terr_old > Terr)&& (mask1==0xf9ff))
{mask1=0xf9ff;flagm=0;}
/* Error decreasing and 1 */
if((Terr_old > Terr)&& (mask1==0xfbff)){
if(Terr >= lol){mask1=0xfbff;flagm=1;}
else {mask1=0xf9ff;flagm=0;}}
/* Negative error */
/* Error increasinga and 0 */
if((Terr_old < Terr)&& (mask2==0xf9ff))
{mask2=0xf9ff;flagm1=0;}
/* Error increasing and -1 */
if((Terr_old < Terr)&& (mask2==0xfdff)){
if(Terr >= upll){mask2=0xf9ff;flagm1=0;}
else {mask2=0xfdff;flagm1=-1;}}
/* Error decreasing and -1 */
if((Terr_old > Terr)&& (mask2==0xfdff))
{mask2=0xfdff;flagm1=-1;}
/* Error decreasing and 0 */
if((Terr_old > Terr)&& (mask2==0xf9ff)){
if(Terr >= loll){mask2=0xf9ff;flagm1=0;}
else {mask2=0xfdff;flagm1=-1;}}
if(Terr_old == Terr){mask2=mask2;
mask1=mask1;}
/******************************************************************/
mask3 = mask1 | mask2;
flagm2 = flagm1 + flagm;
fluxerr_old=fluxerr;
fluxerr = Flx - fluxref;
/******** Two-level flux hysterisis: ******************************/
if((fluxerr_old < fluxerr)&& (mask4==0xffff))
mask4=0xffff;
if((fluxerr_old < fluxerr)&& (mask4==0xf7ff)){
if(fluxerr > uplf)mask4=0xffff;
else mask4=0xf7ff;}
if((fluxerr_old > fluxerr)&& (mask4==0xf7ff))
mask4=0xf7ff;
if((fluxerr_old > fluxerr)&& (mask4==0xffff)){
if(fluxerr > lolf)mask4=0xffff;
else mask4=0xf7ff;}
/******************************************************************/
mask5 = mask3 & mask4;
angint1 = angint & mask5;
/*writing to pin 17.18 &19 of XC4005E */
ds1102_p14_pin_io_write(angint1);
/*output to DAC (oscilloscope)*/
output1; output2; output3;output4;
end_isr_t0(); /* end of interrupt service routine */
}
void isr_t1()
{
begin_isr_t1(*error); /* overload check */
/* the count from ds1102_inc() is 4 times */
ie_count=(ds1102_inc(1)*8388608);
/* speed in rad/s of the 200 p.p.r. */
speed=ie_count*(3.1415926)/4;
ds1102_inc_clear_counter(1); /* clearing the counter */
end_isr_t1();
/* end of interrupt service routine */
}
/****************************************************************/
main()
{
int i;
float u3t=0;
float u4t=0;
float speedt=0;
init();
*error = NO_ERROR; /* initialize error flag */
ds1102_p14_pin_io_init(0x1fff);
/* initialise switch status array */
for(i=0; i<=2; i++){
port_pin_read[i] = 0;
}
/**** Calculating the offsets for the currents ******************/
for(i=0; i<=100000; i++){
ds1102_ad_start();
u3 = ds1102_ad(3)*4.1667;
u4 = ds1102_ad(4)*4.1667;
u5=(-u3 - u4);
u3t=u3t + u3;
u4t = u4t + u4;}
offs1=u3t/100001; offs2=u4t/100001;
/****************************************************************/
start_isr_t0(DT); /* initialize sampling clock timer1 */
start_isr_t1(DT2); /* initialize sampling clock timer2 */
while (*error == NO_ERROR)
/* background process */
service_cockpit(); /* call COCKPIT code */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -