This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

各位大神老师,求教啊!!!BLDC3-1例程捕获问题

Other Parts Discussed in Thread: CONTROLSUITE, DRV8312-C2-KIT

各位老师好,我现在用的是TI官网的BLDC3_1例程,程序我都能读的通,但是还有下面问题:

1.调试时为什么刚开始捕获到的GPIO口捕获信号一直是7,而且6路PWM信号在刚编译开始时,从第二个开关管单独导通,第四个单独导通,到第六个开光管单独导通,然后再才有两路开关管导通。

2.根本没有捕获发生,但是mod.counter还不停的在递增加1,这是怎么回事?

下面是我的主程序,pwm程序和hall3程序。麻烦各位老师指教,学生真的遇到难处了,困惑了好几天了,一直弄不对,还望各位老师赐教。在此先谢谢了。

void main(void)
{

// Initialize System Control registers, PLL, WatchDog, Clocks to default state:
// This function is found in the DSP281x_SysCtrl.c file.
InitSysCtrl();

// HISPCP prescale register settings, normally it will be set to default values
EALLOW; // This is needed to write to EALLOW protected registers
SysCtrlRegs.HISPCP.all = 0x0000; // SYSCLKOUT/1
EDIS; // This is needed to disable write to EALLOW protected registers

// Disable and clear all CPU interrupts:
DINT;
IER = 0x0000;
IFR = 0x0000;

// Initialize Pie Control Registers To Default State:
// This function is found in the DSP281x_PieCtrl.c file.
InitPieCtrl();

InitPieVectTable();
InitPeripherals(); //4月9日改:外设模块初始化
// User specific functions, Reassign vectors (optional), Enable Interrupts:
EvaRegs.GPTCONA.all = 0;

// Set the Period for the GP timer 2,用通用定时器2干啥?
EvaRegs.T2PR = SYSTEM_FREQUENCY*1000000*T; // Perscaler X1 (T2), ISR period = T x 1

// Clear the counter/compare Regs for GP timer 2
EvaRegs.T2CNT = 0x0000;
EvaRegs.T2CMPR = 0x0000;

// Enable Period interrupt bits for GP timer 2
EvaRegs.EVAIMRB.bit.T2PINT = 1;
EvaRegs.EVAIFRB.bit.T2PINT = 1;

// Count up, x1, internal clk, disable compare, use own period
EvaRegs.T2CON.all = 0x1000;//已经使能计数

// Reassign ISRs.
// Reassign the PIE vector for T2PINT to point to a different
// ISR then the shell routine found in DSP281x_DefaultIsr.c.
// This is done if the user does not want to use the shell ISR routine
// but instead wants to use their own ISR.

EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.T2PINT = &MainISR;//通用定时器2的周期中断频率为80kHz,比pwm的频率高四倍,所以可以采用周期中断不断检测捕获中断的方法,实现单环控制
EDIS; // This is needed to disable write to EALLOW protected registers

// Enable PIE group 3 interrupt 1 for T2PINT
PieCtrlRegs.PIEIER3.all = M_INT1;

// Enable CPU INT3 for T2PINT:
IER |= M_INT3;

// Initialize PWM module
pwm1.PeriodMax = (SYSTEM_FREQUENCY/PWM_FREQUENCY)*1000; // Asymmetric PWM
pwm1.DutyFunc = DFuncDesired; // DutyFunc = Q15
pwm1.init(&pwm1);

// Initialize DATALOG module
dlog.iptr1 = &DlogCh1;
dlog.iptr2 = &DlogCh2;
dlog.iptr3 = &DlogCh3;
dlog.iptr4 = &DlogCh4;
dlog.trig_value = 0x01;
dlog.size = 0x400;
dlog.prescalar = 1;
dlog.init(&dlog);

// Initialize ADC module
adc1.ChSelect = 0x6543; // for DMC1500 and eZdsp2812/eZdsp2808 boards
adc1.init(&adc1);

// Initialize the SPEED_PR module (150 MHz, N = 1 event period/rev)
speed1.InputSelect = 0;
speed1.BaseRpm = 120*(BASE_FREQ/P);//120*f/极数
speed1.SpeedScaler = (Uint32)(ISR_FREQUENCY/(1*BASE_FREQ*0.001));

// Initialize RMPCNTL module
rc1.RampDelayMax = 20;//说明20次中断,才有0.0000305的步进量,这样能计算出多久跟踪到给定值
rc1.RampLowLimit = _IQ(0);
rc1.RampHighLimit = _IQ(1);

// Initialize Hall module
hall1.DebounceAmount = 5;
hall1.Revolutions = -10;
hall1.init(&hall1);
mod1.Counter = Counter;
// Initialize RMP2 module
rmp2.Out = (int32)DFuncDesired;
rmp2.Ramp2Delay = 0x00000050;
rmp2.Ramp2Max = 0x00007FFF;
rmp2.Ramp2Min = 0x0000000F;

// Initialize the PID_REG3 module for dc-bus current
pid1_idc.Kp = _IQ(1);
pid1_idc.Ki = _IQ(T/0.003);//Ki=Kp*T/Ti,Ti为积分时间
pid1_idc.Kd = _IQ(0/T);
pid1_idc.Kc = _IQ(0.2);
pid1_idc.OutMax = _IQ(0.99);
pid1_idc.OutMin = _IQ(0);

// Initialize the PID_REG3 module for speed
pid1_spd.Kp = _IQ(1);
pid1_spd.Ki = _IQ(T/0.1);
pid1_spd.Kd = _IQ(0/T);
pid1_spd.Kc = _IQ(0.2);
pid1_spd.OutMax = _IQ(0.99);
pid1_spd.OutMin = _IQ(0);

EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
EvaRegs.T1CON.bit.TENABLE=1;//开始计数
EvaRegs.T2CON.bit.TENABLE=1;
// IDLE loop. Just sit and loop forever:
for(;;) BackTicker++;

}

interrupt void MainISR(void)//T2的周期中断
{

IsrTicker++;

adc1.read(&adc1);

rc1.TargetValue = _IQ(SpeedRef);
rc1.calc(&rc1);

hall1.HallMapPointer = (int16)mod1.Counter;
hall1.read(&hall1);

mod1.TrigInput =(int32)hall1.CmtnTrigHall;
mod1.Counter = (int32)hall1.HallMapPointer;
mod1.calc(&mod1);

rmp2.DesiredInput = (int32)DFuncDesired;
rmp2.calc(&rmp2);

// Connect inputs of the PID_REG3 module and call the PID speed controller
pid1_spd.Ref = rc1.SetpointValue;
pid1_spd.Fdb = speed1.Speed;
pid1_spd.calc(&pid1_spd);

// Set the speed closed loop flag once the speed is built up to a desired value.
if (rc1.EqualFlag == 0x7FFFFFFF)
{
SpeedLoopFlag = TRUE;
rc1.RampDelayMax = 300;
}

// Connect inputs of the PWM_DRV module and call the PWM signal generation
if (SpeedLoopFlag == FALSE)
{
pwm1.DutyFunc = (int16)rmp2.Out;
}// fixed duty-cycle,如果没有完成SetpointValue对Speedref的跟踪,则占空比也采用步进量。
else
{
pwm1.DutyFunc = (int16)_IQtoIQ15(pid1_spd.Out);
}// controlled Speed duty-cycle,当SetpointValue等于Speedref时,则占空比也采用PID调节的输出量

pwm1.CmtnPointer = (int16)mod1.Counter;
pwm1.update(&pwm1);

// Connect inputs of the SPEED_PR module and call the speed calculation
if ((mod1.Counter == 5)&&(hall1.CmtnTrigHall == 0x7FFF))
{
speed1.TimeStamp = VirtualTimer;
speed1.calc(speed1);
}

// Connect inputs of the DATALOG module
DlogCh1 = (int16)mod1.Counter;
DlogCh2 = (int16)mod1.TrigInput;
DlogCh3 = (int16)_IQtoIQ15(pid1_spd.Ref);
DlogCh4 = (int16)_IQtoIQ15(pid1_spd.Fdb);

// Increase virtual timer and force 15 bit wrap around
VirtualTimer++;
VirtualTimer &= 0x00007FFF;

// Call the DATALOG update function.
dlog.update(&dlog);

// Enable more interrupts from this timer
EvaRegs.EVAIMRB.bit.T2PINT = 1;
EvaRegs.EVAIFRB.all = BIT0;
PieCtrlRegs.PIEACK.all |= PIEACK_GROUP3;
}

void F281X_EV1_HALL3_Init(HALL3 *p)
{
EvaRegs.CAPFIFOA.all = 0x0000; //清空捕获堆栈
//EvaRegs.CAPCONA.bit.CAPRES = 0; //复位CAPA
EvaRegs.EVAIMRC.bit.CAP1INT=1;
EvaRegs.EVAIFRC.bit.CAP1INT=1;
EvaRegs.EVAIMRC.bit.CAP2INT=1;
EvaRegs.EVAIFRC.bit.CAP2INT=1;
EvaRegs.EVAIMRC.bit.CAP3INT=1;
EvaRegs.EVAIFRC.bit.CAP3INT=1;
EvaRegs.CAPCONA.all = 0x8000; //关闭捕获功能
F281X_EV1_HALL3_Determine_State(p);
p->HallGpioBuffer = p->HallGpio; // Init with current CAP/GPIO logic levels
p->HallGpioAccepted = p->HallGpio; // Init with current CAP/GPIO logic levels

EvaRegs.CAPCONA.all = HALL3_INIT_STATE; // Set up capture units, CAP1-3 using GP timer 2
EvaRegs.CAPFIFOA.all = 0x1500; // 写01代表堆栈每接受到一个值,则会有捕获单元中断产生
EALLOW; // Enable EALLOW
GpioMuxRegs.GPAMUX.all |= 0x0700; // Set up the capture 1-3 pins to primary functions
EDIS; // Disable EALLOW

//修改部分,为了启动电机
if(p->HallGpio == 1)//AC相导通
{
Counter = 1;
}
else if(p->HallGpio == 2)//BA相导通
{
Counter = 3;
}
else if(p->HallGpio == 3)//BC相导通
{
Counter = 2;
}
else if(p->HallGpio == 4)//CB相导通
{
Counter = 5;
}
else if(p->HallGpio == 5)//AB相导通
{
Counter = 0;
}
else//CA相导通
{
Counter = 4;
}
}

void F281X_EV1_BLDC_PWM_Init(PWMGEN *p)
{
EvaRegs.T1PR = p->PeriodMax; // Init Timer 1 Period Register
EvaRegs.T1CON.all = BLDCPWM_INIT_STATE; // Init PWM Operation
EvaRegs.ACTRA.all = 0x0FFF;
EvaRegs.GPTCONA.all = 0x0000; //没有设置中断启动ADC转换
EvaRegs.COMCONA.all = 0xCA00;

//EvaRegs.DBTCONA.all = 0x09F0;//死区时间设置为9*16/150

EALLOW; // Enable EALLOW
GpioMuxRegs.GPAMUX.all |= 0x00FF; // Setting PWM1-6 as primary output pins
EDIS; // Disable EALLOW
}

  • 兄弟,你的问题解决了吗

  • BLDC带HALL传感器控制的算法,一般会遇到软件中的HALL分区标号与实际电机不符的情况,所以请先将软件的分区和实际被控电机的HALL信号对一下。也就是你最后面自己修改的地方,需要确认是否这种HALL信号反馈时,发出的控制PWM是对的。
    对于你的问题1没太看明白,
    问题2,这确实是奇怪的现象,但总是有原因的,除了正常的信号进来导致捕获发生,一些干扰或者软件的原因也要排查一下。
    从你贴的代码看,好像是你从controlSUITE里拉的一些基本库,自己做的代码。
    如果做方波的BLDC带HALL控制,可以直接参考controlSUITE里专门为方波控制做的例程,例程位置:


    ~\ti\controlSUITE\development_kits\DRV8312-C2-KIT_v128\BLDC_Sensored
  • 程序没看很懂,所以导致一出现问题就不知所措,先好好琢磨琢磨程序,一步一步看,会找出问题的。祝好运。