请帮忙分析下这个马达控制问题
- BLDC001
- 2
- 来自:马达驱动
- 2018-11-16
老师,请耐心帮忙看下这段代码为什么实现不了通过读霍尔信号来计算电机转速的想法?
问题描述:马达众筹有感软件中计算电机转速的方法是通过TIM2定时60电角度,然后利用公式推导出来。而我想实现通过TIM3引脚的输入捕获功能来捕获某一路HALL信号的一个电周期的时间(从一个上升沿到另一个上升沿),TIM3的配置如下:
请问:TIM3的配置是否有问题?我编译后没错误,但是刷进去后,让电机转起来,但是LCD显示的电机转速为0,也就是我TIM3捕获计算的电机转速为0,但是电机确实在转动。是哪里导致捕获失败?
/*******************************增加TIM3输入比较获得转速*******************************/
//以下代码放在Sys.c文件中
/* TIM3时基 */
TIM_TimeBaseStructure.TIM_Prescaler = 47; //捕获功能的时钟周期为1us
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
TIM_TimeBaseStructure.TIM_Period = 0xFFFF;//任意给定的一个值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //不分频
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; //不重复计数
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //初始化时基结构体
// 捕获通道IC1配置
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;//对应为HALLC
// 设置捕获的边沿
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising ; //上升沿捕获
// 设置捕获通道的信号来自于哪个输入通道
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//直连通道
// 1分频,即捕获信号的每个有效边沿都捕获
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;// 不滤波
TIM_ICInit(TIM3, &TIM_ICInitStructure); //初始化TIM3
TIM_ClearFlag(TIM3, TIM_FLAG_Update | TIM_FLAG_CC1); //清除更新中断和捕获中断标志位
TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1); //选择出发信号
TIM_ITConfig(TIM3, TIM_IT_Update | TIM_IT_CC1, ENABLE); //
TIM_Cmd(TIM3, ENABLE);
/**************************配置TIM3的中断优先级*******************************/
// 设置中断来源
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure); //初始化中断
*************************************************************************************************
然后我写了一个中断函数:
以下代码放在stm32f0xx_it.c 中
void TIM3_IRQHandler(void)
{
// 当要被捕获的信号的周期大于定时器的最长定时时,定时器就会溢出,产生更新中断
// 这个时候我们需要把这个最长的定时周期加到捕获信号的时间里面去
if ( TIM_GetITStatus ( TIM3, TIM_IT_Update) != RESET ) //确认是否是更新中断
{
TIM_ICUserValueStructure.Capture_Period ++; //如果是更新中断,此变量自动加
TIM_ClearITPendingBit ( TIM3, TIM_IT_Update ); //清除更新中断标志位
}
if ( TIM_GetITStatus (TIM3, TIM_IT_CC1 ) != RESET) //判断是否是上升沿捕获中断
{
// 第一次捕获
if ( TIM_ICUserValueStructure.Capture_StartFlag == 0 ) //确认是否是第一次捕获,这个变量为0的话是第一次
{
// 计数器清0
TIM_SetCounter ( TIM3, 0 );
// 自动重装载寄存器更新标志清0
TIM_ICUserValueStructure.Capture_Period = 0;
// 存捕获比较寄存器的值的变量的值清0
TIM_ICUserValueStructure.Capture_CcrValue = 0;
// 开始捕获标准置1,说明已经捕获到起始沿
TIM_ICUserValueStructure.Capture_StartFlag = 1;
}
else
{ // 第二次捕获
// 获取捕获比较寄存器的值
TIM_ICUserValueStructure.Capture_CcrValue = TIM_GetCapture1(TIM3);
// 开始捕获标志清0,以遍进行下一次转速计算
TIM_ICUserValueStructure.Capture_StartFlag = 0;
// 捕获完成标志置1
TIM_ICUserValueStructure.Capture_FinishFlag = 1;
}
TIM_ClearITPendingBit (TIM3,TIM_IT_CC1); //清除捕获中断标志位
}
}
******************************************************************************
然后,我在主函数里面加了一个if语句,通过捕获到的两次上升沿的时间推导出电机转速rpm,然后把原来LCD现实的用TIM2定时计算的转速替换成我用TIM3捕获计算得到的转速,软件刷进去后,电机正常转,但是转速一直显示为0.为什么不能捕获呢?