学习记录--编码器测速

一,编码器原理详解:

参考:[野火]《电机应用开发实战指南》第13章

1,基本参数

(本次实验所用的增量式编码器查参数得为13ppr)

2,增量式编码器基本原理:

3,编码器的倍频

 4,M法测速:

5,STM32的编码器接口实现原理(输入捕获定时器)

2倍频实现为例,其他的原理类同(一个通道的上升和下降沿都计数)

 二,CUBEMX配置

1,定时器配置

需要注意的是:有些编码器输出是不带上拉电阻的,此时就需要将A,B通道的IO口成设置成上拉,本实验用的编码器查参数得知是带上拉输出(默认上拉到供电VCC引脚),故可用单片机直接采集。

关于几个成员的理解:

2,打开一个串口传数据

3,设置两个输出IO驱动电机

三,keil中代码

1,开启一系列

  /* USER CODE BEGIN 2 */
	//开启PWM输出
	HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_3);
	
  //清零计数器 
  __HAL_TIM_SET_COUNTER(&htim3, 0);
  //清零中断标志位 
  __HAL_TIM_CLEAR_IT(&htim3,TIM_IT_UPDATE);
  // 使能定时器的更新事件中断 
  __HAL_TIM_ENABLE_IT(&htim3,TIM_IT_UPDATE);
  //设置更新事件请求源为:计数器溢出(也就是只有计数溢出时触发更新中断)
  __HAL_TIM_URS_ENABLE(&htim3);	
	
  //使能编码器接口(TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected)
  HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL);
	
  /* USER CODE END 2 */

2, 写更新中断回调函数(计在T0内有多少次溢出,用来计算T0内的总计数次数)

定义变量(关于__IO, 参考博客:(12条消息) 关于"__IO uint32_t" 中的__IO 表达的意思_znmdwahaha的专栏-优快云博客

// 定时器溢出次数 
__IO int16_t Encoder_Overflow_Count = 0;

 // 转向
__IO int8_t Motor_Direction = 0;
// 当前时刻总计数值 
__IO int32_t Capture_Count = 0;
// 上一时刻总计数值
__IO int32_t Last_Count = 0;
// 转轴转速 
__IO float Shaft_Speed = 0.0f;

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  /* 判断当前计数器计数方向 */
  if(__HAL_TIM_IS_TIM_COUNTING_DOWN(&htim3))
    /* 下溢 */
    Encoder_Overflow_Count--;
  else
    /* 上溢 */
    Encoder_Overflow_Count++;
}

由上述STM32的编码器接口实现原理:每次捕获到输入沿(即编码器每产生一个脉冲)计数器就计数一次,因此可以通过T0内计数次数和编码器线数等算出转速(这里应该是忽略了在一个装载值内转向改变带来的影响)

3,计算转速,直接在void HAL_SYSTICK_Callback()里写了(1ms调用一次)

void HAL_SYSTICK_Callback(void)
{
  static uint16_t i = 0;

  i++;
  if(i == 1000)	//1s计算一次
  {
    //电机旋转方向 = 当前计数器计数方向 
    Motor_Direction = __HAL_TIM_IS_TIM_COUNTING_DOWN(&htim3);
    
    // 当前计数值 = 当前装载内计数器值 + 计数溢出次数 * 定时器装载值  
    Capture_Count =__HAL_TIM_GET_COUNTER(&htim3) + (Encoder_Overflow_Count * 65535);
    
    // 转轴转速 = 单位时间内的计数值(当前计数值-上一次计数值) / 编码器总分辨率(ppr*倍频)*时间系数(进行单位转化的)
    Shaft_Speed = (float)(Capture_Count - Last_Count) / (13*4) * 1;

    printf("电机方向:%d\r\n", Motor_Direction);
    printf("电机转轴处转速:%.2f 转/秒 \r\n", Shaft_Speed);
		//注意输出的和转轴处转速不一样,还要除一个电机减速比
    printf("电机输出轴转速:%.2f 转/秒 \r\n", Shaft_Speed/30);
    
		// 记录当前总计数值,供下一时刻计算使用 
    Last_Count = Capture_Count;
    i = 0;
  }
}

由于手头的硬件无法进行实验,先挖个坑之后再调看是不是通的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值