📄 vhz_wx.c
字号:
#include "f2407_c.h"
#include "cursample.h"
#include "freq_theta.h"
#include "polar_rect_c.h"
#include "qep.h"
#include "scopead.h"
#include "sincos.h"
#include "softsvpwm_c.h"
#include "volt_freq_c.h"
#include "var_vhz_wx.c"
#include "init_vhz_wx.c"
#include "int_vhz_wx.c"
unsigned int ave_adresult=0,adresult[4]={0,0,0,0},sz1=0;
unsigned int handflag=0;
unsigned int handstart=0,handstop=0;
unsigned int autoflag=0;
unsigned int autostart=0,autostop=0,autostart1=0;
unsigned int iovalue[3]={0,0,0},lastiovalue=0,sz=0;
unsigned int speed_ref=0; //保存接收到的转速显示器速度给定
unsigned int speed_rec_flag=0,time_rec_flag=0;
void variable_init(void);
void kickdog(void);
void clearipm(void);
void mailbox0rec(void);
void mailbox1rec(void);
void mailbox2rec(void);
void mailbox3send(void);
void read_io(void);
void stop(void);
main()
{ sysinit();
wdinit();
variable_init();
qepinit();
caninit();
mailbox2_init();
mailbox3_init();
mailbox0_init();
mailbox1_init();
pdpinit();
pwminit();
adinit();
ioinit();
kickdog();
asm(" CLRC INTM");
for(;;)
{
/////////////////////////////////2005-11-8///////////
if(flagspeedchang==1)
{
flagspeedchang=0;
if(freq_ref_out.freq_ref_max-freq_ref_out.freq_ref!=0) //如果发生了频率更新,则执行以下的操作
{
if(freq_ref_out.freq_ref_max>freq_ref_out.freq_ref) //如果更新后的频率大于原来的参考频率,则执行下面的操作
{
freq_ref_out.freq_ref=freq_ref_out.freq_ref+freq_ref_slope_out.freq_ref_slope;
if(freq_ref_out.freq_ref>freq_ref_out.freq_ref_max)
freq_ref_out.freq_ref=freq_ref_out.freq_ref_max;
if(freq_ref_out.freq_ref<frequence_min)
freq_ref_out.freq_ref=frequence_min;
}
if(freq_ref_out.freq_ref_max<freq_ref_out.freq_ref) //如果更新后的频率小于原来的参考频率,则执行下面的操作
{
freq_ref_out.freq_ref=freq_ref_out.freq_ref-freq_ref_slope_out.freq_ref_slope;
if(freq_ref_out.freq_ref<freq_ref_out.freq_ref_max)
freq_ref_out.freq_ref=freq_ref_out.freq_ref_max;
if(freq_ref_out.freq_ref<frequence_min) //如果更新后的频率小于最小频率,则取最小值
freq_ref_out.freq_ref=frequence_min;
}
}
}
////////////////////////////////////////
// if(ipmfault==1) clearipm(); //如果有错误信号,则清除
mailbox0rec();
mailbox1rec();
mailbox2rec();
mailbox3send();
if(soft_timer.key_timer>=30) //3ms读一次按键,读3次,相同则有效
{
soft_timer.key_timer=0;
read_io();
}
if(handflag==1)
{
if((handstart==1)&&(handstop==0))
{
flagflag=1;
ave_adresult=(adresult[0]+adresult[1]+adresult[2]+adresult[3])>>2; //取AD采样的平均值,并右移6位
//此处AD的最大值对应300Hz,对应Q16格式的0xffff;
freq_ref_out.freq_ref_max=ave_adresult*64; //(ave_adresult*0xffff)/1024; //注意此处为Q16格式,基值为300Hz
if(freq_ref_out.freq_ref_max<frequence_min)
freq_ref_out.freq_ref_max=frequence_min;
if((*ACTRB&0x0fff)!=0x999 )
*ACTRB=(*ACTRB&0xF000)|0x999; //PWM8,10,12 active high,PWM7,9,11 active low
}
else
{
stop();
}
}
if(autoflag==1)
{
if((autostart==1)&&(autostop==0)&&(autostart1==1))
{
flagflag=1;
fspeed=(float)speed_ref;
// freq_ref_out.freq_ref_max=(int)(fspeed*728/100); // 7.28 P=2 speed_ref为接收的转速显示器给定转速(speed_ref*p/60)*2^16/300
// freq_ref_out.freq_ref_max=(int)(fspeed*1092/100); // 10.92 P=3 speed_ref为接收的转速显示器给定转速(speed_ref*p/60)*2^16/300
freq_ref_out.freq_ref_max=(int)(fspeed*364/100); // 3.64 虎溪 P=1 speed_ref为接收的转速显示器给定转速(speed_ref*p/60)*2^16/300
if(freq_ref_out.freq_ref_max<frequence_min)
freq_ref_out.freq_ref_max=frequence_min;
if((*ACTRB&0x0fff)!=0x999 )
*ACTRB=(*ACTRB&0xF000)|0x999; //PWM8,10,12 active high,PWM7,9,11 active low
}
else
{
stop();
}
}
if((handflag==0)&&(autoflag==0))
{
stop();
if(ipmfault==1) clearipm(); //如果有错误信号,则清除
}
kickdog();
}
}
void kickdog(void)
{
*WDKEY=0x5555;
*WDKEY=0xAAAA;
}
void variable_init(void)
{
freq_theta_out.ktheta=k_theta;
freq_theta_out.theta=0;
polar_rect_out.ualfa=0;
polar_rect_out.ubeta=0;
sincos_out.inv_step=sincos_inv_step;
sincos_out.k_cosx=sincos_k_cos;
sincos_out.sinx=0;
sincos_out.cosx=0;
// svpwm_out.Vdcinvt=0x608; // 刘和平 T_pwm*线电压峰值/直流母线电压=0x609; T_pwm=2000;
svpwm_out.Vdcinvt=T_pwm; // 2000*380*1.414/537 ;2000对应10KHZ
svpwm_out.PWMPRD=T_pwm;
svpwm_out.va=0;
svpwm_out.vb=0;
svpwm_out.vc=0;
vhz_volt_out.slope=vHz_slope_init;
vhz_volt_out.uout=0;
freq_ref_out.freq_ref_max=frequence_min;
freq_ref_out.freq_ref=frequence_min;
freq_ref_slope_out.freq_ref_slope=0x01;
soft_timer.timer=0;
soft_timer.speed_timer=0;
soft_timer.key_timer=0;
}
////////////////////清IPM模块错误信号程序
void clearipm(void)
{
int i=0;
*EVBIFRA=*EVBIFRA|0x0001;
for(i=0;i<20000;i++); //延时清错误信号
if((*COMCONB&0x0100)==0x0100)
{
ipmfault=0;
*COMCONB=*COMCONB|0x0200; //使能PWM输出
}
}
void read_io(void) //注意手动自动选择开关是自锁开关, 启动停止按钮是按键
{
int temp;
adresult[sz1]=*RESULT8>>6;
sz1=sz1+1;
if(sz1>=4) sz1=0;
temp=*PBDATDIR&0x003f;
iovalue[sz]=temp;
sz=sz+1;
if(sz>=3) sz=0;
if((iovalue[0]==iovalue[1])&&(iovalue[1]==iovalue[2])) lastiovalue=iovalue[0];
if(((lastiovalue&0x01)==0)&&((lastiovalue&0x08)!=0)) //手动
{
handflag=1;
if(((lastiovalue&0x02)==0)&&((lastiovalue&0x04)!=0))
{
handstart=1;
handstop=0;
}
if(((lastiovalue&0x02)!=0)&&((lastiovalue&0x04)==0))
{
handstart=0;
handstop=1;
}
}
if(((lastiovalue&0x01)!=0)&&((lastiovalue&0x08)==0)) //自动
{
autoflag=1;
if(((lastiovalue&0x10)==0)&&((lastiovalue&0x20)!=0))
{
autostart=1;
autostop=0;
}
if(((lastiovalue&0x10)!=0)&&((lastiovalue&0x20)==0))
{
autostart=0;
autostop=1;
}
}
if((((lastiovalue&0x01)==0)&&((lastiovalue&0x08)==0))|(((lastiovalue&0x01)!=0)&&((lastiovalue&0x08)!=0)))
{
handflag=0;
autoflag=0;
}
}
void mailbox3send(void)
{
if((soft_timer.timer-soft_timer.can_timer)>=mailbox3_refresh) //向上位机发送电机转速信息100ms发一次
//if the interval larger than 5ms, then refresh the MBX3A
{
soft_timer.can_timer=soft_timer.timer;
if(*TCR&0x2000==0)
asm( "nop"); //如果上一次发送成功,才更新发送缓冲区的数据
else
{
*TCR=*TCR|0x2000; //清除发送成功位
*MCR=(*MCR&0xFFFC)|0x103; //CPU request to change the data field of mailbox3
if(speed_rec_flag==1)
*MBX3A=(*MBX3A&0xff00)|0x0055;
if(time_rec_flag==1)
*MBX3A=(*MBX3A&0x00ff)|0x5500;
if(freq_ref_out.freq_ref!=0) //电机启动
*MBX3C=(*MBX3C&0xff00)|0x0055;
fspeed=(float)(freq_ref_out.freq_ref);
// fspeed=20*fspeed*300/65535; //注意:20=60/P;P=3;其中P为电机极对数
fspeed=60*fspeed*300/65535; //注意:20=60/P;P=1;其中P为电机极对数
speed=(int)fspeed;
// speed=30*(((freq_ref_out.freq_ref>>8)*300)>>8); //P=2
*MBX3B=speed;
// *MBX3C=speed;
// *MBX3D=speed;
*MCR=*MCR&0xFEFF; //CPU request normal operation
*TCR=*TCR|0X20;
}
}
}
///////////////////////////////CAN接收程序///////////////////////////
void mailbox0rec(void) //邮箱0接收电机转速显示器发送的转速给定,地址为0xAA+000b
{
if((*RCR&0x10)==0x10) //mailbox0 checking
{
speed_ref=*MBX0B;
speed_rec_flag=1; //速度接收成功标志置1
*RCR=*RCR|0x10;
}
}
void mailbox1rec(void) // 邮箱1接收时间显示器的时间参数,地址为0xA5+000b
{
if((*RCR&0x20)==0x20)
{
if(*MBX1D==0x5555) autostart1=1;
if(*MBX1D!=0x5555)
{
autostart1=0;
autostart=0;
}
time_rec_flag=1; // 接收时间成功标志置1
*RCR=*RCR|0x20;
}
}
void mailbox2rec(void) //邮箱2接收上位机的转速给定,地址为0xAA+010b
{
if((*RCR&0x40)==0x40)
{
if(*MBX1D==0x5555) autostart1=1;
if(*MBX1D!=0x5555)
{
autostart1=0;
autostart=0;
}
time_rec_flag=1; // 接收时间成功标志置1
*RCR=*RCR|0x40;
}
}
///////////////////2005-10-21//////////
void stop(void) //电机停止过程频率给定逐渐减小,当减小到最小值时在给0,然后在关断PWM
{
if(freq_ref_out.freq_ref_max>freq_ref_out.freq_ref) //如果启动未完成就按停止,则从当前频率开始减小
freq_ref_out.freq_ref_max=freq_ref_out.freq_ref;
if(freq_ref_out.freq_ref<=frequence_min)
{
flagflag=0;
freq_ref_out.freq_ref=0;
*ACTRB=0x1FFF; //vector rotate positive, PWM7,8,9,10,11,12 force high
}
else
freq_ref_out.freq_ref_max=freq_ref_out.freq_ref_max-freq_ref_slope_out.freq_ref_slope;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -