06:TIM定时器功能------编码器接口功能

news2024/11/15 2:22:46

目录

1:简历

2: 正交编码器

 3:编码器接口基本结构

 4:编码器的工作模式

5:极性反转

A:编码器接口测速

1:连接图

 2:函数介绍

3:步骤

4:代码

B:编码器接口计次

1:连接图

2:代码


1:简历

        Encoder Interface 编码器接口

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

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

        两个输入引脚借用了输入捕获的通道1和通道2

2: 正交编码器

当编码器旋转起来的时候, 会输出下面的方波信号

 3:编码器接口基本结构

        编码器接口,都是上升沿和下降沿都有效的 , 上升沿和下降沿都需要计次 ,  所以在编码器接口模式下 ,  边沿检测极性选择就不再是边沿的极性选择了 ,  而是高低电平的极性选择.

        选择上升沿的参数------就是信号直通过来,高低电平极性不反转---5:极性反转

        选择上升沿的参数-------就是信号通过一个非门过来,高低电平极性反转----5:极性反转

        

 4:编码器的工作模式

         正转的状态都向上计数,   反转的状态都向下计数----TIM_EncoderMode_TI12

        上面的2个模式--只在一个计数

5:极性反转

均不反转

 TI1反转

 

A:编码器接口测速

1:连接图

 2:函数介绍

在stm32f10x tim.h文件中的函数------配置定时器编码器接口

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

  TIM_EncoderInterfaceConfig  TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);

参数 : 第二个参数---见上面的 4:编码器的工作模式

           第三个(IC1极性)和第四个(IC2极性)参数一样 : ----   3:编码器接口基本结构中的 边沿检测极性选择

        这里的上升沿并不代表上升沿有效 , 因为编码器接口始终都是上升沿、下降沿都有效的 , 这里的上升沿参数代表的是高低电平极性不反转-----5:极性反转

在stm32f10x tim.h文件中的函数------读取计数器CNT的值

uint16_t TIM_GetCounter(TIM_TypeDef* TIMx)

TIM_SetCounter :计数器读取到了65535清零

在stm32f10x tim.h文件中的函数------给CNT重新赋值

void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter)
 

TIM_SetCounter : 第二给参数: 读取CNT后,改它赋一个新的值;  我们这里选择把他清零

在stm32f10x tim.h文件中的函数------中断标志位和标志位清零

ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);

void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT)
 

TIM_GetITStatus: 获取中断标志位是否被置1了(检测外部中断的状态)

TIM_ClearITPendingBit清除中断挂起标志位

3:步骤

配置定时器编码器接口的步骤

1 : RCC开启时钟,(TIM外设---RCC_APB1PeriphClockCmd和GPIO外设----RCC_APB2PeriphClockCmd的时钟打开)

2 : 配置GPIO----GPIO_Init    (最后写第二步)

3 :  配置时基单元-----TIM_TimeBaseInit()

4 :  配置输入捕获(ic)----TIM_ICInit()--- IC需要配置2篇见代码

5 :   配置定时器编码器接口---TIM_EncoderInterfaceConfig()

6 : 启动定时器-----TIM_Cmd()

定时器开启步骤

1: 开启时钟 (RCC)

2: 选择时基单元的时钟 (TIM_InternalClockConfig--选择内部时钟)

3: 配置时基单元  (TIM_TimeBaseInit)

4 : 使能更新中断( TIM_ITConfig中断时钟控制)

5: NICV的配置   (见 02: STM32)

6: 启动定时器  (TIM_Cmd)

定时器开启步骤    详情见:03:TIM定时器

4:代码

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

void Timer_init(void){
//第一步是开启时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
//第二步,选择时基单元的时钟 (stm23上电默认使用的是内部时钟,这一行代码可以省略)
TIM_InternalClockConfig(TIM2);
//第三步,配置时基单元
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数
/*计数器溢出频率:CK_CNT_OV = CK_CNT / (ARR + 1)
					       = CK_PSC / (PSC + 1) / (ARR + 1
	定时频率=72M/(PSC+1)/(ARR+1)
	72MHZ=72000KHZ
	72000KHZ/7200=10KHZ=10000HZ
	T=1/F   T=1/10000hz=0.0001s=0.1ms
	然后以0.1ms的周期计10 000个数,所以就是1s
	
	*/
TIM_TimeBaseInitStructure.TIM_Period=10000-1;			//自动重装载寄存器ARR
TIM_TimeBaseInitStructure.TIM_Prescaler=7200-1;  //预分频器PSC
TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;//高级定时器特有的(重复寄存器)
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
	
//第四使能更新中断

TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	
	
TIM_ClearFlag(TIM2, TIM_FLAG_Update);//手动清除更新中断标志位
	
//第五步NICV的配置
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	
	
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);
}

void Encoder_Init(void)
{
	//1:配置RCC,把我们这里涉及的外设的时钟都打开(GPIO,AFIO)
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	//2:配置GPIO,选择我们的端口为输入模式  注意打开了2个中断
	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(GPIOB, &GPIO_InitStructure);
	//第四步,配置时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1;		//ARR
	TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1;		//PSC
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
	//配置输入捕获(IC)
	TIM_ICInitTypeDef TIM_ICInitStructure;
	TIM_ICStructInit(&TIM_ICInitStructure);
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
	TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;
	TIM_ICInitStructure.TIM_ICFilter = 0xF;
	TIM_ICInit(TIM3, &TIM_ICInitStructure);
	
	
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
	TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;
	TIM_ICInitStructure.TIM_ICFilter = 0xF;
	TIM_ICInit(TIM3, &TIM_ICInitStructure);
	//配置定时器编码器接口
	TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
	//启动定时器
	TIM_Cmd(TIM3, ENABLE);
}



int16_t Encoder_Get(void)
{
	int16_t Temp;
	//读取CNT的值
	Temp = TIM_GetCounter(TIM3);
	TIM_SetCounter(TIM3, 0);
	return Temp;
}



int16_t Speed;
int main(void)
{
	OLED_Init();
	Timer_init();
	Encoder_Init();
	OLED_ShowString(1, 1, "Speed:");
	
	while (1)
	{
		OLED_ShowSignedNum(1,7,Speed,5);
		//Delay_ms(1000);
	}
}

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


}

        只有TIM定时器的通道1和通道2接口可以作为 编码器接口

        通道3和通道4并不能做为编码器接口

IC需要配置2遍

B:编码器接口计次

        这个代码是通过定时器的编码器接口,来自动计次;  

        之前的代码是通过触发外部中断 , 然后在中断函数里手动进行计次-----见02:STM32--EXTI外部中断

1:连接图

2:代码

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


void Encoder_Init(void)
{
	//1:配置RCC,把我们这里涉及的外设的时钟都打开(GPIO,AFIO)
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	//2:配置GPIO,选择我们的端口为输入模式  
	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(GPIOB, &GPIO_InitStructure);
	//第四步,配置时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1;		//ARR
	TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1;		//PSC
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
	//配置输入捕获(IC)
	TIM_ICInitTypeDef TIM_ICInitStructure;
	TIM_ICStructInit(&TIM_ICInitStructure);
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
	TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;
	TIM_ICInitStructure.TIM_ICFilter = 0xF;
	TIM_ICInit(TIM3, &TIM_ICInitStructure);
	
	
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
	TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;
	TIM_ICInitStructure.TIM_ICFilter = 0xF;
	TIM_ICInit(TIM3, &TIM_ICInitStructure);
	//配置定时器编码器接口
	TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
	//启动定时器
	TIM_Cmd(TIM3, ENABLE);
}



int16_t Encoder_Get(void)
{
	
	return  TIM_GetCounter(TIM3);
}



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

TIM篇章完结

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

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

相关文章

无涯教程-分类算法 - 简介

分类可以定义为根据观测值或给定数据点预测类别的过程。分类的输出可以采用"黑色"或"白色"或"垃圾邮件"或"非垃圾邮件"的形式。 在数学上,分类是从输入变量(X)到输出变量(Y)近似映射函数(f)的任务,它属于有监督…

Bito----一款Idea智能化代码辅助插件,让你的开发效率飞起来!

ChatGPT,想必大家都比较熟悉了,一款高情商对话AI,可以用来进行文本对话、问答等多种人机交互场景,也可以用来辅助编写代码,大大提高程序员的开发效率。而今天的主角Bito,是一款比ChatGPT更快,无…

error LNK2019: 无法解析的外部符号 __imp__glClear@4,函数 _main 中引用了该符号

自己犯这个错误有些搞笑了,找着教程一步一步来还出错,复制GLFW示例代码 运行,报的第一个错误,这是一个链接错误,解决方案:

Unity Meta Quest MR 开发教程:(二)自定义透视 Passthrough【透视功能进阶】

文章目录 📕教程说明📕动态开启和关闭透视⭐方法一:OVRManager.instance.isInsightPassthroughEnabled⭐方法二:OVRPassthroughLayer 脚本中的 hidden 变量 📕透视风格 Passthrough Styling⭐Inspector 面板控制⭐代码…

JVM7:垃圾回收是什么?从运行时数据区看垃圾回收到底回收哪块区域?垃圾回收如何去回收?垃圾回收策略,引用计数算法及循环引用问题,可达性分析算法

垃圾回收是什么?从运行时数据区看垃圾回收到底回收哪块区域? 垃圾回收如何去回收? 垃圾回收策略 引用计数算法及循环引用问题 可达性分析算法 垃圾回收是什么?从运行时数据区看垃圾回收到底回收哪块区域?垃圾回收如何去…

使用Linux部署Kafka教程

目录 一、部署Zookeeper 1 拉取Zookeeper镜像 2 运行Zookeeper 二、部署Kafka 1 拉取Kafka镜像 2 运行Kafka 三、验证是否部署成功 1 进入到kafka容器中 2 创建topic 生产者 3 生产者发送消息 4 消费者消费消息 四、搭建kafka管理平台 五、SpringBoot整合Kafka 1…

求生之路2私人服务器开服搭建教程centos

求生之路2私人服务器开服搭建教程centos 大家好我是艾西,朋友想玩求生之路2(left4dead2)重回经典。Steam玩起来有时候没有那么得劲,于是问我有没有可能自己搭建一个玩玩。今天跟大家分享的就是求生之路2的自己用服务器搭建的一个心路历程。 &#xff0…

【LeetCode-面试经典150题-day15】

目录 104.二叉树的最大深度 100.相同的树 226.翻转二叉树 101.对称二叉树 105.从前序与中序遍历序列构造二叉树 106.从中序与后序遍历序列构造二叉树 117.填充每个节点的下一个右侧节点指针Ⅱ 104.二叉树的最大深度 题意: 给定一个二叉树 root ,返回其…

登录校验-JWT令牌-登陆后下发令牌

目录 思路 接口文档 令牌生成和下发 步骤 具体代码如下 工具类 控制类 测试 前后端联调 思路 令牌生成:登陆成功后,生成JWT令牌,并返回给前端令牌校验:在请求到达服务端后,对令牌进行统一拦截、校验 接口文档…

c语言练习题31:字符转换

scanf(“%[^\n]“, str)正则用法 1 ^表示"非",[^\n]表示读入换行字符就结束读入。这个是scanf的正则用法,我们都知道scanf不能接收空格符,一接受到空格就结束读入,所以不能像gets()等函数一样接受一行字符串&#xff0…

全基因组选择:LightGBM通过提升GWAS敏感性促进基因挖掘

GWAS是识别性状相关基因和理解性状背后的遗传结构的有效方法,随着下一代测序技术的快速发展,基因分型费用显著降低,而在大规模人群的情况下,表型已成为GWAS的瓶颈。由于测序技术的快速发展,获取基因的成本已经显著降低…

分享几个 Selenium 自动化常用操作

最近工作会用到selenium来自动化操作一些重复的工作,那么在用selenium写代码的过程中,又顺手整理了一些常用的操作,分享给大家。 常用元素定位方法 虽然有关selenium定位元素的方法有很多种,但是对于没有深入学习,尤…

Python“牵手”当当网商品列表数据,关键词搜索当当网API接口数据,当当网API接口申请指南

当当网平台API接口是为开发电商类应用程序而设计的一套完整的、跨浏览器、跨平台的接口规范,当当网API接口是指通过编程的方式,让开发者能够通过HTTP协议直接访问当当网平台的数据,包括商品信息、店铺信息、物流信息等,从而实现当…

AVR128 智能风扇设计-proteus-程序

一、系统方案 模拟的电风扇的工作状态有3种:自然风、常风及睡眠风。使用三个按键S1-S3设置自然风、常风及睡眠风。 再使用两个按键S4和S5,S4用于定时电风扇定时时间长短的设置,每按一次S4键,定时时间增加10秒,最长60秒…

MacOS软件安装包分享(附安装教程)

目录 一、软件简介 二、软件下载 一、软件简介 MacOS是一种由苹果公司开发的操作系统,专门用于苹果公司的计算机硬件。它被广泛用于创意和专业应用程序,如图像设计、音频和视频编辑等。以下是关于MacOS的详细介绍。 1、MacOS的历史和演变 MacOS最初于…

功能强大的网站检测工具Web-Check

什么是 Web-Check ? Web-Check是一款功能强大的一体化工具,用于查找有关网站/主机的信息。目前仪表版上可以显示:IP 信息、SSL 信息、DNS 记录、cookie、请求头、域信息、搜索爬虫规则、页面地图、服务器位置、开放端口、跟踪路由、DNS 安全扩…

UE4/5的Custom节点:在VScode使用HLSL(新手入门用)

目录 custom节点 VSCode环境安装 将VSCode里面的代码放入Custom中 custom节点 可以看到这是一个简单的Custom节点: 而里面是可以填写代码的: 但是在这里面去写代码会发现十分的繁琐【按下enter后,不会换行,也不会自动缩进】 …

关于UG/NX二次开发的历史和发展前景

UG/NX是一款广泛应用于计算机辅助设计与制造领域的软件,具有强大的二次开发能力。本文将介绍UG/NX二次开发的历史和发展前景。 一、UG/NX二次开发的历史 UG/NX最初由美国UGS公司(后被西门子收购)开发,是一款集成了CAD、CAM和CAE…

docker 重装提示 Exising installation is up to date 解决方法

Windows Docker 重装提示 Exising installation is up to date 解决方法 出现这个问题是因为卸载Docker没有卸载干净,导致无法重装 解决方法: 按下WindowR唤起命令输入界面,输入 regedit 打开注册表编辑在地址栏输入HKEY_LOCAL_MACHINE\SOFTW…

大数据之Maven

一、Maven的作用 作用一:下载对应的jar包 避免jar包重复下载配置,保证多个工程共用一份jar包。Maven有一个本地仓库,可以通过pom.xml文件来记录jar所在的位置。Maven会自动从远程仓库下载jar包,并且会下载所依赖的其他jar包&…