本帖最后由 特朗姆斯 于 2016-8-24 15:12 编辑
直流无刷电机控制方式比较简单,直接用PWM控制速度即可。
目前碰到的问题是在相同的PWM占空比下,两个相同的电机真实呈现的速度不一样,因此我想到了利用速度检测功能来对其进行校准。但是速度检测功能令我很头疼,目前采用的是把速度检测引脚连接到I/O引脚,用外部中断的方式采集一秒钟内的脉冲数来进行判断。按原子哥的说法是这种方式会使ARM频繁进入中断,不是理想的实现方式。
想到过用定时器捕获输入的方式,看完datasheet中关于定时器捕获输入的内容,似乎也是要通过中断来实现脉冲捕获,那和我使用的外部中断采集没有区别。
另外还有看到定时器外部时钟模式2,可以通过TIMx_CHx引脚触发开始计数,通过TIMx_ETR引脚来对脉冲进行计数。使用这种模式虽然可以不使用中断,但是要占用两个定时器,这两个定时器还必须是有TIMx_ETR引脚的高级定时器,加上额外的I/O资源开销似乎也是得不偿失。
目前研究下来差不多是上述情况,希望有大神给予指引。
ps:我用的直流无刷电机有配套的控制器,ARM采集的脉冲数由控制器发出。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
我以前试过,这个方法至少可以测到5Hz~25MHz的频率,精度0.03%以下
[mw_shl_code=c,true]//TIM7->100ms
//TIM2_CH2->PB3
void TIM_Cnt_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_DeInit(TIM2);
TIM_DeInit(TIM7);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2|RCC_APB1Periph_TIM7,ENABLE); //TIM2时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); //使能PORTA时钟
//IO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //GPIOA0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; //速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //下拉
GPIO_Init(GPIOB,&GPIO_InitStructure); //初始化PA0
GPIO_PinAFConfig(GPIOB,GPIO_PinSource3,GPIO_AF_TIM2); //PA0复用位定时器5
//TIM2配置
TIM_TimeBaseStructure.TIM_Prescaler=0; //定时器分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseStructure.TIM_Period=0xFFFFFFFF; //自动重装载值
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);
TIM_TIxExternalClockConfig(TIM2,TIM_TIxExternalCLK1Source_TI2,TIM_ICPolarity_Rising,0);//外部时钟源
//TIM7 100ms
TIM_TimeBaseStructure.TIM_Prescaler=18000-1; //定时器分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseStructure.TIM_Period=1000-1; //自动重装载值
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM7,&TIM_TimeBaseStructure);
//中断
NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority =0; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器、
TIM_ITConfig(TIM7,TIM_IT_Update,ENABLE);//允许更新中断 ,允许CC1IE捕获中断
TIM_Cmd(TIM7,ENABLE ); //使能定时器5
TIM_Cmd(TIM2,ENABLE ); //使能定时器5
}
volatile u32 TIM_ExtCntFreq;
u32 TIM7_LastCnt;
void TIM7_IRQHandler(void)
{
char str[32];
TIM_ExtCntFreq=(TIM2->CNT-TIM7_LastCnt)*10;
sprintf(str,"%3.3f",TIM_ExtCntFreq/1000.0);//必须加这一句,莫明其妙
TIM7_LastCnt=TIM2->CNT;
TIM_ClearITPendingBit(TIM7,TIM_IT_Update);
}[/mw_shl_code]
脉冲怎么会是由电机提供的,电机可以给自身提供脉冲?你用了编码器的吧?
定时器捕获输入可以用dma 我用过,
计数模式只是用频率低的
一周热门 更多>