锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

stm32霍尔编码器电机测速原理

时间:2023-06-13 15:37:01 4k7单圈电位器ksp102

本次选用的编码器电机为13线霍尔编码器电机,电机减速比为30:1,转动一圈输出13*30=390个脉冲。轮胎直径为75mm,轮胎周长为pi*d=3*75=225mm.定时器采用四倍频计数,一圈输出390*4=1560个脉冲。这里就不多说具体的编码器知识了。

根据速度测量原理:假设编码器输出的脉冲数为N,电机转动一圈输出1569个脉冲,转动一圈轮将向前移动225mm。当输出脉冲数为N时,前进距离应为225*(N/1560)mm,除以时间和速度。

具体代码如下:

encoder.c文件

#include "encoder.h"  void Encoder_TIM2_Init(void) {  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //开时钟  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);    GPIO_InitTypeDef GPIO_InitStruct;       //配置IO口  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;  GPIO_Init(GPIOA, &GPIO_InitStruct);    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;    ///定时器初始化  TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;  TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;  TIM_TimeBaseInitStruct.TIM_Period = 65535;  TIM_TimeBaseInitStruct.TIM_Prescaler = 0;  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);    ///  TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);    TIM_ICInitTypeDef TIM_ICInitStruct;       //输入捕获单元配置  TIM_ICStructInit(&TIM_ICInitStruct);  TIM_ICInitStruct.TIM_ICFilter = 10;  TIM_ICInit(TIM2, &TIM_ICInitStruct);    TIM_ClearFlag(TIM2, TIM_FLAG_Update);    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);    TIM_SetCounter(TIM2, 0);    TIM_Cmd(TIM2, ENABLE); }  void Encoder_TIM4_Init(void) {  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);    GPIO_InitTypeDef GPIO_InitStruct;  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;  GPIO_Init(GPIOB, &GPIO_InitStruct);    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;  TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;  TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;  TIM_TimeBaseInitStruct.TIM_Period = 65535;  TIM_TimeBaseInitStruct.TIM_Prescaler = 0;  TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStruct);    TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);      TIM_ICInitTypeDef TIM_ICInitStruct;   TIM_ICStructInit(&TIM_ICInitStruct);  TIM_ICInitStruct.TIM_ICFilter = 10;  TIM_ICInit(TIM4, &TIM_ICInitStruct);    TIM_ClearFlag(TIM4, TIM_FLAG_Update);    TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);    TIM_SetCounter(TIM4, 0);    TIM_Cmd(TIM4, ENABLE); }  int Read_Spead(int TIMx)   ///读取编码器输出脉冲数 {  int value_1;  switch(TIMx)  {   case 2:value_1 = (short)TIM_GetCounter(TIM2);TIM_SetCounter(TIM2, 0);break;   case 4:value_1 = (short)TIM_GetCounter(TIM4);TIM_SetCounter(TIM4, 0);break;   default:value_1 = 0;  }  return value_1; }  void TIM2_IRQHander(void) {  if(TIM_GetITStatus(TIM2, TIM_IT_Update) == 1)  {   TIM_ClearITPendingBit(TIM2, TIM_IT_Update);  } }  void TIM4_IRQHander(void) {  if(TIM_GetITStatus(TIM4, TIM_IT_Update) == 1)  {   TIM_ClearITPendingBit(TIM4, TIM_IT_Update);  } } 

我用的很简单delay收集定时器捕获的编码器脉冲数,但我建议使用定时器中断来处理编码器收集。该函数只收集右轮脉冲进行计算

主函数循环体内函数:

while(1)  {   delay_s(1);   {    uint16_t right = Read_Spead(2)//采集右轮脉冲数    displacement = 0.225 * (right / 1560)    speed = displacement;///因为我设置为延迟一秒,所以不需要除时间    OLED_Float(0, 0, speed, 4);//通过OLED显示速度    set_PWM(999)PWM    TIM_SetCounter(TIM2, 0)///下一秒计数前再次清除计数   }  }

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章