2019-08-07 12:00 AM
I want to measure the rpm of bldc motor, so by using hall sensor (H.S) output we can capture the frequency. With help of Hall sensor frequency and num of motor poles, we can able to measure the RPM. I captured the frequency successfully by using input capture mode in stm32f103 .
Works well without running motor:
Works too bad while running motor: ( PROBLEM )
// Input capture mode...
#include "stm32f10x.h"
int n; int gap;
float counter0,counter1,Counter,Frequency,RPM;
int main()
{
RCC->APB2ENR |=RCC_APB2ENR_TIM1EN;
GPIOA->CRH&=~GPIO_CRH_CNF8;
GPIOA->CRH|=(1<<3);
GPIOA->ODR|=(1<<8);
TIM1->PSC|=719;
TIM1->CCMR1 |=TIM_CCMR1_CC1S_0; // set T1[1] as input capture
TIM1->CCER &=~TIM_CCER_CC1P; // Rising edge
TIM1->CCMR1 &=~TIM_CCMR1_IC1PSC; // Diabling the PSC
TIM1->DIER |=TIM_DIER_UIE|TIM_DIER_CC1IE;
TIM1->CCER |=TIM_CCER_CC1E;
TIM1->CR1 |= TIM_CR1_CEN;
NVIC_EnableIRQ(TIM1_CC_IRQn);
while(1)
{
}
}
void TIM1_CC_IRQHandler(void)
{
if ((TIM1->SR & TIM_SR_CC1IF) != 0)
{
if ((TIM1->SR & TIM_SR_CC1OF) != 0) /* Check the overflow */
{
/* Overflow error management */
gap = 0; /* Reinitialize the laps computing */
TIM1->SR &= ~(TIM_SR_CC1OF | TIM_SR_CC1IF); /* Clear the flags */
}
if (gap == 0) /* Test if it is the first rising edge */
{
counter0 = TIM1->CCR1; /* Read the capture counter which clears the
CC1ICF */
gap = 1; /* Indicate that the first rising edge has yet been detected */
}
else
{
counter1 = TIM1->CCR1; /* Read the capture counter which clears the
CC1ICF */
if (counter1 > counter0) /* Check capture counter overflow */
{
Counter = counter1 - counter0;
Frequency=100000/Counter;
RPM=(Frequency*60)/4;
}
else
{
Counter = counter1 + 0xFFFF - counter0 + 1;
Frequency=100000/Counter;
RPM=(Frequency*60)/4;
}
counter0 = counter1;
}
}
else
{
/* Unexpected Interrupt */
/* Manage an error for robust application */
}
}
MCU - stm32f103
Timer pin - A8
2019-08-09 11:13 PM
Guys i don't know if i am asked anything wrong , kindly guide me.
Waiting for your reply guys.
2019-08-09 11:13 PM
Waiting for your reply gugs
2019-08-10 12:31 AM
> But when i run motor and ... multi-meter anything
Can You elaborate on this?
I haven't worked with input capture mode, so can't comment on that much, but there rises one general question - have You looked at that signal with oscilloscope?
2019-08-10 01:30 AM
@Piranha Input capturing is used to capture the signals frequency. I am running bldc motor using stm32 and want to measure the rpm of the motor. So by pinging the H.S pin we can able to capture the H.S frequency, with that we can calculate the RPM.
-By using stm32 i programmed to run bldc motor (code 1), which runs good.
-For input capture method also, i programmed it using register language(code 2) and i tested by giving 500hz square wave using multi-meter. which works well.
But when i combine the code 1&2 to run the bldc motor and to capture signals frequency. The motor runs good, but stm32 cant able to capture the signals frequency.
I uploaded only code 2. Because i cannot upload code 1.
2019-08-10 06:01 AM
Just for fun (for me) I improved Your code "a little bit"...
#include "stm32f10x.h"
uint16_t nRPM;
int main(void)
{
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
GPIOA->CRH = (GPIOA->CRH & ~GPIO_CRH_CNF8) | (1ul << 3);
GPIOA->BSRR = 1ul << 8;
TIM1->PSC = 720 - 1;
TIM1->CCMR1 = 1ul << TIM_CCMR1_CC1S_Pos;
TIM1->CCER = TIM_CCER_CC1E;
TIM1->DIER = TIM_DIER_CC1IE;
TIM1->CR1 = TIM_CR1_CEN;
NVIC_EnableIRQ(TIM1_CC_IRQn);
for (;;) {
}
}
void TIM1_CC_IRQHandler(void)
{
// Does not need interrupt flag checking as we have only one interrupt enabled
static bool fRun;
uint16_t tCapture1 = TIM1->CCR1; // Read capture register first to minimize possibility of overcapture
if (TIM1->SR & TIM_SR_CC1OF) {
TIM1->SR = ~TIM_SR_CC1OF;
fRun = false;
}
static uint16_t tCapture0_;
if (fRun && (tCapture1 != tCapture0_)) { // Prevent tDelta == 0 and division by zero
uint16_t tDelta = tCapture1 - tCapture0_; // Subtracts correctly at integer overflow
nRPM = (60 * 100000 / 4) / tDelta; // No floating point operations needed
} else {
fRun = true;
}
tCapture0_ = tCapture1;
}
Though I left only comments related to key aspects. General logic restructuring, no floating point operations (particularly important as Cortex-M3 doesn't have FPU), integer arithmetic respective to overflow, static variables, not doing unnecessary/wrong reads and bitwise operations when assigning register values, code formatting - You can learn much from this. =)
Also take a note that this code (both versions) is not able to capture or detect speeds lower than 23 RPM (tDelta == 0xFFFF) - it'll calculate wrong speed.
P.S. You didn't answer about signal on oscilloscope.