STM32 编码器模式实战指南

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:STM32 编码器模式是微控制器STM32用于获取旋转编码器信号的特殊工作方式,广泛应用于电机控制领域。本文深入探讨了 STM32 如何配置定时器实现编码器模式,并通过 encoder.c 和 encoder.h 文件的编程实践阐述了相关知识。通过本指南,读者将掌握 STM32 编码器模式的配置步骤,包括定时器初始化、编码器输入通道配置和中断服务处理,并了解 encoder.c 和 encoder.h 文件中函数和结构体的作用。本指南旨在帮助开发者快速上手 STM32 编码器模式的应用,为电机控制项目提供基础。

1. STM32 编码器编程指南

第一章:STM32 编码器模式简介

STM32 编码器是一种用于测量角位移和速度的专用硬件模块。它可以连接到外部编码器设备,例如增量式编码器或绝对式编码器。STM32 编码器模式提供以下功能:

  • 测量旋转角度和速度
  • 跟踪编码器的方向和位置
  • 提供中断服务程序,用于快速响应编码器事件

2. 定时器配置为编码器模式

2.1 TIMx_ENCODER_MODE 配置

TIMx_ENCODER_MODE 配置是定时器编码器模式的基本配置,它将定时器配置为编码器模式,并使用内部时钟源。

代码块:

TIM_Encoder_InitTypeDef sConfig;
sConfig.EncoderMode = TIM_ENCODERMODE_TI1;
sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
sConfig.IC1Filter = 0x0;
sConfig.IC2Polarity = TIM_ICPOLARITY_RISING;
sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
sConfig.IC2Filter = 0x0;

逻辑分析:

  • sConfig.EncoderMode = TIM_ENCODERMODE_TI1; :将定时器配置为编码器模式,使用 TI1 输入通道作为编码器输入。
  • sConfig.IC1Polarity = TIM_ICPOLARITY_RISING; :设置 TI1 输入通道的极性为上升沿触发。
  • sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI; :选择 TI1 输入通道直接连接到定时器输入捕获寄存器。
  • sConfig.IC1Prescaler = TIM_ICPSC_DIV1; :设置 TI1 输入通道的分频器为 1,即不分频。
  • sConfig.IC1Filter = 0x0; :设置 TI1 输入通道的滤波器为 0,即不滤波。
  • sConfig.IC2Polarity = TIM_ICPOLARITY_RISING; :设置 TI2 输入通道的极性为上升沿触发。
  • sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI; :选择 TI2 输入通道直接连接到定时器输入捕获寄存器。
  • sConfig.IC2Prescaler = TIM_ICPSC_DIV1; :设置 TI2 输入通道的分频器为 1,即不分频。
  • sConfig.IC2Filter = 0x0; :设置 TI2 输入通道的滤波器为 0,即不滤波。

2.2 TIMx_ENCODER_MODE_TI12 配置

TIMx_ENCODER_MODE_TI12 配置是定时器编码器模式的扩展配置,它将定时器配置为编码器模式,并使用外部时钟源。

代码块:

TIM_Encoder_InitTypeDef sConfig;
sConfig.EncoderMode = TIM_ENCODERMODE_TI12;
sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
sConfig.IC1Filter = 0x0;
sConfig.IC2Polarity = TIM_ICPOLARITY_RISING;
sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
sConfig.IC2Filter = 0x0;

逻辑分析:

  • sConfig.EncoderMode = TIM_ENCODERMODE_TI12; :将定时器配置为编码器模式,使用 TI1 和 TI2 输入通道作为编码器输入。
  • sConfig.IC1Polarity = TIM_ICPOLARITY_RISING; :设置 TI1 输入通道的极性为上升沿触发。
  • sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI; :选择 TI1 输入通道直接连接到定时器输入捕获寄存器。
  • sConfig.IC1Prescaler = TIM_ICPSC_DIV1; :设置 TI1 输入通道的分频器为 1,即不分频。
  • sConfig.IC1Filter = 0x0; :设置 TI1 输入通道的滤波器为 0,即不滤波。
  • sConfig.IC2Polarity = TIM_ICPOLARITY_RISING; :设置 TI2 输入通道的极性为上升沿触发。
  • sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI; :选择 TI2 输入通道直接连接到定时器输入捕获寄存器。
  • sConfig.IC2Prescaler = TIM_ICPSC_DIV1; :设置 TI2 输入通道的分频器为 1,即不分频。
  • sConfig.IC2Filter = 0x0; :设置 TI2 输入通道的滤波器为 0,即不滤波。

2.3 TIMx_ENCODER_MODE_TI12_INDEX 配置

TIMx_ENCODER_MODE_TI12_INDEX 配置是定时器编码器模式的进一步扩展配置,它将定时器配置为编码器模式,并使用外部时钟源和索引通道。

代码块:

TIM_Encoder_InitTypeDef sConfig;
sConfig.EncoderMode = TIM_ENCODERMODE_TI12_INDEX;
sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
sConfig.IC1Filter = 0x0;
sConfig.IC2Polarity = TIM_ICPOLARITY_RISING;
sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
sConfig.IC2Filter = 0x0;
sConfig.IndexInput = TIM_INDEXINPUT_TI1;
sConfig.IndexPolarity = TIM_ICPOLARITY_RISING;
sConfig.IndexPrescaler = TIM_ICPSC_DIV1;
sConfig.IndexFilter = 0x0;

逻辑分析:

  • sConfig.EncoderMode = TIM_ENCODERMODE_TI12_INDEX; :将定时器配置为编码器模式,使用 TI1 和 TI2 输入通道作为编码器输入,并使用索引通道。
  • sConfig.IC1Polarity = TIM_ICPOLARITY_RISING; :设置 TI1 输入通道的极性为上升沿触发。
  • sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI; :选择 TI1 输入通道直接连接到定时器输入捕获寄存器。
  • sConfig.IC1Prescaler = TIM_ICPSC_DIV1; :设置 TI1 输入通道的分频器为 1,即不分频。
  • sConfig.IC1Filter = 0x0; :设置 TI1 输入通道的滤波器为 0,即不滤波。
  • sConfig.IC2Polarity = TIM_ICPOLARITY_RISING; :设置 TI2 输入通道的极性为上升沿触发。
  • sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI; :选择 TI2 输入通道直接连接到定时器输入捕获寄存器。
  • sConfig.IC2Prescaler = TIM_ICPSC_DIV1; :设置 TI2 输入通道的分频器为 1,即不分频。
  • sConfig.IC2Filter = 0x0; :设置 TI2 输入通道的滤波器为 0,即不滤波。
  • sConfig.IndexInput = TIM_INDEXINPUT_TI1; :选择 TI1 输入通道作为索引通道。
  • sConfig.IndexPolarity = TIM_ICPOLARITY_RISING; :设置索引通道的极性为上升沿触发。
  • sConfig.IndexPrescaler = TIM_ICPSC_DIV1; :设置索引通道的分频器为 1,即不分频。
  • sConfig.IndexFilter = 0x0; :设置索引通道的滤波器为 0,即不滤波。

3. 编码器输入通道配置

3.1 编码器输入通道选择

STM32 编码器模式支持使用两个通道(TI1 和 TI2)作为编码器输入。这些通道可以连接到 GPIO 引脚,以接收来自外部编码器的信号。

配置输入通道时,需要指定以下参数:

  • 通道源: 选择用于编码器输入的 GPIO 引脚。
  • 极性: 指定编码器信号的极性(上升沿或下降沿)。
  • 滤波: 配置输入信号的滤波器,以减少噪声和抖动。

3.2 编码器输入通道滤波

输入通道滤波器用于减少编码器信号中的噪声和抖动。滤波器通过对多个采样进行平均来实现,从而平滑信号。

STM32 编码器模式支持两种类型的滤波器:

  • 采样滤波器: 对多个采样进行平均,以平滑信号。
  • 时钟分频滤波器: 将时钟信号分频,以降低采样率,从而减少噪声。

3.3 编码器输入通道极性

编码器输入通道极性用于指定编码器信号的极性。极性可以设置为上升沿或下降沿触发。

设置极性时,需要考虑编码器的类型和连接方式。例如,对于增量式编码器,极性通常设置为上升沿或下降沿,具体取决于编码器的连接方式。

代码示例

以下代码示例展示了如何配置编码器输入通道:

/* TIMx_ENCODER_MODE 配置 */
TIMx->CCMR1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0;

/* TIMx_ENCODER_MODE_TI12 配置 */
TIMx->CCMR1 |= TIM_CCMR1_CC1S_1 | TIM_CCMR1_CC2S_1;

/* TIMx_ENCODER_MODE_TI12_INDEX 配置 */
TIMx->CCMR1 |= TIM_CCMR1_CC1S_1 | TIM_CCMR1_CC2S_1 | TIM_CCMR1_CC2S_0;

参数说明

  • TIMx :编码器定时器外设基地址。
  • CCMR1 :编码器模式寄存器 1。
  • CC1S :捕获/比较 1 输入通道选择。
  • CC2S :捕获/比较 2 输入通道选择。

逻辑分析

上述代码示例配置了编码器输入通道。对于 TIMx_ENCODER_MODE 配置,通道 1 和通道 2 都被选择为编码器输入。对于 TIMx_ENCODER_MODE_TI12 配置,通道 1 和通道 2 都被选择为编码器输入,并且通道 2 的极性被反转。对于 TIMx_ENCODER_MODE_TI12_INDEX 配置,通道 1 和通道 2 都被选择为编码器输入,通道 2 的极性被反转,并且通道 2 的输入被配置为索引信号。

4. 中断服务程序处理

4.1 编码器中断服务程序结构

编码器中断服务程序通常包含以下部分:

  • 中断入口点: 这是中断服务程序的入口点,它保存寄存器并禁用中断。
  • 数据处理: 此部分读取编码器寄存器并更新编码器计数。
  • 状态机: 此部分根据编码器的当前状态更新状态机。
  • 中断出口点: 这是中断服务程序的出口点,它恢复寄存器并启用中断。

4.2 编码器中断服务程序中的数据处理

在数据处理部分,中断服务程序执行以下操作:

  • 读取编码器寄存器: 中断服务程序读取编码器寄存器以获取编码器计数和状态信息。
  • 更新编码器计数: 中断服务程序将读取的编码器计数添加到编码器计数变量中。
  • 更新编码器状态: 中断服务程序更新编码器状态变量以反映编码器的当前状态。
void TIMx_IRQHandler(void) {
  // 保存寄存器
  __disable_irq();

  // 读取编码器寄存器
  uint32_t encoder_count = TIMx->CNT;
  uint32_t encoder_status = TIMx->SR;

  // 更新编码器计数
  encoder_count += encoder_count_offset;

  // 更新编码器状态
  encoder_status_flags = encoder_status;

  // 清除中断标志
  TIMx->SR &= ~TIM_SR_UIF;

  // 恢复寄存器
  __enable_irq();
}

4.3 编码器中断服务程序中的状态机

在状态机部分,中断服务程序执行以下操作:

  • 检查编码器状态: 中断服务程序检查编码器的当前状态以确定编码器的方向和速度。
  • 更新状态机: 中断服务程序根据编码器的当前状态更新状态机。
switch (encoder_status_flags) {
  case TIM_SR_CC1IF:
    // 编码器正向旋转
    encoder_state = ENCODER_STATE_FORWARD;
    break;
  case TIM_SR_CC2IF:
    // 编码器反向旋转
    encoder_state = ENCODER_STATE_REVERSE;
    break;
  case TIM_SR_CC1IF | TIM_SR_CC2IF:
    // 编码器停止旋转
    encoder_state = ENCODER_STATE_STOPPED;
    break;
  default:
    // 未知状态
    encoder_state = ENCODER_STATE_UNKNOWN;
    break;
}

5. encoder.c 文件代码解析

5.1 encoder_init() 函数

void encoder_init(TIM_TypeDef *TIMx, uint32_t encoder_mode)
{
    // 配置定时器为编码器模式
    TIMx->CR1 |= TIM_CR1_CEN;
    TIMx->CCMR1 |= encoder_mode;

    // 配置编码器输入通道
    TIMx->CCER |= TIM_CCER_CC1E | TIM_CCER_CC2E;
    TIMx->CCMR1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0;

    // 配置编码器中断
    TIMx->DIER |= TIM_DIER_UIE;
    NVIC_EnableIRQ(TIMx_IRQn);
}

参数说明:

  • TIMx : 定时器外设基地址
  • encoder_mode : 编码器模式,可以是 TIMx_ENCODER_MODE TIMx_ENCODER_MODE_TI12 TIMx_ENCODER_MODE_TI12_INDEX

代码解释:

  1. 配置定时器为编码器模式:
  2. 设置 TIMx->CR1 寄存器的 CEN 位,使能定时器。
  3. 设置 TIMx->CCMR1 寄存器的 CC1S CC2S 位,选择编码器模式。

  4. 配置编码器输入通道:

  5. 设置 TIMx->CCER 寄存器的 CC1E CC2E 位,使能编码器输入通道。
  6. 设置 TIMx->CCMR1 寄存器的 CC1S CC2S 位,选择输入通道。

  7. 配置编码器中断:

  8. 设置 TIMx->DIER 寄存器的 UIE 位,使能更新中断。
  9. 使能定时器中断。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:STM32 编码器模式是微控制器STM32用于获取旋转编码器信号的特殊工作方式,广泛应用于电机控制领域。本文深入探讨了 STM32 如何配置定时器实现编码器模式,并通过 encoder.c 和 encoder.h 文件的编程实践阐述了相关知识。通过本指南,读者将掌握 STM32 编码器模式的配置步骤,包括定时器初始化、编码器输入通道配置和中断服务处理,并了解 encoder.c 和 encoder.h 文件中函数和结构体的作用。本指南旨在帮助开发者快速上手 STM32 编码器模式的应用,为电机控制项目提供基础。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值