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

【STM32编码器】【STM32】

提示:一般情况下我们会设计一个硬件电路模块来自动完成简单重复而高频的计算

文章目录

  • 一、为什么通常情况下不使用外部中断来对编码器的脉冲进行计数?
  • 二、编码器速度测量程序设计思路
  • 三、正交编码器
  • 四、初始化流程
  • 五、STM32正交编码器输入捕获模式配置示例
  • 总结


一、为什么通常情况下不使用外部中断来对编码器的脉冲进行计数?

电机高速旋转过程中会在短时间产生成千上万个脉冲信号,如果频繁调用中断进行累加运算会占用一定的软件资源;

一般情况下我们会设计一个硬件电路模块来自动完成上述简单重复而高频的计算;

二、编码器速度测量程序设计思路

每隔一段实际取一次值就可以得到编码器旋转的速度了;

编码器接口(Encoder Interface),编码器的信号,根据编码器旋转产生的正交信号脉冲,自动控制CNT自增或者自减,从而指示编码器的位置、旋转方向和旋转速度;
每个高级定时器和通用定时器都拥有一个编码器接口;

两个输入引脚借用了输入捕获的通道1和通道2;
注意CH3和CH4引脚不能接编码器

每个高级定时器和通用定时器都拥有一个编码器接口;

三、正交编码器

正交编码器的接口:
A相 B相 编码器电源 GND Z相(编码器0位置的输出,每转到一个固定的位置的时候输出一个脉冲,一般用于位置测量,校准0位置用的。)

正交信号精度更高:
A、B相都可以计次,相当于频率提高了一倍;
正交信号可以抗噪声:
正交信号的两个信号必须是交替跳变的,可以设计成一个抗噪声电路;

65535的补码为-1,如果想读取到负数,可以将编码器的uint_16类型强行转换为int_16类型;
读取编码器计数次数库函数:

uint16_t TIM_GetCounter(TIM_TypeDef* TIMx)

四、初始化流程

①RCC开启时钟,开启GPIO和定时器的时钟;
②配置GPIO,把PA6和PA7 配置成输入模式;
③配置时基单元,预分频器一般选择不分频(PSC = 0),自动重装一般给最大值65535(0~2^16-1);
④配置输入捕获单元,这里输入捕获单元只有滤波器和极性有用,后面的参数没有用到,与编码器无关;
⑤配置编码器接口模式
⑥调用TIM_Cmd启动定时器;

编码器初始化需要调用到的库函数

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

获取定时器CNT的计数值

uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);

五、STM32正交编码器输入捕获模式配置示例

代码如下(示例):

/*** @brief  正交编码器输入捕获初始化,采用PA6、PA7捕获编码器A相与B相数据;注意PA6与PA7不可以随意更换,PA6->TIM3的CH1 PA7->TIM3的CH2;* @param  无* @retval 无*/
void Encoder_Init_IC(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIOA的外设时钟GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;//设置上拉输入模式GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;//选中GPIO口GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能定时器TIM3的外设时钟//TIM_InternalClockConfig(TIM3);//选择内部时钟驱动TIM3的时钟单元,定时器上电默认使用内部时钟,这句话可以不写//TIM_ETRConfig(TIM3,TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_Inverted,0x0F);//选择外部时钟驱动TIM3的时钟单元TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;//滤波器的采样时钟分频系数,跟时基单元关联不大,决定了滤波器的输入时钟频率(越低滤波输出越稳定,同时延迟会增大)TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;//选择向上计数TIM_TimeBaseInitStruct.TIM_Period = 65535;//ARR自动重装器的值,取值0~65535,10KHZ/10000=1HZTIM_TimeBaseInitStruct.TIM_Prescaler = 0;//预分频器的值,取值0~65535,72MHZ/7200=10KHZTIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;//重复计数器的值,高级定时器特有的配置,这里用不上TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);TIM_ICInitTypeDef TIM_ICInitStruct;TIM_ICStructInit(&TIM_ICInitStruct);//给结构体赋初始值,主要是为了防止结构体不完整导致出错TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;//指定配置1~4哪一个通道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;//选择信号从哪一路引脚输入,可以选择直连通道或者交叉通道(DirectTI表示直连通道,InDirectTI表示交叉通道)TIM_ICInit(TIM3,&TIM_ICInitStruct);TIM_ICInitStruct.TIM_Channel = TIM_Channel_2;//指定配置1~4哪一个通道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;//选择信号从哪一路引脚输入,可以选择直连通道或者交叉通道(DirectTI表示直连通道,InDirectTI表示交叉通道)TIM_ICInit(TIM3,&TIM_ICInitStruct);TIM_Cmd(TIM3,ENABLE);//启动定时器TIMx  这里的上升沿代表高低电平极性不反转TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12 ,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);//写入到TIMCmd后防止被覆盖
}/*
在输入捕获的模式下如果想获取编码器的位置信息可以直接读出CNT的值;
如果想获取编码器的速度和方向,需要每隔一段固定的闸门时间,去除一次CNT再把CNT清零;
上述测量速度即测频法;
*/

总结

以上就是今天要讲的内容,本文简单介绍了STM32中编码器的使用方式。

http://www.lryc.cn/news/468261.html

相关文章:

  • Python轴承故障诊断 (13)基于故障信号特征提取的超强机器学习识别模型
  • VScode分文件编写C++报错 | 如何进行VScode分文件编写C++ | 不懂也能轻松解决版
  • 洞察前沿趋势!2024深圳国际金融科技大赛——西丽湖金融科技大学生挑战赛技术公开课指南
  • Unity3D学习FPS游戏(4)重力模拟和角色跳跃
  • C#基础知识-枚举
  • 系统架构设计师教程 第2章 2.1-2计算机系统及硬件 笔记
  • 通过使用Visual Studio将你的程序一键发布到Docker
  • vue2和vue3动态引入路由,权限控制
  • Spring Boot:植物健康的智能守护者
  • 红黑树 学习笔记
  • linux更改系统时间
  • B站C#刘铁猛笔记
  • 如何使用信号发生器产生正弦波并用数字示波器进行测量
  • XJ04、消费金融|授信基本概念及其流程设计
  • 儿童预防接种预约微信小程序springboot+论文源码调试讲解
  • nginx 修改配置
  • 孤岛架构在安全性方面
  • COSCon'24 志愿者招募令:共创开源新生活!
  • vscode使用make编译c的问题
  • 管家婆财贸ERP BB019.操作员制单日期控制
  • 从 Vue 2 到 Vue 3:全面升级指南
  • Apache paimon表操作实战-5
  • 阿里云用STS上传oss的完整程序执行流程图 和前端需要哪些参数uniapp
  • 决策树方法根据指定条件筛选方案
  • 多特征变量序列预测(四) Transformer-BiLSTM风速预测模型
  • 【开源免费】基于SpringBoot+Vue.JS蜗牛兼职平台 (JAVA毕业设计)
  • Ajax笔记
  • 软考:缓存分片和一致性哈希
  • 3109 体验积分值
  • 初识jsp