Tool/software: Code Composer Studio
Hello,
I have been working looking for a way to calculate rpm with hall sensor and it seems ECap is the best suit for it.
I have successfully initialized ECap and i managed to perform RPM calculation but i have got a problem if my motor stops spinning momentarily ECap interrupt's data stays at previous interrupt's data before motor stopped.
for example motor spins 1200 rpm i see 1199-1200 rpm and if i shut down power supply of motor. ECap stops reading hall sensor with latest value of 1199rpm unless i start motor back. I understand that since there is no rising edge means no interrupt but there must be a way to understand motor stopped..
I couldnot find an algorithm or register that if motor is not spinning is should return zero.( except motors off state rpm is almost perfect just cant return to 0 rpm)
my motor has 4 pole pairs so i set interrupt in a way that 1 interrupt appears on 1 full turn.
my ECap init;
void InitECapture()
{
EALLOW;
ECap1Regs.ECEINT.all = 0x0000; // Disable all capture interrupts
ECap1Regs.ECCLR.all = 0xFFFF; // Clear all CAP interrupt flags
ECap1Regs.ECCTL1.bit.CAPLDEN = 0; // Disable CAP1-CAP4 register loads
ECap1Regs.ECCTL2.bit.TSCTRSTOP = 0; // Make sure the counter is stopped
ECap1Regs.ECCTL1.bit.CAP1POL = 0;
ECap1Regs.ECCTL1.bit.CAP2POL = 0;
ECap1Regs.ECCTL1.bit.CAP3POL = 0;
ECap1Regs.ECCTL1.bit.CAP4POL = 0;
ECap1Regs.ECCTL1.bit.CTRRST1 = 1;
ECap1Regs.ECCTL1.bit.CTRRST2 = 1;
ECap1Regs.ECCTL1.bit.CTRRST3 = 1;
ECap1Regs.ECCTL1.bit.CTRRST4 = 1;
ECap1Regs.ECCTL1.bit.CAPLDEN = 1;
ECap1Regs.ECCTL1.bit.PRESCALE = 0;
ECap1Regs.ECCTL2.bit.CAP_APWM = 0;
ECap1Regs.ECCTL2.bit.CONT_ONESHT = 0;
ECap1Regs.ECCTL2.bit.SYNCO_SEL = 2;
ECap1Regs.ECCTL2.bit.SYNCI_EN = 0;
ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1;
ECap1Regs.ECEINT.bit.CEVT1 = 0; // 1 Capture Event 1 Interrupt Enable
ECap1Regs.ECEINT.bit.CEVT2 = 0; // 2 Capture Event 2 Interrupt Enable
ECap1Regs.ECEINT.bit.CEVT3 = 0; // 3 Capture Event 3 Interrupt Enable
ECap1Regs.ECEINT.bit.CEVT4 = 1; // 4 Capture Event 4 Interrupt Enable
ECap1Regs.ECEINT.bit.CTROVF = 0; // 5 Counter Overflow Interrupt Enable
ECap1Regs.ECEINT.bit.CTR_EQ_PRD = 0; // 6 Period Equal Interrupt Enable
ECap1Regs.ECEINT.bit.CTR_EQ_CMP = 0; // 7 Compare Equal Interrupt Enable
// ECAP interrupt clear
ECap1Regs.ECCLR.bit.INT = 1; // 0 Global Flag
ECap1Regs.ECCLR.bit.CEVT1 = 1; // 1 Capture Event 1 Interrupt Flag
ECap1Regs.ECCLR.bit.CEVT2 = 1; // 2 Capture Event 2 Interrupt Flag
ECap1Regs.ECCLR.bit.CEVT3 = 1; // 3 Capture Event 3 Interrupt Flag
ECap1Regs.ECCLR.bit.CEVT4 = 1; // 4 Capture Event 4 Interrupt Flag
ECap1Regs.ECCLR.bit.CTROVF = 1; // 5 Counter Overflow Interrupt Flag
ECap1Regs.ECCLR.bit.CTR_EQ_PRD = 1; // 6 Period Equal Interrupt Flag
EDIS;
}
also my ECap interrupt ;
__interrupt void
ecap1_isr(void)
{
ECap1IntCount++;
periodCap1[0] = ECap1Regs.CAP1;
periodCap1[1] = ECap1Regs.CAP2;
periodCap1[2] = ECap1Regs.CAP3;
periodCap1[3] = ECap1Regs.CAP4;
periodCap1[4] = periodCap1[0] + periodCap1[1] + periodCap1[2] + periodCap1[3];
periodCap1[4]= periodCap1[4]/CPU_CLK;
rpm[0] = min/periodCap1[4];
kmh[0] = (rpm[0]*PI*diameter*min)/constant;
ECap1Regs.ECCLR.bit.CEVT1 = 1;
ECap1Regs.ECCLR.bit.CEVT2 = 1;
ECap1Regs.ECCLR.bit.CEVT3 = 1;
ECap1Regs.ECCLR.bit.CEVT4 = 1;
ECap1Regs.ECCLR.bit.INT = 1;
//
// Acknowledge this interrupt to receive more interrupts from group 4
//
PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;
}