STM32编码器接口

news2024/11/22 16:52:53

一、概述

1、Encoder Interface 编码器接口概念

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

正交编码器:

其实只测其中一相就能测出速度,两相可以知道编码器正传还是反转。

编码器接口基本结构:

2、工作模式

TI1指的是通道1, TI2指的是通道2。

TI1和TI2均不反相(反相就是电平翻转):

TI或TI2反相:

虽然TI1的波形在图里没有翻转,但是你会发现,TI1上升沿,TI2为低电平,应该为向上计数,而图中是向下计数,所以TI1或TI2反相为反相计数器才会向下计数,可以对着表格测试一下。CNT向上计数表示编码器正转,CNT向下计数表示编码器反转。

二、用旋转编码器进行手动模拟 

完整代码如下:

  • 定时器定时1s

Timer.c:

#include "stm32f10x.h"                  // Device header

extern uint16_t Num;
void Timer_Init(void)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	NVIC_InitTypeDef NVIC_InitStructure;
	//1.配置时钟,用那个外设
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	
	//2.内部时钟配置
	TIM_InternalClockConfig(TIM2);
	
	//3.配置时基单元
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;     //滤波频率
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up; //计数方式
	TIM_TimeBaseInitStruct.TIM_Period=10000-1;                 //自动重装载寄存器ARR
	TIM_TimeBaseInitStruct.TIM_Prescaler=7200-1;               //预分频器
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;            //这个是高级定时器才用的,这里不用,给0

	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);
	

	TIM_ClearFlag(TIM2,TIM_FLAG_Update);                        //清除中断标志位
	//4.配置中断输出控制,打开中断
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
	
	//5.NVIC配置
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

	NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
	
	NVIC_Init(&NVIC_InitStructure);
	
	//6.启动定时器
	TIM_Cmd(TIM2,ENABLE);
}


Timer.h:

#ifndef _TIMER_H
#define _TIMER_H


void Timer_Init(void);



#endif
  • 编码器接口

Encoder.c:

这里没有考虑定时器溢出情况。

#include "stm32f10x.h"                  // Device header


void Encoder_Init(void)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_ICInitTypeDef  TIM_ICInitStruct;
	GPIO_InitTypeDef GPIO_InitStructure;
	//1.配置时钟,用那个外设
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
 	GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPU;   
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
 	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	//2.配置时基单元
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;     //滤波频率
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up; //计数方式,向上
	TIM_TimeBaseInitStruct.TIM_Period=65535-1;                 //自动重装载寄存器ARR,让CNT达到最大量程
	TIM_TimeBaseInitStruct.TIM_Prescaler=1-1;                  //预分频器
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;

	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);
	
	//3.初始化捕获单元
	TIM_ICStructInit(&TIM_ICInitStruct);                          //对结构体进行初始化,防止产生其他影响
	TIM_ICInitStruct.TIM_Channel=TIM_Channel_1;                   //选择输入通道
	TIM_ICInitStruct.TIM_ICFilter=0xF;                            //滤波
	//TIM_ICInitStruct.TIM_ICPolarity=TIM_ICPolarity_Rising;      //选择极性,上升沿
   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_ICInit(TIM3,&TIM_ICInitStruct);
	
	//4.配置编码器接口
   TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12, 
   TIM_ICPolarity_Falling,TIM_ICPolarity_Rising);
	
	//5.启动定时器
	TIM_Cmd(TIM3,ENABLE);
	
}

int16_t Encoder_Get(void)
{
	int16_t Temp;
	Temp=TIM_GetCounter(TIM3);
	TIM_SetCounter(TIM3,0);
    return Temp;   

}

Encoder.h:

#ifndef _ENCODER_H
#define _ENCODER_H

int16_t Encoder_Get(void);

void Encoder_Init(void);

#endif

main.c:

#include  "stm32f10x.h"                  // Device header
#include  "OLED.h"
#include  "delay.h"
#include  "Timer.h"
#include  "Encoder.h"

int16_t speed;

int main(void)
{
	
   OLED_Init();
	Timer_Init();
	Encoder_Init();
	OLED_ShowString(1,1,"CNT:");
	while(1) 
	{

	   OLED_ShowSignedNum(1,5,speed,5);
		Delay_ms(1000);
	}
	
}

void TIM2_IRQHandler(void)
{

	if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
	{
		
		speed=Encoder_Get();
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);  //更新中断就是产生一个中断标志位
	}


}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2198267.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何录制微课教程?K12教育相关课程录制录屏软件推荐

在当今数字化教育的时代,微课作为一种重要的教学资源,受到了越来越多教师和学生的关注。制作一节优质的微课,录制是关键的环节之一。下面我们将结合相关知识,详细介绍如何录制微课教程。 一、微课录制前的准备 1.教学设计文档编写…

Ultralytics:YOLO11使用教程

Ultralytics:YOLO11使用教程 前言相关介绍前提条件实验环境安装环境项目地址LinuxWindows YOLO11使用教程进行目标检测进行实例分割进行姿势估计进行旋转框检测进行图像分类 参考文献 前言 由于本人水平有限,难免出现错漏,敬请批评改正。更多…

题目:圆桌会议

解题思路: 结果的顺序就是原序列的逆序,例如12345就是54321为结果顺序。同时将一个顺序序列(非环)变成逆序需要的次数为。想要的得到最短的交换次数,只需要将环尽量对半分,然后分别对两部分进行顺序序列变逆…

DAY27||回溯算法基础 | 77.组合| 216.组合总和Ⅲ | 17.电话号码的字母组合

回溯算法基础知识 一种效率不高的暴力搜索法。本质是穷举。有些问题能穷举出来就不错了。 回溯算法解决的问题有: 组合问题:N个数里面按一定规则找出k个数的集合切割问题:一个字符串按一定规则有几种切割方式子集问题:一个N个数…

SeaTunnel如何创建Socket数据同步作业?

本文为Apache SeaTunnel Socket Connector的使用文档,旨在帮助用户快速理解和有效利用Socket Connector,助力用户的应用程序实现高效、稳定的网络通信。 Socket是应用层与TCP/IP协议族之间进行通信的中间软件抽象层,它是网络编程的基础&…

视频怎么做成扫码展示?视频二维码在线做的方法

视频想要快速的分享给其他人,选择生成二维码是一种很方便的形式,其他人只需要扫描二维码就可以在线查看视频,与其他分享方式相比更加的简单、方便。现在日常生活中有很多场景都会有视频二维码的应用,简化了获取视频的流程&#xf…

typora笔记导出word格式:

Pandoc:各系统下载github链接 https://github.com/jgm/pandoc/releases/latest windows安装包 链接:https://pan.baidu.com/s/17AZNIMImbzFtWJAcAfAB0g?pwd55l2 提取码:55l2 先解压压缩包 点击 设置Pandoc路径,然后选择pa…

处理器中的几种hazard

什么是hazard? Instructions interact with each other in pipeline ; Structural Hazard 原因: An instruction in the pipeline may need a resource being used by another instruction in the pipeline ;Structural hazard occurs when two instructions nee…

Chromium 中chrome.cookies扩展接口c++实现分析

chrome.cookies 使用 chrome.cookies API 查询和修改 Cookie,并在 Cookie 发生更改时收到通知。 更多参考官网定义:chrome.cookies | API | Chrome for Developers (google.cn) 本文以加载一个清理cookies功能扩展为例 https://github.com/Google…

RHCSA的学习(4)

一、vi编辑器 (1)为什么学vi? 所有的Unix Like 系统都会内建 vi 文本编辑器,其他的文本编辑器则不一定会存在; 很多个别软件的编辑接口都会主动呼叫 vi (例如未来会谈到的 crontab, visudo, edquota 等指令)&#x…

考试宝 逆向 分析

声明: 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 有相关问题请第一时间头像私信联系我…

【打印模板】子表类型数据支持超出行默认填充

09/25 主要更新模块概览 打印分组 默认填充 匹配地址 嵌入页面 01 表单管理 1.1 【打印模板】-子表类型(数据关联,数据查询,子表单)支持分组设置 说明: 在打印模板中,子表类型&#…

如何让 Raft 更稳健,使用 Pre-vote

本文参考文献 《Consensus: Bridging Theory and Practice》 1. Provote 解析原文 该算法解决的是某台机器被隔离后,再次加入时出现的扰动其他机器的问题。 1. 防止服务器重新加入集群时引发的中断 Raft领导者选举算法的一个缺点是,当一台已从集群中…

使用tcpkill断开异常tcp连接

在linux系统中,遇到TCP链接迟迟不能释放的情况,类似FIN_WAIT1、FIN_WAIT2的状态,释放时间不确定,而且对应的程序已经关闭,相应的端口也不再监听,无法通过杀进程来解决,这种情况下,为…

JS设计模式之策略模式:灵活、可扩展的编程利器

一. 前言 在 JavaScript 前端开发中,随着代码规模的增长和项目的复杂性,我们常常需要处理各种不同的条件和情况,而这可能导致代码变得冗长、难以维护。这时,我们就需要一种强大而灵活的编程模式来应对这些复杂的逻辑,…

人工智能的未来:从知识廉价时代到AI主导国家模式

随着人工智能(AI)技术的飞速发展,知识的获取和使用正变得更加普及与廉价。这不仅引发了技术领域的深刻变革,也将对全球社会经济模式产生广泛影响。特别是在《时代》杂志对风险投资巨头维诺德科斯拉(Vinod Khosla&#…

【AUTOSAR 基础软件】PduR模块详解(通信路由)

文章包含了AUTOSAR基础软件(BSW)中PduR模块相关的内容详解。本文从AUTOSAR规范解析,ISOLAR-AB配置以及模块相关代码分析三个维度来帮读者清晰的认识和了解PduR这一基础软件模块。文中涉及的ISOLAR-AB配置以及模块相关代码都是依托于ETAS提供的…

[Python学习日记-42] Python 中的生成器

[Python学习日记-42] Python 中的生成器 简介 表达式生成器 函数生成器 用生成器实现并发编程 简介 Python 中的生成器(Generator)是一种特殊的迭代器,它又被成为惰性运算,它可以在迭代过程中动态生成值,而不需要事…

HTML CSS 基础

HTML & CSS 基础 HTML一、HTML简介1、网页1.1 什么是网页1.2 什么是HTML1.3 网页的形成1.4总结 2、web标准2.1 为什么需要web标准2.2 Web 标准的构成 二、HTML 标签1、HTML 语法规范1.1基本语法概述1.2 标签关系 2、 HTML 基本结构标签2.1 第一个 HTML 网页2.2 基本结构标签…

PHP input 多文件上传功能实现-网页不为人知的数据库缺陷——未来之窗行业应用跨平台架构

一、多文件上传html部分 1.1错误示例 <input type"file" class"input fl" name"file" style"width:200px;display:inline;border:0px;" multiple />1.2 正确示例 <input type"file" class"input fl" …