当前位置: 首页 > article >正文

TIM编码器接口函数及应用

TIM编码器接口函数及应用

文章目录

  • TIM编码器接口函数及应用
    • 1.编码器接口简介
    • 2.正交编码器
      • 2.2工作模式
      • 2.3实例1(均不反相)
    • 3.编码器接口框图
      • 3.1以通用计时器为例
      • 3.2编码器接口基本结构
        • 3.2.1实现步骤
    • 4.用到的库函数
    • 5.编码器接口测速(实操)
      • 5.1接线图
      • 5.2代码编写
        • 5.2.1主函数main.c
        • 5.2.2函数定义Encoder.c
        • 5.2.3函数声明Encoder.h

1.编码器接口简介

手册14.3.12编码器接口模式有相关介绍

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

2.正交编码器

正交编码器一般可以测量位置,或者带有方向的速度值

一般有A相和B相两个,分别为超前和滞后90°的关系(图中正转为A相超前B相90°,反转是B相滞后A相90°)

可以根据边沿状态和另一相状态来确定正转还是反转

正交编码器

2.2工作模式

工作模式

总结:正转的方向都是向上计数,反转的方向都是向下计数

2.3实例1(均不反相)

不反相

3.编码器接口框图

3.1以通用计时器为例

通用计时器

3.2编码器接口基本结构

编码器接口基本结构

3.2.1实现步骤
  1. RCC开启时钟,开启GPIO和定时器的时钟
  2. 配置GPIO,这里把PA6和PA7配置成输入模式
  3. 配置时基单元
  4. 配置输入捕获单元,这里的输入捕获单元只有滤波器和极性两个参数有用
  5. 配置编码器接口模式
  6. 最后,调用TIM_Cmd,启动定时器

4.用到的库函数

void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,
                                uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity);

void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity);定时器编码器接口配置,第一个参数选择定时器,第二个参数选择编码器模式,第三个参数选择通道1编码器的极性,第四个参数选择通道2编码器的极性

5.编码器接口测速(实操)

5.1接线图

编码器接线图

5.2代码编写

5.2.1主函数main.c
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "KEY.h"
#include "OLED.h"
//#include "OLED_Font.h"
#include "Timer.h"
#include "Encoder.h"

int16_t Speed;


int main(void){
	
	OLED_Init();
	Timer_Init();
	Encoder_Init();
	OLED_ShowString(1,1,"Speed:");
	while(1){
		//CNT = Encoder_GetCounter();
		OLED_ShowSignedNum(1,7,Speed,5);
		//获取CNT的值,每秒获取一次
		//Delay_ms(1000);
	}
}

void TIM2_IRQHandler(void){
	if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET){
		Speed = Encoder_GetCounter();
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
		
	}
}
配置中断函数
//void TIM2_IRQHandler(void){
//	if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET){
//		num++;
//		
//		//清除标志位
//		TIM_ClearITPendingBit(TIM2,	TIM_IT_Update);
//	}
//}

5.2.2函数定义Encoder.c
#include "stm32f10x.h"                  // Device header

void Encoder_Init(void){
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

	//开启GPIO通道
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitTypeDef GPIO_Structure;
	GPIO_Structure.GPIO_Mode = GPIO_Mode_IPU;//如果外部模块默认输出高电平,就配置上拉输入,默认输入高电平
											 //如果外部模块默认输出低电平,就配置下拉输入,默认输入低电平
	//不确定外部状态或者输出功率特别小,就选择浮空输入(没有上拉输入和下拉输入去影响外部信号,缺点是悬空的时候就没有默认电平了)
	GPIO_Structure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_Structure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_Structure);
	
	
	
	//选择时钟源去掉,因为编码器接口就是一个带方向控制的外部时钟
	//TIM_InternalClockConfig(TIM2);
	  
	//配置时基单元
	TIM_TimeBaseInitTypeDef TIM_Structure;
	TIM_Structure.TIM_ClockDivision = TIM_CKD_DIV1;
	//TIM_Structure.TIM_CounterMode = TIM_CounterMode_Up;编码器接口托管
	TIM_Structure.TIM_Period = 65535 - 1;			//ARR
	TIM_Structure.TIM_Prescaler = 1 - 1;		//PSC
	TIM_Structure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM3,&TIM_Structure);
	
	//初始化输入捕获单元
	TIM_ICInitTypeDef TIM_ICInitStruct;
	TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;
	TIM_ICInitStruct.TIM_ICFilter = 0xF;
	TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;//上升沿并不代表上升沿有效,因为编码器接口都是上升沿和下降沿都有效的,这里的上升沿表示高低电平极性不反转
	TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;
	TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI; 
	TIM_ICInit(TIM3,&TIM_ICInitStruct);
	TIM_ICInitStruct.TIM_Channel = TIM_Channel_2;
	TIM_ICInitStruct.TIM_ICFilter = 0xF;
	TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;//上升沿并不代表上升沿有效,因为编码器接口都是上升沿和下降沿都有效的,这里的上升沿表示高低电平极性不反转
	TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;
	TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI; 
	TIM_ICInit(TIM3,&TIM_ICInitStruct);
	
	TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);//第二个是哪个相计数,这里的配置会覆盖前面的,所以前面的可以去掉

	TIM_Cmd(TIM3,ENABLE);
	
}

int16_t Encoder_GetCounter(){
	int16_t temp;
	temp = TIM_GetCounter(TIM3);
	//读取后清零
	TIM_SetCounter(TIM3,0);
	return temp;
}



5.2.3函数声明Encoder.h
#ifndef __ENCODER_H
#define __ENCODER_H

void Encoder_Init(void);
int16_t Encoder_GetCounter(void);

#endif


http://www.kler.cn/a/517934.html

相关文章:

  • 从规则到神经网络:机器翻译技术的演进与未来展望
  • 基于ESP32的桌面小屏幕实战[6]:环境搭建和软件基础
  • 代码随想录算法训练营day31(补0124)
  • 科技快讯 | 理想官宣:正式收费!WeChat 港币钱包拓宽商户网络;百川智能发布深度思考模型Baichuan-M1-preview
  • 【Salesforce】审批流程,代理登录 tips
  • 【第六天】零基础入门刷题Python-算法篇-数据结构与算法的介绍-一种常见的贪心算法(持续更新)
  • 环境变量配置与问题解决
  • Gin 学习笔记
  • JAVA实战开源项目:在线旅游网站(Vue+SpringBoot) 附源码
  • 【Linux跬步积累】——thread封装
  • 使用Pytest Fixtures来提升TestCase的可读性、高效性
  • Java 实现Excel转HTML、或HTML转Excel
  • 「 机器人 」系统辨识实验浅谈
  • 如何有效进行软件集成测试?常见的集成测试工具分享
  • 工程数学速记手册(下)
  • 汽车免拆诊断案例 | 2007 款日产天籁车起步加速时偶尔抖动
  • 前端react后端java实现提交antd form表单成功即导出压缩包
  • LMI Gocator GO_SDK VS2019引用配置
  • 【2025美赛D题】为更美好的城市绘制路线图建模|建模过程+完整代码论文全解全析
  • ThinkPhp伪静态设置后,访问静态资源也提示找不到Controller
  • 【新人系列】Python 入门(二十九):常用标准库 - 下
  • 【Git】如何在 Git 提交后补充 Change-Id
  • PDF密码有哪些类型?
  • 使用Python和Flask搭建导航网站需要注意的问题有哪些?
  • Python数据分析-Python的数据结构、函数和文件(三)
  • 六、深入了解DI