📄 bldc.c
字号:
/* ==============================================================================
System Name: BLDC3_2
File Name: BLDC32.C
Description: Primary system file for the implementation of sensorless current
controller for a three phase brushless DC Motor.
Originator: Digital control systems Group - Texas Instruments
Target dependency: x240/1/2/3/07
To Select the target device see target.h file.
=====================================================================================
History: 9-15-2000 Release Rev 1.0
================================================================================= */
/*-----------------------------------------------------------------------------
Get the compilation target setting.
This target is defined by TARGET.H. To change the target, or to find out
the present target, see that file.
-----------------------------------------------------------------------------*/
#include <TARGET.H>
/*-----------------------------------------------------------------------------
Include header information for this file.
-----------------------------------------------------------------------------*/
#include <bldc.h>
//#include "hall_pedal.h" //ygg
/*-------------------------------------------------------------------------------
Get buildlevel information.
---------------------------------------------------------------------------------*/
#include <build.h>
/*-----------------------------------------------------------------------------
System settings
-----------------------------------------------------------------------------*/
#if (TARGET==F243)
#define WAIT_STATES 0x0040
#endif /* (TARGET==F243) */
#if (TARGET==F2407)
#define WAIT_STATES 0x00C0
#endif /* (TARGET==F243) */
/*-----------------------------------------------------------------------------
Global Declarations
/*-----------------------------------------------------------------------------
Instance the EVMDAC Interface.
-----------------------------------------------------------------------------*/
EVMDAC dac = EVMDAC_DEFAULTS;
/*-----------------------------------------------------------------------------
Instance the PWM Generator (Driver) Interface.
Also initalize the PWMGEN object.
This pre-initializer takes on the nature depending on the TARGET device.
An IMPORTANT NOTE :
This pre-initalization initializes the PWMGEN data structure in
memory. This WILL NOT initialize the PWM Generator timers and
so on. This is accomplished by calling the init method in the
PWMGEN object. This applies to most drivers that supply an init
method.
-----------------------------------------------------------------------------*/
PWMGEN pwm = PWMGEN_DEFAULTS;
/*-----------------------------------------------------------------------------
Instance the ADC (Driver) Interface.
Also initalize the ADCVALS object.
This pre-initializer takes on the nature depending on the TARGET device.
An IMPORTANT NOTE :
This pre-initalization initializes the ADCVALS data structure in
memory. This WILL NOT initialize the ADC CONTROLS and
so on. This is accomplished by calling the init method in the
ADCVALS object.
-----------------------------------------------------------------------------*/
ADCVALS adc = ADC_DEFAULTS;
/*-----------------------------------------------------------------------------
Instance a single BLDC_TI object.
-----------------------------------------------------------------------------*/
BLDC_TI bldc = BLDC_TI_INITVALS;
/*-----------------------------------------------------------------------------
Instance the WATCHDOG Interface.
-----------------------------------------------------------------------------*/
WATCHDOG wdog = WATCHDOG_DEFAULTS;
/*-----------------------------------------------------------------------------
Instance the ISR checking variable
-----------------------------------------------------------------------------*/
int isr_ticker;
int g_temp1=0;
int g_temp2=0;
int g_temp3=0;
unsigned int g_errcode = 0;
unsigned int flag = 0;
unsigned int bldc_step = 1; //BLDC的六步标志
unsigned int bldc_stepBufferFlag = 0;
unsigned int bldc_step_cnt = 0;
unsigned int adc4 = 4;
unsigned int adc2 = 2;
unsigned int adc1 = 1;
unsigned int adc0 = 0; //CUR_A 电流传感器
unsigned int CWFlg = 0;
unsigned int CWOldFlg = 1; //!!
unsigned int CCWFlg = 1; //逆时针方向是默认正方向
unsigned int CCWChangeFlg = 1; //!!
unsigned int g_hall = 0;
unsigned int g_OldHall = 0;
unsigned int g_hallFlg = 0;
unsigned int g_pedal_digital = 0;
unsigned int g_unUpFlg = 0;
unsigned int g_unStopFlg = 0;
unsigned int g_DutyCycle = 9980;
unsigned int g_DutyCycleLast = 0;
unsigned int g_DutyCycleNot = 0;
unsigned int g_DutyCycle_FLG = 0;
unsigned int g_DutyCycle_CNT = 0;
unsigned int g_unSpeedRef = 0; // 设定目标 Desired Value
unsigned int g_unSpeedFdb = 0;
unsigned int g_unSpeedFdbBig = 0;
unsigned int g_unSpeedFdbMax = 0;
unsigned int g_unSum;
unsigned int g_unKP = 0; // 比例常数 Proportional Const
unsigned int g_unKI = 0; // 积分常数 Integral Const
unsigned int g_unKD = 0; // 微分常数 Derivative Const
int g_unMin = 0; //观察变量
int g_unMax = 0;
unsigned int g_unADCInput = 0;
unsigned int g_unADCOutput = 0;
int g_nErr = 0; // 当前误差 g_nDeviation[0]
int g_nLastErr = 0; // 上次误差 g_nDeviation[-1]
long g_lUp = 0;
long g_lUi = 0;
long g_lUimin = 0;
long g_lUimax = 0;
long g_lUd = 0;
long g_lSum = 0;
volatile unsigned int *j;
unsigned int ADRESULT0[8];
unsigned int ADRESULT1[8];
unsigned int ADRESULTSum = 0;
unsigned int ADRESULTHighSum = 0;
unsigned int i = 0;
unsigned int ii = 0;
unsigned int g_unLastPst = 0;
long g_lCRTSum = 0;
unsigned int CCWOldFlg = 0;
void main()
{
/*-----------------------------------------------------------------------------
Return system to a sane condition
-----------------------------------------------------------------------------*/
RstSystem(); //ygg
/*-----------------------------------------------------------------------------
Initialize PWM generator
-----------------------------------------------------------------------------*/
pwm.init(&pwm); /* pwm driver initialization *///已经合并
/*-----------------------------------------------------------------------------
Initialize ADC driver
-----------------------------------------------------------------------------*/
// adc.init(&adc); /* adc driver initialization ?? ygg yes */
/*-----------------------------------------------------------------------------
Initialize time base generator
-----------------------------------------------------------------------------*/
time_base_init();
/*-----------------------------------------------------------------------------
Initialise the Real time monitor
-----------------------------------------------------------------------------*/
//#if (REAL_TIME == TRUE)
// rtmon_init(); /* Call the monitor init function */
//#endif /* REAL_TIME==TRUE */
/*-----------------------------------------------------------------------------
Hardware/Board Specific Initialization
-----------------------------------------------------------------------------*/
evm_pwm_init();
hall_pedal_init(); //ygg
encoder_init(); //ygg
PIDInit(); //ygg
/*-----------------------------------------------------------------------------
ADC channel select
Channels 6,5,4,3 for 243EVM with DMC1500
Channels 12,11,10,5 for 2407EVM/6,5,4,3 for 2407eZdsp with DMC1500
-----------------------------------------------------------------------------*/
// adc.a4_ch_sel = CHANNEL_SETTINGS;
/*-----------------------------------------------------------------------------
Intialize the BLDC_TI object. This is a call to the init method within
the BLDC_TI object bldc
-----------------------------------------------------------------------------*/
// BLDC_TI_Init(&bldc);
// pwm.d_func = ALIGN_DUTY;
#if (BUILDLEVEL==LEVEL1)
// dac.qptr0 = &bldc.impl.out;
#endif /* BUILDLEVEL==LEVEL1 */
enable_ints(); /* set off the system running */
while(1) /* Nothing running in the background at present */
{
} /* Main system background loop */
} /* End: main() */
void interrupt c_adint()
{
asm(" CLRC SXM ");
ADCTRL2 = ADCTRL2 | 0X0200;
adc4 = (unsigned int)(RESULT2) >> 3; //已经修改为第三通道
// if (adc4 < 80)
// adc4 = 80;
// else if (adc4 > 660)
// adc4 = 660;
adc0 = (unsigned int)(RESULT0) >> 6; //电流环采样
adc1 = (unsigned int)(RESULT1) >> 6;
adc2 = (unsigned int)(RESULT3) >> 6;
if (g_unMin > adc0)
g_unMin = adc0;
if (g_unMax < adc0)
g_unMax = adc0;
g_unSpeedRef = (unsigned int)RESULT2 >> 3; //参考值没有经过滤波
if (g_unSpeedRef < 640) //200rpm范围内 512-->500
g_unSpeedRef = 640;
if (g_unSpeedRef > 6250)
g_unSpeedRef = 6250;
currentFdb_calc();
}
void interrupt c_int02()
{
asm(" CLRC XF ");
isr_ticker++;
/*---------------------------------------------------------------------------*/
#if TARGET==F243
EVIFRB=0x0ffff; /* Clear all Group A EV interrupt flags */
#elif TARGET==F2407
EVAIFRA=0x0ffff; /* Clear all EV1 Group A EV interrupt flags ft!*/
#endif/* #if TARGET */
asm(" SETC XF ");
//-------------------------------------------ygg
//DSP的pwm管脚(IGBT标号)
// pwm1(pwmA+) pwm3(pwmB+) pwm5(pwmC+)
// pwm2(pwmA-) pwm4(pwmB-) pwm6(pwmC-)
//利用hall信号进行几步之间的切换
read_hall();
if (g_pedal_digital == 0)
{
if (g_unSpeedRef < 640) //200rpm范围内 512-->500
g_unSpeedRef = 640;
if (g_unSpeedRef > 6250)
g_unSpeedRef = 6250;
speedFdb_calc();
if (g_unSpeedFdb < 0) //特别注意
g_unSpeedFdb = 0;
if (g_unSpeedFdb >120)
g_unSpeedFdb = 120;
// SpeedPID_calc();
// g_DutyCycleNot = (adc0 - 80) * 125 / 29; //[0 -- 2500] 出现计算16位溢出
// g_DutyCycleNot = ((adc0 - 80) * 50 / 29) * 5; //[0 -- 2500]
// if ((int)(g_DutyCycleNot - g_DutyCycleLast) > 2)//pwm速率限制??? 0-1>1是可以出现的?必须强制类型转换
// g_DutyCycleLast += 2;
// else if ((int)(g_DutyCycleLast - g_DutyCycleNot) > 2)
// g_DutyCycleLast -= 2;
// else
// g_DutyCycleLast = g_DutyCycleNot; //速度限制结论:3不行2、1可以
if (g_DutyCycleNot > g_DutyCycleLast)
g_DutyCycleLast += 2;
else if (g_DutyCycleNot < g_DutyCycleLast)
g_DutyCycleLast -= 2;
else
g_DutyCycleLast = g_DutyCycleNot;
//
if (g_DutyCycleLast > 5000) //~~<<<[0 -- 500]
g_DutyCycleLast = 5000;
g_DutyCycle = 5000 - g_DutyCycleLast; //[1000 -- 500]
// g_DutyCycle = 5000; //设置pwm输出封口 !
if (CCWFlg == 1) //逆时针正方向运行
{
if (g_OldHall != g_hall)
{
g_OldHall = g_hall;
bldc_stepBufferFlag = 0;
if (g_hall == 0x0001) //001
bldc_step = 2;
else if (g_hall == 0x0005) //101
bldc_step = 3;
else if (g_hall == 0x0004) //100
bldc_step = 4;
else if (g_hall == 0x0006) //110
bldc_step = 5;
else if (g_hall == 0x0002) //010
bldc_step = 6;
else if (g_hall == 0x0003) //011
bldc_step = 1;
else
bldc_step = 0;
}
}
else if (CWFlg == 1) //顺时针反方向运行
{
if (g_OldHall != g_hall)
{
g_OldHall = g_hall;
bldc_stepBufferFlag = 0;
if (g_hall == 0x0001) //001
bldc_step = 5;
else if (g_hall == 0x0005) //101
bldc_step = 6;
else if (g_hall == 0x0004) //100
bldc_step = 1;
else if (g_hall == 0x0006) //110
bldc_step = 2;
else if (g_hall == 0x0002) //010
bldc_step = 3;
else if (g_hall == 0x0003) //011
bldc_step = 4;
else
bldc_step = 0;
}
}
else
bldc_step = 0;
//-------------------------------------------ygg
//DSP的pwm管脚(IGBT标号)
// pwm1(pwmA+) pwm3(pwmB+) pwm5(pwmC+)
// pwm2(pwmA-) pwm4(pwmB-) pwm6(pwmC-)
bldc_step = 6;
g_DutyCycle = 4600;
if (bldc_step == 1) //g_hall=001,测量为静态情况
{
// CMPR3 = g_DutyCycle;
CMPR1 = g_DutyCycle; //有效PWM1的低电平占空比=(T1PR-COMPR1)/T1PR=??/10000//实际上高电平的占空比
// if (bldc_stepBufferFlag > 20)
// {
// ACTRA = 0x0D3F; // 15 4通
// ACTRA &= 0xFFFD;
// bldc_stepBufferFlag++;
// }
// else
ACTRA = 0x0F3D; //设置pwm1为低电平有效,pwm4强制为低
}
else if (bldc_step == 2) //101
{
CMPR1 = g_DutyCycle; //有效PWM1的低电平占空比=(T1PR-COMPR1)/T1PR=??/10000//实际上高电平的占空比
// if (bldc_stepBufferFlag > 20)
// {
// ACTRA = 0x0F3D;
// ACTRA &= 0xF3FF; //pwm6强制为低,1 46通
// bldc_stepBufferFlag++;
// }
// else
ACTRA = 0x03FD; //设置pwm1为低电平有效,pwm6强制为低
}
else if (bldc_step == 3) //100
{
// CMPR1 = g_DutyCycle;
CMPR2 = g_DutyCycle; //有效PWM1的低电平占空比=(T1PR-COMPR1)/T1PR=??/10000//实际上高电平的占空比
// if (bldc_stepBufferFlag > 20)
// {
// ACTRA = 0x03FD;
// ACTRA &= 0xFFDF; //设置pwm3为低电平有效,13 6通
// bldc_stepBufferFlag++;
// }
// else
ACTRA = 0x03DF; //设置pwm3为低电平有效,pwm6强制为低
}
else if (bldc_step == 4) //110
{
CMPR2 = g_DutyCycle; //有效PWM1的低电平占空比=(T1PR-COMPR1)/T1PR=??/10000//实际上高电平的占空比
// if (bldc_stepBufferFlag > 20)
// {
// ACTRA = 0x03DF;
// ACTRA &= 0xFFF3; //3 62通
// bldc_stepBufferFlag++;
// }
// else
ACTRA = 0x0FD3; //设置pwm3为低电平有效,pwm2强制为低
}
else if (bldc_step == 5) //010
{
// CMPR2 = g_DutyCycle;
CMPR3 = g_DutyCycle; //有效PWM1的低电平占空比=(T1PR-COMPR1)/T1PR=??/10000//实际上高电平的占空比
// if (bldc_stepBufferFlag > 20)
// {
// ACTRA = 0x0FD3; //35 2通
// ACTRA &= 0xFDFF;
// bldc_stepBufferFlag++;
// }
// else
ACTRA = 0x0DF3; //设置pwm5为低电平有效,pwm2强制为低 0DF3
}
else if (bldc_step == 6) //011
{
CMPR3 = g_DutyCycle; //有效PWM1的低电平占空比=(T1PR-COMPR1)/T1PR=??/10000//实际上高电平的占空比
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -