各位老师好,我现在用的是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
}
user5308366:
兄弟,你的问题解决了吗
各位老师好,我现在用的是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
}
Igor An:BLDC带HALL传感器控制的算法,一般会遇到软件中的HALL分区标号与实际电机不符的情况,所以请先将软件的分区和实际被控电机的HALL信号对一下。也就是你最后面自己修改的地方,需要确认是否这种HALL信号反馈时,发出的控制PWM是对的。
对于你的问题1没太看明白,
问题2,这确实是奇怪的现象,但总是有原因的,除了正常的信号进来导致捕获发生,一些干扰或者软件的原因也要排查一下。
从你贴的代码看,好像是你从controlSUITE里拉的一些基本库,自己做的代码。
如果做方波的BLDC带HALL控制,可以直接参考controlSUITE里专门为方波控制做的例程,例程位置:
~\ti\controlSUITE\development_kits\DRV8312-C2-KIT_v128\BLDC_Sensored
各位老师好,我现在用的是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
}
user5213609:
回复 user5308366:
程序没看很懂,所以导致一出现问题就不知所措,先好好琢磨琢磨程序,一步一步看,会找出问题的。祝好运。