STM32端口模拟编码器输入
文章目录
- 前言
- 一、正交编码器是什么?
- 二、使用步骤
- 2.1开启时钟
- 2.2配置编码器引脚 TIM3 CH1(PA6) CH2 (PA7)上拉输入
- 2.3.初始化编码器时基
- 2.4 初始化编码器输入
- 2.5 配置编码器接口
- 2.6 开启定时器
- 2.7获取编码器数据
- 三、参考程序
- 四、测试结果
- 4.1测试方法
- 4.2串口输出结果
- 总结
前言
提示:这里可以添加本文要记录的大概内容:
项目需要:
提示:以下是本篇文章正文内容,下面案例可供参考
一、正交编码器是什么?
在这里插入图片描述
二、使用步骤
2.1开启时钟
/*开启时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //开启TIM3的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟
2.2配置编码器引脚 TIM3 CH1(PA6) CH2 (PA7)上拉输入
/*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(GPIOA, &GPIO_InitStructure);
2.3.初始化编码器时基
代码如下(示例):
/*时基单元初始化*/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); //将结构体变量交给TIM_TimeBaseInit,配置TIM3的时基单元
2.4 初始化编码器输入
代码如下(示例):
/*输入捕获初始化*/TIM_ICInitTypeDef TIM_ICInitStructure; //定义结构体变量TIM_ICStructInit(&TIM_ICInitStructure); //结构体初始化,若结构体没有完整赋值//则最好执行此函数,给结构体所有成员都赋一个默认值//避免结构体初值不确定的问题TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; //选择配置定时器通道1TIM_ICInitStructure.TIM_ICFilter = 0; //输入滤波器参数,可以过滤信号抖动TIM_ICInit(TIM3, &TIM_ICInitStructure); //将结构体变量交给TIM_ICInit,配置TIM3的输入捕获通道TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; //选择配置定时器通道2TIM_ICInitStructure.TIM_ICFilter = 0; //输入滤波器参数,可以过滤信号抖动TIM_ICInit(TIM3, &TIM_ICInitStructure); //将结构体变量交给TIM_ICInit,配置TIM3的输入捕获通道
2.5 配置编码器接口
/*编码器接口配置*/TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//配置编码器模式以及两个输入通道是否反相//注意此时参数的Rising和Falling已经不代表上升沿和下降沿了,而是代表是否反相//此函数必须在输入捕获初始化之后进行,否则输入捕获的配置会覆盖此函数的部分配置
2.6 开启定时器
/*TIM使能*/TIM_Cmd(TIM3, ENABLE); //使能TIM3,定时器开始运行
2.7获取编码器数据
/*** 函 数:获取编码器的增量值* 参 数:无* 返 回 值:自上此调用此函数后,编码器的增量值*/
int16_t Encoder_Get(void)
{/*使用Temp变量作为中继,目的是返回CNT后将其清零*/int16_t Temp;Temp = TIM_GetCounter(TIM3);TIM_SetCounter(TIM3, 0);return Temp;
}
三、参考程序
#include "stm32f10x.h"
#include "stdio.h"
//全局GPIO_InitTypeDef GPIO_InitStruct;int x;/*** 函 数:编码器初始化* 参 数:无* 返 回 值:无*/
void Encoder_Init(void)
{/*开启时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //开启TIM3的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟/*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(GPIOA, &GPIO_InitStructure); //将PA6和PA7引脚初始化为上拉输入/*时基单元初始化*/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); //将结构体变量交给TIM_TimeBaseInit,配置TIM3的时基单元/*输入捕获初始化*/TIM_ICInitTypeDef TIM_ICInitStructure; //定义结构体变量TIM_ICStructInit(&TIM_ICInitStructure); //结构体初始化,若结构体没有完整赋值//则最好执行此函数,给结构体所有成员都赋一个默认值//避免结构体初值不确定的问题TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; //选择配置定时器通道1TIM_ICInitStructure.TIM_ICFilter = 0; //输入滤波器参数,可以过滤信号抖动TIM_ICInit(TIM3, &TIM_ICInitStructure); //将结构体变量交给TIM_ICInit,配置TIM3的输入捕获通道TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; //选择配置定时器通道2TIM_ICInitStructure.TIM_ICFilter = 0; //输入滤波器参数,可以过滤信号抖动TIM_ICInit(TIM3, &TIM_ICInitStructure); //将结构体变量交给TIM_ICInit,配置TIM3的输入捕获通道/*编码器接口配置*/TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//配置编码器模式以及两个输入通道是否反相//注意此时参数的Rising和Falling已经不代表上升沿和下降沿了,而是代表是否反相//此函数必须在输入捕获初始化之后进行,否则输入捕获的配置会覆盖此函数的部分配置/*TIM使能*/TIM_Cmd(TIM3, ENABLE); //使能TIM3,定时器开始运行
}/*** 函 数:获取编码器的增量值* 参 数:无* 返 回 值:自上此调用此函数后,编码器的增量值*/
int16_t Encoder_Get(void)
{/*使用Temp变量作为中继,目的是返回CNT后将其清零*/int16_t Temp;Temp = TIM_GetCounter(TIM3);TIM_SetCounter(TIM3, 0);return Temp;
}void usart1_init()
{//PA9 TX PA10 RX USART1GPIO_InitTypeDef GPIO_InitStruct;USART_InitTypeDef USART_InitStruct;NVIC_InitTypeDef NVIC_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1, ENABLE);//1.开时钟GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;//发送GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStruct);GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;//接收GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStruct);USART_InitStruct.USART_BaudRate=115200;USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;USART_InitStruct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;USART_InitStruct.USART_Parity=USART_Parity_No;USART_InitStruct.USART_StopBits=USART_StopBits_1;USART_InitStruct.USART_WordLength=USART_WordLength_8b;USART_Init(USART1, &USART_InitStruct);//2.初始化串口 USART_Cmd(USART1, ENABLE);//3.是能串口USART_SendData(USART1, '4');while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)!=1);USART_SendData(USART1, '1');while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)!=1);USART_SendData(USART1, 0X41);while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)!=1);USART_SendData(USART1, 41);while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)!=1);USART_ITConfig(USART1,USART_IT_RXNE,ENABLE );// 4.接受完成中断NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 5.配置中断分组NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn;NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0;NVIC_InitStruct.NVIC_IRQChannelSubPriority=0; NVIC_Init(&NVIC_InitStruct);//配置中断优先级}int fputc(int ch,FILE *f)
{USART_SendData(USART1, (u8)ch);while(!USART_GetFlagStatus(USART1, USART_FLAG_TXE));return ch;
}void delay(u16 ms)
{u16 i,j;for(i=0;i<ms;i++)for(j=0;j<1000;j++);
}int main()
{//局部 // 库函数开启GPIO时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitStruct.GPIO_Pin= GPIO_Pin_0|GPIO_Pin_1;GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(GPIOA, &GPIO_InitStruct); //&xGPIO_InitStruct.GPIO_Pin= GPIO_Pin_2|GPIO_Pin_3;GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOB, &GPIO_InitStruct); //&x usart1_init();Encoder_Init();u16 Speed=0;GPIO_ResetBits(GPIOA, GPIO_Pin_0);GPIO_ResetBits(GPIOA, GPIO_Pin_1);while(1){GPIO_SetBits(GPIOA, GPIO_Pin_0);//GPIO_ResetBits(GPIOA, GPIO_Pin_0);u8 k=0;for(k=0;k<20;k++){GPIO_ResetBits(GPIOA, GPIO_Pin_0);GPIO_ResetBits(GPIOA, GPIO_Pin_0);delay(100);GPIO_ResetBits(GPIOA, GPIO_Pin_1);GPIO_ResetBits(GPIOA, GPIO_Pin_1);delay(100);GPIO_SetBits(GPIOA,GPIO_Pin_0); GPIO_SetBits(GPIOA,GPIO_Pin_0);delay(100);GPIO_SetBits(GPIOA,GPIO_Pin_1); GPIO_SetBits(GPIOA,GPIO_Pin_1); delay(100);}Speed = Encoder_Get(); //每隔固定时间段读取一次编码器计数增量值,即为速度值printf("测到的脉冲是=%d \r\n",Speed);}
}
四、测试结果
4.1测试方法
将正交编码编码的信号输入STM32 PA6 PA7引脚
因为没有编码器所以用PA0 和PA1模拟输出正交编码的PWM波形
如果有编码器器可以直接接入 PA6 PA7
4.2串口输出结果
结果分析:
这里对输入的波形滤波
PA0 PA1 高低电平输出
循环20次
一次PA0循环输出1次上升沿,1次下降沿
一次PA1循环输出1次上升沿,1次下降沿
20*(1+1+1+1)=80
所以计数器的次数是0
接线
总结
学习使人快乐!
音乐使人愉悦!
日积月累使人充实和自信!
相关文章:

STM32端口模拟编码器输入
文章目录 前言一、正交编码器是什么?二、使用步骤2.1开启时钟2.2配置编码器引脚 TIM3 CH1(PA6) CH2 (PA7)上拉输入2.3.初始化编码器时基2.4 初始化编码器输入2.5 配置编码器接口2.6 开启定时器2.7获取编码器数据 三、参考程序四、测试结果4.1测试方法4.2串口输出结果…...

Centos 8, add repo
Centos repo前言 Centos 8更换在线阿里云创建一键更换repo 自动化脚本 华为Centos 源 , 阿里云Centos 源 华为epel 源 , 阿里云epel 源vim /centos8_repo.sh #!/bin/bash # -*- coding: utf-8 -*- # Author: make.han...

MYSQL- 查看存储过程调式信息语句(二十七)
13.7.5.27 SHOW PROCEDURE CODE 语句 SHOW PROCEDURE CODE proc_name此语句是MySQL扩展,仅适用于已构建有调试支持的服务器。它显示了命名存储过程的内部实现的表示。类似的语句SHOW FUNCTION CODE显示有关存储函数的信息(见第13.7.5.19节“SHOW FUNTIO…...

C#基础上机练习题
21.计算500-800区间内素数的个数cn,并按所求素数的值从大到小的顺序排列,再计算其间隔加、减之和,即第1个素数-第2个素数第3个素数-第4个素数第5个素数……的值sum。请编写函数实现程序的要求,把结果cn和sum输出。 22.在三位整数…...

5.5 W5500 TCP服务端与客户端
文章目录 1、TCP介绍2、W5500简介2.1 关键函数socketlistensendgetSn_RX_RSRrecv自动心跳包检测getSn_SR 1、TCP介绍 TCP 服务端: 创建套接字[socket]:服务器首先创建一个套接字,这是网络通信的端点。绑定套接字[bind]:服务器将…...

一区北方苍鹰算法优化+创新改进Transformer!NGO-Transformer-LSTM多变量回归预测
一区北方苍鹰算法优化创新改进Transformer!NGO-Transformer-LSTM多变量回归预测 目录 一区北方苍鹰算法优化创新改进Transformer!NGO-Transformer-LSTM多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab NGO-Transformer-LST…...

深入理解 MyBatis 的缓存机制:一级缓存与二级缓存
MyBatis 是目前 Java 开发中常用的一种 ORM(对象关系映射)框架,它不仅简化了 SQL 语句的编写和管理,还提供了强大的缓存机制,用以提高数据库访问的性能。MyBatis 的缓存分为一级缓存和二级缓存,分别应用于不…...

移远通信推出全新5G RedCap模组RG255AA系列,以更高性价比加速5G轻量化大规模商用
11月20,全球领先的物联网整体解决方案供应商移远通信宣布,正式推出其全新5G RedCap模组RG255AA系列。该系列模组支持5G NR独立组网(SA)和LTE Cat 4双模通信,具有高性能高集成度、低功耗、小尺寸、高性价比等优势&#…...

架构-微服务-环境搭建
文章目录 前言一、案例准备1. 技术选型2. 模块设计3. 微服务调用 二、创建父工程三、创建基础模块四、创建用户微服务五、创建商品微服务六、创建订单微服务 前言 微服务环境搭建 使用的电商项目中的商品、订单、用户为案例进行讲解。 一、案例准备 1. 技术选型 maven&a…...

conda下载与pip下载的区别
一、conda下载与pip下载的区别 最重要是依赖关系: pip安装包时,尽管也对当前包的依赖做检查,但是并不保证当前环境的所有包的所有依赖关系都同时满足。 当某个环境所安装的包越来越多,产生冲突的可能性就越来越大。conda会检查当…...

MySQL获取数据库内所有表格数据总数
在 MySQL 中,要获取数据库内所有表格的数据总数,可以编写一个查询脚本来遍历每个表并计算其行数。你可以使用 INFORMATION_SCHEMA 数据库,它包含了关于数据库元数据的表格,如 TABLES 和 COLUMNS。 以下是一个示例脚本,…...

Matlab 深度学习工具箱 案例学习与测试————求二阶微分方程
clc clear% 定义输入变量 x linspace(0,2,10000);% 定义网络的层参数 inputSize 1; layers [featureInputLayer(inputSize,Normalization"none")fullyConnectedLayer(10)sigmoidLayerfullyConnectedLayer(1)sigmoidLayer]; % 创建网络 net dlnetwork(layers);% 训…...

django authentication 登录注册
文章目录 前言一、django配置二、后端实现1.新建app2.编写view3.配置路由 三、前端编写1、index.html2、register.html3、 login.html 总结 前言 之前,写了django制作简易登录系统,这次利用django内置的authentication功能实现注册、登录 提示ÿ…...

三种蓝牙架构实现方案
一、蓝牙架构方案 1、hostcontroller双芯片标准架构 手机里面包含很多SoC或者模块,每颗SoC或者模块都有自己独有的功能,比如手机应用跑在AP芯片上,显示屏,3G/4G通信,WiFi/蓝牙等都有自己专门的SoC或者模块࿰…...

ffmpeg 视频滤镜:高斯模糊-gblur
滤镜描述 gblur 官网地址 > FFmpeg Filters Documentation 这个滤镜会将视频变得模糊。 滤镜使用 参数 gblur AVOptions:sigma <float> ..FV.....T. set sigma (from 0 to 1024) (default 0.5)steps <int> ..FV.....T…...

期权懂|在期权市场中,如何用好双买期权?
期权小懂每日分享期权知识,帮助期权新手及时有效地掌握即市趋势与新资讯! 在期权市场中,如何用好双买期权? 期权双买操作,即同时买入认购期权(看涨期权)和认沽期权(看跌期权…...

【Linux学习】【Ubuntu入门】2-3 make工具和makefile引入
1.使用命令新建三个.c文件vi main.c,vi input.c,vi caclcu.c,两个.h文件vi input.h,vi caclcu.h 2.vi Makefile:新建Makefile文件,输入一下内容 注意:命令列表中每条命令前用TAB键,不…...

《黑神话:悟空》游戏辅助修改器工具下载指南与操作方法详解
《黑神话:悟空》是一款备受期待的动作冒险游戏,目前尚未正式发布。游戏开发团队一直在强调游戏的完整性和公平性,因此官方并不支持任何形式的作弊或修改行为。然而,对于一些玩家而言,使用辅助修改器可能会成为他们体验…...

C语言菜鸟入门·关键字·union的用法
目录 1. 简介 2. 访问成员 2.1 声明 2.2 赋值 3. 共用体的大小 4. 与typedef联合使用 5. 更多关键字 1. 简介 共用体(union)是一种数据结构,它允许在同一内存位置存储不同的数据类型,但每次只能存储其中一种类型的…...

ensp静态路由实验
一、实验目的 1、熟练掌握交换机的基本配置命令 2、熟练掌握静态路由的使用方法 3. 熟练掌握交换机端口模式 二、实验内容 需求: 根据要求利用现有实验设备组建小型局域网 实验设备: 交换机S37002台;PC机2台;路由器2台。 …...

构建 Java Web 应用程序:从 Servlet 到数据库交互(Eclipse使用JDBC连接Mysql数据库)
第 1 部分:环境设置 安装 Java Development Kit (JDK):下载并安装 JDK。设置 IDE:安装并配置 IDE(如 IntelliJ IDEA 或 Eclipse)。安装数据库:下载并安装 MySQL 数据库。配置数据库:创建数据库…...

mfc100u.dll是什么?分享几种mfc100u.dll丢失的解决方法
mfc100u.dll 是一个动态链接库(DLL)文件,属于 Microsoft Foundation Classes (MFC) 库的一部分。MFC 是微软公司开发的一套用于快速开发 Windows 应用程序的 C 类库。mfc100u.dll 文件包含了 MFC 库中一些常用的函数和类的定义,这…...

Java面试之多线程并发篇
前言 本来想着给自己放松一下,刷刷博客,突然被几道面试题难倒!说一说自己对于 synchronized 关键字的了解?说说自己是怎么使用 synchronized 关键字?什么是线程安全?Vector是一个线程安全类吗?…...

视频推拉流EasyDSS互联网直播点播平台技术特点及应用场景剖析
在数字科技日新月异的今天,视频直播和点播已经成为互联网内容传播的重要方式之一。而互联网直播点播平台EasyDSS作为功能强大的流媒体直播点播视频能力平台,提供了一站式的视频推拉流、转码、直播、点播、时移回放、存储等视频服务,广泛应用于…...

安全加固方案
交换机安全加固 查看是否关闭未使用的接口 25GE1/0/1、25GE1/0/47、25GE1/0/48需要使用,暂不关闭 system-view # interface Eth-Trunk99 shutdown quit interface Eth-Trunk100 shutdown quit interface Eth-Trunk110 shutdown quit interface 25GE1/…...

Linux firewall防火墙规则
官网 https://firewalld.org/ 查看所有防火墙规则: firewall-cmd --list-all-zones查看当前区域防火墙规则: firewall-cmd --list-all添加一个开放服务规则: firewall-cmd --add-servicessh删除一个开放服务规则: firewall-cmd…...

速盾:CDN缓存的工作原理是什么?
CDN(内容分发网络)是一种将内容分发到全球不同地理位置的网络架构,以提供更快速、可靠的内容传输。其核心原理是利用缓存技术,将数据内容分布到离用户最近的边缘节点上。当用户请求内容时,CDN将根据用户的IP地址&#…...

日常开发记录-正确的prop传参,reduce搭配promise的使用
日常开发记录-正确的prop传参,reduce搭配promise的使用 1.正确的prop传参2.reduce搭配promise的使用 1.正确的prop传参 一般会的父组件传参子组件 //父组件 <A :demodata.sync"testData" :listData.sync"testData2"></A> data ()…...

Hyper-V配置-cnblog
启用Hyper-V以在 Windows 10上创建虚拟机 (1)控制面板检查系统要求: 确保您的计算机符合 Hyper-V 的系统要求。通常情况下,您的计算机需要运行 Windows 10 专业版、企业版或教育版,并且具有启用了虚拟化技术的处理器。…...

运维Tips:Docker或K8s集群拉取Harbor私有容器镜像仓库配置指南
[ 知识是人生的灯塔,只有不断学习,才能照亮前行的道路 ] Docker与Kubernetes集群拉取Harbor私有容器镜像仓库配置 描述:在现在微服务、云原生的环境下,通常我们会在企业中部署Docker和Kubernetes集群,并且会在企业内部搭建Harbor私有镜像仓库以保证开发源码安全,以及加快…...