江协科技STM32学习- P20 实验-TIM编码器接口测速

news2024/9/28 11:15:12

      🚀write in front🚀  
🔎大家好,我是黄桃罐头,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​ 

💬本系列哔哩哔哩江科大STM32的视频为主以及自己的总结梳理📚 

🚀Projeet source code🚀   

💾工程代码放在了本人的Gitee仓库:iPickCan (iPickCan) - Gitee.com

引用:

STM32入门教程-2023版 细致讲解 中文字幕_哔哩哔哩_bilibili

Keil5 MDK版 下载与安装教程(STM32单片机编程软件)_mdk528-CSDN博客

STM32之Keil5 MDK的安装与下载_keil5下载程序到单片机stm32-CSDN博客

0. 江协科技/江科大-STM32入门教程-各章节详细笔记-查阅传送门-STM32标准库开发_江协科技stm32笔记-CSDN博客

【STM32】江科大STM32学习笔记汇总(已完结)_stm32江科大笔记-CSDN博客

江科大STM32学习笔记(上)_stm32博客-CSDN博客

STM32学习笔记一(基于标准库学习)_电平输出推免-CSDN博客

STM32 MCU学习资源-CSDN博客

stm32学习笔记-作者: Vera工程师养成记

术语:

英文缩写描述
GPIO:General Purpose Input Onuput通用输入输出
AFIO:Alternate Function Input Output复用输入输出
AO:Analog Output模拟输出
DO:Digital Output数字输出
内部时钟源 CK_INT:Clock Internal内部时钟源
外部时钟源 ETR:External clock 时钟源 External clock 
外部时钟源 ETR:External clock mode 1外部时钟源 Extern Input pin 时钟模式1
外部时钟源 ETR:External clock mode 2外部时钟源 Extern Trigger 时钟模式2
外部时钟源 ITRx:Internal trigger inputs外部时钟源,ITRx (Internal trigger inputs)内部触发输入
外部时钟源 TIx:external input pin 外部时钟源 TIx (external input pin)外部输入引脚
CCR:Capture/Comapre Register捕获/比较寄存器
OC:Output Compare输出比较
IC:Input Capture输入捕获
TI1FP1:TI1 Filter Polarity 1Extern Input 1 Filter Polarity 1,外部输入1滤波极性1
TI1FP2:TI1 Filter Polarity 2Extern Input 1 Filter Polarity 2,外部输入1滤波极性2

正文:

0. 概述

从 2024/06/12 定下计划开始学习下江协科技STM32课程,接下来将会按照哔站上江协科技STM32的教学视频来学习入门STM32 开发,本文是视频教程 P2 STM32简介一讲的笔记。


定时器共四个部分,分为八个小节笔记。本小节为第一部分第一节。

🌳在第一部分,是定时器的基本定时的功能:定时中断功能、内外时钟源选择

🌳在第二部分,是定时器的输出比较功能,最常见的用途是产生PWM波形,用于驱动电机等设备

🌳在第三部分,是定时器的输入捕获功能和主从触发模式,来实现测量方波频率

🌳在第四部分,是定时器的编码器接口,能够更加方便读取正交编码器的输出波形,编码电机测速


1.🚢编码器

编码器接口测速

接线图:

A相可以接PA6或者PA7,这个可以随便交换,但是必须用PA6和PA7这两个引脚,因为我们计划用定时器3来接编码器,PA6和PA7对应的是定时器3的通道一和通道二。

2.🚢编码器接口的初始化步骤

编码器接口的初始化步骤看这个结构图来配置

  • 🌾第一步,RCC开启时钟,开启GPIO和定时器的时钟。
  • 🌾第二步,配置GPIO,这里需要把PA6和PA7配置成输入模式。
  • 🌾第三步,配置时基单元,这里预分频器,一般选择不分频。自动重装一般给最大65535,只需要个CNT执行计数就行了。
  • 🌾第四步,配置输入捕获单元,不过这里输入捕获单元只有滤波器和极性这两个参数有用,后面的参数没有用到,与编码器无关。
  • 🌾第五步,配置编码器接口模式,这个直接调用个库函数就可以了。
  • 🌾第六步,启动定时器,调用TIM_Cmd启动定时器。
  • 🌾电路初始化完成之后,CNT就会随着编码器旋转而自增自减。如果想要测量编码器的位置,直接读出CNT的值就行了。如果想测量编码器的速度和方向,就需要每隔一段固定的闸门时间取出一次CNT,然后再把CNT清零,这样就是测频法测量速度了。

 

3.🚢编码器使用到的stm32f10x_tim.h中新函数

编码器使用到的stm32f10x_tim.h中新函数

void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,
                                uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity);
定时器编码器接口配置

 上拉和下拉如何选择

我们一般可以看一下接在这个引脚的外部模块输出的默认电平。如果外部模块空闲默认输出高电平,我们就选择上拉输入,默认输入高电平。如果外部模块默认输出低电平,我们配置下拉输入,默认输入低电平,和外部模块保持默认状态一致,防止默认电平打架,这是上拉和下拉的选择原则。

不过一般来说,默认高电平是一个习惯的状态,所以一般上拉输入用的比较多。

然后如果不确定外部模块输出的默认状态或者外部信号输出功率非常小,这时就尽量选择浮空输入,浮空输入没有上拉电阻和下拉电阻去影响外部信号。但是缺点就是当引脚悬空时没有默认的电平了,输入就会受噪声干扰,来回不断的跳变。

这就是三种输入模式的选择原则。

4.实验1-编码器接口读取编码器正传反转

源码

Encoder.c

#include "stm32f10x.h"                  // Device header
#include "Encoder.h"

void Encoder_Init(void)
{
	//RCC开启外设时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//GPIOB外设RCC时钟使能
	
	//GPIO配置
	GPIO_InitTypeDef GPIOInitStructure;
	GPIOInitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIOInitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
	GPIOInitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIOInitStructure);
	
	
	//使用定时器TIM3 CH1
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	
	//Setp 3.
	//配置时基单元
	TIM_TimeBaseInitTypeDef TimeBaseInitStruct;
	TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;		//时钟信号滤波使用,滤波的采样频率,采样点数
	TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;	//计数器向上计数
	TimeBaseInitStruct.TIM_Period = 65536 - 1;					//ARR, Auto-Reload Register 自动重装载寄存器的值,记得需要减一
	TimeBaseInitStruct.TIM_Prescaler = 1 - 1;					//PSC, 预分频器的值,记得需要减一
	TimeBaseInitStruct.TIM_RepetitionCounter = 0;				//重复计数器的值	
	TIM_TimeBaseInit(TIM3, &TimeBaseInitStruct);
	
	//输入信号滤波
	TIM_ICInitTypeDef TIM_ICInitStruct;
	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);
	
	//输入编码器配置
	TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
	
	TIM_Cmd(TIM3, ENABLE);
}



int16_t Encoder_GetCount(void)
{
	int16_t tmp;
	
	tmp = TIM_GetCounter(TIM3);
	TIM_SetCounter(TIM3, 0);
	
	return tmp;
}

Timer.c

 

#include "stm32f10x.h"                  // Device header
#include "Timer.h"

void Timer_Init(void)
{
	
	//Setp 1.
	//RCC APB1的外设时钟控制,因为TIM2在STM32的APB1外设总线上
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	
	//Setp 2.
	//选择时基单元的时钟,使用内部RCC时钟 CLK_INT (Clock_Internal)
	TIM_InternalClockConfig(TIM2);
	
	//Setp 3.
	//配置时基单元
	TIM_TimeBaseInitTypeDef TimeBaseInitStruct;
	TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;		//时钟信号滤波使用,滤波的采样频率,采样点数
	TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;	//计数器向上计数
	TimeBaseInitStruct.TIM_Period = 10000/4 - 1;					//Auto-Reload Register 自动重装载寄存器的值,记得需要减一
	TimeBaseInitStruct.TIM_Prescaler = 7200 - 1;				//预分频器的值,记得需要减一
	TimeBaseInitStruct.TIM_RepetitionCounter = 0;				//重复计数器的值	
	TIM_TimeBaseInit(TIM2, &TimeBaseInitStruct);
	
	
	//在TIM_TimeBaseInit()之后,在启用中断之前,手动清除一下定时器更新中断标志位,
	//就能避免初始化之后就立即进入中断的问题了。
	TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	
	//Setp 4.
	//使能定时中断
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	
	//Setp 5.
	//NVIC配置
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	//NVIC优先级分组
	
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStruct);					//NVIC配置定时器中断优先级
	
	
	//Setp 6.
	//定时器启动
	TIM_Cmd(TIM2, ENABLE);
}


uint16_t Speed;
int16_t Encoder_GetCount(void);

//定时器TIM2,中断处理函数
void TIM2_IRQHandler(void)
{
	//检查中断标志位
	if(SET == TIM_GetITStatus(TIM2, TIM_IT_Update))
	{
		Speed = Encoder_GetCount();
		//清除中断标志位
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}

int16_t Encoder_GetSpeed(void){
	return Speed;
}

 main.c

#include "stm32f10x.h"                  // Device header
#include "oled.h"
#include "Countersensor.h"
#include "Encoder.h"
#include "Timer.h"

extern uint16_t Num;

int main(int argc, char *argv[])
{	
	OLED_Init();
	OLED_ShowString(1, 1, "Cnt:");
	
	Timer_Init();
	Encoder_Init();


	while(1)
	{

		OLED_ShowSignedNum(1,5,Encoder_GetSpeed(),5);
	}
	
	return 1;
}

 3.1 实验结果

编码器正传,读取出来的TIM计数器的值为正,因为是在"IT1,IT2均计数" 所以每正传一个格子计数器的值增加4.

编码器正传,读取出来的TIM计数器的值为正,因为是在"IT1,IT2均计数" 所以每正传一个格子计数器的值减4.

编码器反转到计数器值为0,下一次自编码器的值为‘0-4’溢出后为(65536-4),如果想要显示为负数可以用补码的知识直接将uin16_t类型的值强制转换为 int16_t。

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

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

相关文章

游戏厅计时器ps5计算时间的软件 佳易王电玩计时计费管理系统操作教程

一、前言 游戏厅计时器ps5计算时间的软件 佳易王电玩计时计费管理系统操作教程 软件为绿色免安装版,解压即可使用。 二、软件程序教程 计时的时候,点击 开始计时按钮 开台后可设置定时语音提醒的时间 时间设置好后,点击 开启提醒 即可 三、…

无人机飞手入伍当兵技术优势分析

随着现代战争形态的不断演变,无人机技术在军事领域的应用日益广泛,成为提升军队作战能力的重要手段。对于无人机飞手而言,其专业技能和实战经验在入伍当兵后能够转化为显著的技术优势,为国防事业贡献重要力量。以下是从专业技能优…

“不关心⚠️Warning”的代价:http自动升级https导致免费的存储服务扣费

背景 7 月 12 日的时候我手机突然收到一条短信:显示我在 LeanCloud 平台的账户欠费了。虽然只是欠费 0.01 元,但还是有些疑惑,怎么免费的存储服务突然扣费了? 然而这只是个开始。起初我并没有很在意这扣费的 0.01 元(…

阿里发布Qwen2.5:编程与数学的AI新革命!

阿里发布Qwen2.5:编程与数学的AI新革命! 阿里发布了Qwen2.5系列模型🚀,带来编程和数学领域的超强升级🦸‍♂️。多种规格可选,开源模型推动创新🔓,让AI助手更智能!快来体…

一阶低通滤波器Simulink仿真测试

1、低通滤波器(SMART PLC双线性变化和后向差分对比测试 低通滤波器(SMART PLC双线性变换和后向差分对比测试)_后向差分 和 双线性-CSDN博客文章浏览阅读367次。该博客详细探讨了低通滤波器的设计,对比了SMART PLC中的双线性变换和后向差分法。内容包括Tustin变换公式、后向差…

第一批学习大模型的程序员,已经碾压同事了,薪资差距都甩出一条街了...

前言 随着人工智能技术的突飞猛进,AI大模型已成为引领未来的核心技术。从ChatGPT的横空出世到GPT-4o的震撼发布,AI技术正以前所未有的速度改变着我们的生活和工作方式。 在这场AI革命中,企业对AIGC人才的需求正以指数级增长。据《AIGC就业趋…

基于Hive和Hadoop的病例分析系统

本项目是一个基于大数据技术的医疗病历分析系统,旨在为用户提供全面的病历信息和深入的医疗数据分析。系统采用 Hadoop 平台进行大规模数据存储和处理,利用 MapReduce 进行数据分析和处理,通过 Sqoop 实现数据的导入导出,以 Spark…

OpenAi_Moderation审核更新

更新原文档 最新openai-python版本已不可直接用 openai.Moderation.create()

芝法酱学习笔记(0.5)——使用jenkins做自动打包

前言 上节讲了SpringBoot上的打包。但这些过程都是手动的,在实际的开发测试时,自动化的打包部署,可以大大提升团队开发的效率 一、去官网下载 1.1 官网安装命令 对于如何安装的问题,我向来推荐官网 wget -O /usr/share/keyri…

论文阅读:LM-Cocktail: Resilient Tuning of Language Models via Model Merging

论文链接 代码链接 Abstract 预训练的语言模型不断进行微调,以更好地支持下游应用。然而,此操作可能会导致目标领域之外的通用任务的性能显著下降。为了克服这个问题,我们提出了LM Cocktail,它使微调后的模型在总体上保持弹性。…

解决Mac 默认设置 wps不能双面打印的问题

目录 问题描述: 问题解决: 问题描述: 使用mac电脑的时候,发现wps找不到双面打印的按钮,导致使用wps打开的所有文件都不能自动双面打印 问题解决: mac的wps也是有双面打印的选项,只是默认被关…

双指针算法【算法 18】

双指针算法 在算法设计与实现中,双指针算法是一种非常高效且常用的技术,尤其适用于处理数组和字符串相关的问题。通过维护两个指针(通常称为“快指针”和“慢指针”),双指针算法能够在对数组或字符串进行单次遍历的同时…

VSCode rust文件中的api点击无法跳转问题

如果配置了vscode的setting.json windows端的话 "settings": { "typescript.tsc.autoDetect": "off","rust-analyzer.linkedProjects": [".\\gui-btn\\Cargo.toml",".\\temp\\Cargo.toml", ],其他端类似 能不…

电脑怎么进行网页限制操作?

1、修改Hosts文件: 打开文件资源管理器,导航至C:\Windows\System32\drivers\etc\目录(注意,修改前最好备份原文件)。 找到并打开hosts文件,以管理员身份运行文本编辑器进行编辑。 在文件末尾添加一行&am…

基于Springboot投稿和稿件处理系统设计与实现

博主介绍:专注于Java vue .net php phython 小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设,从业十五余年开发设计教学工作 ☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不然下次找不到哟 我的博客空间发布了1000毕设题目 方便大家学习使用 感兴趣的…

Java | Leetcode Java题解之第441题排列硬币

题目: 题解: class Solution {public int arrangeCoins(int n) {return (int) ((Math.sqrt((long) 8 * n 1) - 1) / 2);} }

【STM32开发环境搭建】-2-安装STM32CubeMX

目录 1 下载STM32CubeMX 2 使用STM32CubeMX 2.1 设置Embedded software Package存放路径 2.2 下载并安装STM32的Embedded software Package 结尾 1 下载STM32CubeMX 注册一个ST的账号,单击STM32CubeMX - STM32Cube初始化代码生成器 - 意法半导体STMicroelectr…

《 C++ 修炼全景指南:十三 》为什么你的代码不够快?全面掌控 unordered_set 和 unordered_map 的哈希性能飙升魔法

摘要 本文深入探讨了 C 标准库中的两大无序容器——unordered_set 和 unordered_map,从底层实现、核心操作、性能优化、实际应用等多个方面进行了全面分析。首先,文章介绍了这两种容器的基本概念,说明了它们基于哈希表实现的特点&#xff0c…

AMD ROCm™ 安装指南

AMD ROCm™ installation — ROCm Blogs 注意: 本文之前是 AMD 实验笔记博客系列的一部分。 AMD ROCm™ 是第一个面向 HPC/超大规模级 GPU 计算的开源软件开发平台。AMD ROCm™ 将 UNIX 的选择权、极简主义和模块化软件开发哲学引入 GPU 计算领域。有关更多信息,请参…

华为OD机试 - 小明的幸运数(Python/JS/C/C++ 2024 E卷 100分)

华为OD机试 2024E卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试真题(Python/JS/C/C)》。 刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,…