[STM32]Day6-Part4编码器接口测速

编码器接口简介

Encoder Interface编码器接口,编码器接口可接收增量(正交)编码器的信号,根据编码器旋转产生的正交信号脉冲,自动控制CNT自增或自减,从而指示编码器的位置、旋转方向和旋转速度。

每个高级定时器和通用定时器都拥有一个编码器接口,两个输入引脚借用了输入捕获通道的通道1和通道2。

正交编码器一般可以测量位置,或者带有方向的速度值。正反转方向可以根据AB相信号再某一时刻的状态来判断,具体如图中右表。

编码器测速原理

编码器AB相分别接TIMx_CH1和TIMx_CH2,经过滤波和边沿检测产生TI1FP1和TI2FP2信号,输入编码器接口。编码器接口的输出信号,控制CNT的计数时钟和计数方向,此时内部时钟源、时基单元初始化设置的计数方向不起作用。

编码器接口基本结构

编码器模式下上升沿和下降沿都是有效的,因此极性选择不再是选择上升沿/下降沿,而是是否让TI1/TI2信号经过非门进行反转,也叫反相。

工作模式

在TI1和TI2上计数的精度较高。

下面是TI1和TI2均不反相时的编码器模式实例。

毛刺部分前后计数器的值不变,体现了使用正交信号抗噪能力强的特点。

下面是TI1经过反相时编码器模式实例

编码器接口测速

整体流程:配置GPIO -> 配置时基单元 -> 配置输入捕获单元 -> 配置编码器接口 -> TIM_cmd使能计数器

关于输入模式:上拉输入/下拉输入/浮空输入的选择,上拉输入和下拉输入一般由外设的默认电平确定,旋转编码器默认输出高电平,因此PA6和PA7选择上拉输入。

c 复制代码
// RotaryEncoder.c
#include "stm32f10x.h"                  // Device header

int16_t RotaryEncoder_Count;

void RotaryEncoder_Init(void)
{
	// 配置GPIO
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;		// 上拉输入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	// 配置时基单元
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseStructInit(&TIM_TimeBaseInitStructure);
	TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1;
	TIM_TimeBaseInitStructure.TIM_Period = 1 - 1;
//	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;		计数方向由编码器决定,无需设置
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
	
	// 配置输入捕获单元
	TIM_ICInitTypeDef TIM_ICInitStructure;
	TIM_ICStructInit(&TIM_ICInitStructure);
	// 通道1
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
	TIM_ICInitStructure.TIM_ICFilter = 0xF;
	TIM_ICInitStructure.TIM_ICPolarity  = TIM_ICPolarity_Rising;		// 不代表上升沿,而是说明不反相
	TIM_ICInit(TIM3, &TIM_ICInitStructure);
	// 通道2
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
	TIM_ICInitStructure.TIM_ICFilter = 0xF;
	TIM_ICInitStructure.TIM_ICPolarity  = TIM_ICPolarity_Rising;		// 不代表上升沿,而是说明不反相
	TIM_ICInit(TIM3, &TIM_ICInitStructure);
	
	// 配置编码器接口,
	// TIM_ICPolarity_Rising, TIM_ICPolarity_Rising两个参数与上面配置通道的极性选择配置的是同一个寄存器
	TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
	
	// 使能计数器
	TIM_Cmd(TIM3, ENABLE);
}

int16_t RotaryEncoder_Get(void)
{
//	return TIM_GetCounter(TIM3);		// 显示位置
	int16_t Temp;
	Temp = TIM_GetCounter(TIM3);
	TIM_SetCounter(TIM3, 0);		// 清零CNT
	return Temp;
}

// RotaryEncoder.h
#ifndef __RotaryEncoder_H
#define __ROtaryEncoder_H

void RotaryEncoder_Init(void);
int16_t RotaryEncoder_Get(void);

#endif

// main.c
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED_Software.h"
#include "RotaryEncoder.h"
#include "Timer.h"

int16_t Speed;

int main(void)
{
	
	OLED_Init();
	Timer_Init();
	RotaryEncoder_Init();
	
	OLED_ShowString(1, 1, "Speed:");

	while(1)
	{
		
		OLED_ShowSignedNum(1, 7, Speed, 5);
//		Delay_ms(1000);		// 容易阻塞主程序
	}
}

// 重写中断函数
void TIM2_IRQHandler(void)
{
	// 检查标志位
	if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET) {
		Speed = RotaryEncoder_Get();
		// 清除标志位
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}
相关推荐
芯岭技术8 小时前
Wi-Fi+BLE双模无线芯片 BK7238,低功耗、高性能,集成MCU和Flash
单片机·嵌入式硬件
云空8 小时前
《ARM Cortex‑M 系列完整梳理》
stm32·单片机·嵌入式硬件·mcu
单片机杂货铺8 小时前
基于单片机的智能花盆浇水系统控制器设
stm32·单片机·嵌入式硬件·毕业设计·51单片机·硬件工程
Dr.kangder9 小时前
嵌入式处理器仿真技术——Hypervisor 原理与实践
服务器·嵌入式硬件·架构·嵌入式
Hello_Damon_Nikola11 小时前
TM1637芯片从入门到精通
单片机·嵌入式硬件
智购科技自动售卖机厂家14 小时前
从STM32到RK3588——自动售货机嵌入式主控方案的架构演进~YH
stm32·嵌入式硬件·物联网·架构·lua·零售·symfony
振南的单片机世界15 小时前
2MHz/50MHz玄机:GPIO速度档选错,信号直接“烂尾”
arm开发·stm32·单片机·嵌入式硬件
Run_Teenage16 小时前
嵌入式:理解STM32文档和社区生态,工具链的选择与安装
stm32·单片机·嵌入式硬件
ACP广源盛1392462567316 小时前
DeepSeek‑V4‑Flash 公测@ACP#昇腾 950 国产算力组合落地,国产 PCIe 交换芯片 IX9104 有哪些硬件机会
大数据·数据库·人工智能·分布式·单片机·嵌入式硬件·microsoft
铅笔小新z16 小时前
【stm32】RCC 与时钟树
stm32·单片机·嵌入式硬件