STM32入门笔记07_TIM编码器+案例: TIM编码器接口测量旋转方向和速度

TIM编码器接口

编码器接口简介

  • Encoder Interface 编码器接口
  • 编码器接口可接受增量(正交) 编码器的信号, 根据编码器旋转产生的正交信号脉冲, 自动控制CNT自增或自减, 从而指示编码器的位置、旋转方向和旋转速度
  • 每个高级定时器和通用定时器都拥有1个编码器接口
  • 两个输入引脚借用了捕获通道的通道1和通道2

使用编码器的意义

  • 实际中测电机速度会产生大量脉冲信号, 如果用外部中断, 则会大量占用软件资源, 因此可以用编码器接口测量, 将软件资源节省下来

正交编码器

在这里插入图片描述在这里插入图片描述

  • 正转和反转都是相对的, 具体情况具体配置极性

编码器接口基本结构

在这里插入图片描述

工作模式

在这里插入图片描述

  • 一般用第三种, 精度比较高

实例(均不反向)

在这里插入图片描述
在这里插入图片描述

  • 可以看到编码器的抗噪声能力比较强

实例(TI1反向)

在这里插入图片描述
在这里插入图片描述

  • 一个输入反向, 计数方向与原来相反
  • 通过配置反向, 方便地翻转极性, 达到想要的效果

案例: TIM编码器接口测量速度

说明:

  • 用旋转编码器模拟电机的转动
  • 仅详说明IC单元配置, 和编码器接口配置

硬件接线

在这里插入图片描述

配置IC单元

// 配置IC单元 对CH1和CH2进行配置(这是因为编码器的接口借用了CH1和CH2作为输入通道)
	// 只需配置通道和滤波器 其他的有编码器自动托管 
	//极性在设置编码器时会重复配置(因此这里不配置)
	TIM_ICInitTypeDef IC_InitStructure;
	TIM_ICStructInit(&IC_InitStructure);  
	IC_InitStructure.TIM_Channel = TIM_Channel_1; 
	IC_InitStructure.TIM_ICFilter = 0xF;
	TIM_ICInit(TIM3, &IC_InitStructure);
	IC_InitStructure.TIM_Channel = TIM_Channel_2;
	IC_InitStructure.TIM_ICFilter = 0xF;
	TIM_ICInit(TIM3, &IC_InitStructure);

配置编码器接口

// 配置编码器接口
	TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
TIM_EncoderInterfaceConfig参数配置及函数原型
/**
  * @brief  Configures the TIMx Encoder Interface.
  * @param  TIMx: where x can be  1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
  * @param  TIM_EncoderMode: specifies the TIMx Encoder Mode.
  *   This parameter can be one of the following values:
  *     @arg TIM_EncoderMode_TI1: Counter counts on TI1FP1 edge depending on TI2FP2 level.
  *     @arg TIM_EncoderMode_TI2: Counter counts on TI2FP2 edge depending on TI1FP1 level.
  *     @arg TIM_EncoderMode_TI12: Counter counts on both TI1FP1 and TI2FP2 edges depending
  *                                on the level of the other input.
  * @param  TIM_IC1Polarity: specifies the IC1 Polarity
  *   This parameter can be one of the following values:
  *     @arg TIM_ICPolarity_Falling: IC Falling edge.
  *     @arg TIM_ICPolarity_Rising: IC Rising edge.
  * @param  TIM_IC2Polarity: specifies the IC2 Polarity
  *   This parameter can be one of the following values:
  *     @arg TIM_ICPolarity_Falling: IC Falling edge.
  *     @arg TIM_ICPolarity_Rising: IC Rising edge.
  * @retval None
  */
void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,
                                uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity)

整体代码

Encoder.c
#include "stm32f10x.h" 
#include "OLED.h"
#include "Timer.h"
#include "Encoder.h"
// TIM 编码器接口测速
// 2023年3月25日14:29:22
int16_t Speed;

int main(void)
{
	OLED_Init();
	Timer_Init();
	EncoderInterface_Init();
	OLED_ShowString(1, 1, "Speed:");
	
	while(1)
	{
		OLED_ShowSignedNum(1, 7, Speed, 5);
	}
}

void TIM2_IRQHandler(void)
{
	// 判断标志位
	if (TIM_GetITStatus(TIM2, TIM_IT_Update)==SET)
	{
		Speed = Encoder_Get();
		// 清除标志位
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}
Timer.c
#include "stm32f10x.h"

// extern uint16_t Num;

void Timer_Init(void)
{
	// RCC开启时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	
	// 选择时钟源
	TIM_InternalClockConfig(TIM2);  // 内部时钟
	
	// 配置时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;  // 内部时钟分频
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;  // 计数模式
	TIM_TimeBaseInitStructure.TIM_Period=10000-1;  // 加载到自动重装寄存器的值
	TIM_TimeBaseInitStructure.TIM_Prescaler=7200-1;  // 预分频的值
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;  // 重复计数器的值 
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);  //
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);  // 清除标志
	// 使能更新中断
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	
	// 配置NVIC
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  // 设置NVIC优先级分组
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn;  // 中断通道
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;  
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;  // 抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;  // 响应优先级
	NVIC_Init(&NVIC_InitStructure);
	
	// 启动定时器
	TIM_Cmd(TIM2, ENABLE);
	return;
}

/*
void TIM2_IRQHandler(void)
{
	// 判断标志位
	if (TIM_GetITStatus(TIM2, TIM_IT_Update)==SET)
	{
		Num++;
		// 清除标志位
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}
*/
main.c
#include "stm32f10x.h" 
#include "OLED.h"
#include "Timer.h"
#include "Encoder.h"
// TIM 编码器接口测速
// 2023年3月25日14:29:22
int16_t Speed;

int main(void)
{
	OLED_Init();
	Timer_Init();
	EncoderInterface_Init();
	OLED_ShowString(1, 1, "Speed:");
	
	while(1)
	{
		OLED_ShowSignedNum(1, 7, Speed, 5);
	}
}

void TIM2_IRQHandler(void)
{
	// 判断标志位
	if (TIM_GetITStatus(TIM2, TIM_IT_Update)==SET)
	{
		Speed = Encoder_Get();
		// 清除标志位
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}

参考资料:

【STM32入门教程-2023持续更新中】 https://www.bilibili.com/video/BV1th411z7sn/?p=20&share_source=copy_web&vd_source=ee06a25b3dfb2900ab707b01fdff6667

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值