stm32读取编码器的两种方式
1.使用外部中断 读取
#include "spin.h"#define encoder_port GPIOG
#define encoder_pin (GPIO_Pin_3|GPIO_Pin_5)
#define encoder_pin_A GPIO_Pin_3 //外部中断引脚
#define encoder_pin_B GPIO_Pin_5void Encoder_Init_Exit()
{GPIO_InitTypeDef GPIO_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;EXTI_InitTypeDef EXTI_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn; //选择触发的通道 EXTI3_IRQn 与 PG3 EXTI_Line3 一致NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应优先级NVIC_Init(&NVIC_InitStructure);RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE);GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_FLOATING;// GPIO_Mode_IPU; //配置为上拉模式GPIO_InitStructure.GPIO_Pin = encoder_pin;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(encoder_port, &GPIO_InitStructure);// GPIO_PinRemaConfig() 可以用来引脚重映射GPIO_EXTILineConfig(GPIO_PortSourceGPIOG, GPIO_PinSource3); //配置AFIO的数据选择器,来选择我们要的引脚,指定外部中断线EXTI_InitStructure.EXTI_Line = EXTI_Line3; //需要我们配置中断线,我们用PG3所在的 EXTI_Line3EXTI_InitStructure.EXTI_LineCmd = ENABLE; //开启中断EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断模式EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //设置触发方式 下降沿触发EXTI_Init(&EXTI_InitStructure); //调用这个参数,就可以根据这个结构体}void EXTI3_IRQHandler(void)
{if (EXTI_GetITStatus(EXTI_Line3) == SET) //确认是 EXTI_Line3引发的中断{ // encoder_pin_A 设置了外部中断,下降沿触发delay_ms(1); //很重要,必不可少, 软件滤波if (0 == GPIO_ReadInputDataBit(encoder_port, encoder_pin_A)) //判断 encoder_pin_A是低电平, 经历了下降沿{if (1 == GPIO_ReadInputDataBit(encoder_port, encoder_pin_B)) //判断 encoder_pin_B 电平状态,{++encoder_g.counter;encoder_g.dir= 10; //正转标志} else{--encoder_g.counter;encoder_g.dir = 20; //反转标志}printf("count %d\n", Encoder_Readnum_Exit(0));printf("dir %d\n", Encoder_ReadDir_Exit());}EXTI_ClearITPendingBit(EXTI_Line3); //手动清除外部中断标志位 }
}
/*** @brief 正转返回1 反转返回-1 静止返回0* */
int Encoder_ReadDir_Exit(void)
{if( 10 == encoder_g.dir ){encoder_g.dir= 0;return 1;}else if (20 == encoder_g.dir ){encoder_g.dir = 0;return -1;}else{encoder_g.dir = 0;return 0;}
}/*** @brief flag=0 读数cnt不清零 flag=0 读数cnt清零**/
int Encoder_Readnum_Exit(u8 flag)
{int result = encoder_g.counter;if (flag){encoder_g.counter = 0;}return result;
}
#ifndef _SPIN_H
#define _SPIN_H#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "delay.h"
#include "usart.h"typedef struct E_g{int counter; //计数 u8 dir; //旋转方向 正为+ 反为- 静为 0u8 sw; //按键状态 按下置1}Encoder_g;static Encoder_g encoder_g={.counter=0,.dir=0,.sw=0
};void Encoder_Init_Exit();
int Encoder_Readnum_Exit(u8 flag);
int Encoder_ReadDir_Exit(void);#endif
2.定时器作编码电机模式读取
#include "encoder.h"/**************************************************************************
函数功能:单位时间读取编码器B计数
入口参数:无
返回 值:计数值
**************************************************************************/
int Read_Encoder(TIM_TypeDef *TIMx)
{return (short)TIMx->CNT;
}
/**************************************************************************
函数功能:把TIM初始化为编码器接口模式
端口配置: PB6 PB7
入口参数:无
返回 值:无
**************************************************************************/void Encoder_Init_TIMx(TIM_TypeDef* TIMx ){TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_ICInitTypeDef TIM_ICInitStructure;GPIO_InitTypeDef GPIO_InitStructure;// NVIC_InitTypeDef NVIC_InitStructure;// NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级3// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级3// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能// NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器/*----------------------------不同定时器 修改这里 以及中断函数配置--------------------------------*/// GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE); //重映射配置 引脚冲突时配置RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器3的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能PB端口GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; //端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PB端口TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // 预分频器TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD; //设定计数器自动重装值TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //选择时钟分频:不分频TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //边沿计数模式TIM_TimeBaseInit(TIMx, &TIM_TimeBaseStructure); //初始化定时器3TIM_EncoderInterfaceConfig(TIMx, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); //使用编码器模式3(TIM_ICPolarity_Rising或者TIM_ICPolarity_Falling效果相同,都是4倍频)TIM_ICStructInit(&TIM_ICInitStructure); //把TIM_ICInitStruct 中的每一个参数按缺省值填入TIM_ICInitStructure.TIM_ICFilter = 10; //设置滤波器长度TIM_ICInit(TIMx, &TIM_ICInitStructure); //根据 TIM_ICInitStruct 的参数初始化外设 TIMxTIM_ClearFlag(TIMx, TIM_FLAG_Update); //清除TIM的更新标志位TIM_ITConfig(TIMx, TIM_IT_Update, ENABLE); //使能定时器中断TIM_SetCounter(TIMx, 0); //计数初值设定TIM_Cmd(TIMx, ENABLE); //使能定时器
}/*************************************************************************** 函数功能:TIM中断服务函数** 功能:防止定时器cnt计数溢出* * 入口参数:无* * 返 回 值:无**************************************************************************/
// void TIM3_IRQHandler(void)
// {
// if (_TIM3_->SR & 0X0001) //溢出中断
// {
// }
// _TIM3_->SR &= ~(1 << 0); //清除中断标志位
// }
#ifndef _encoder_H_
#define _encoder_H_#include "stm32f10x.h"
#include "stm32f10x_tim.h"
#include "stm32f10x_gpio.h"
#define ENCODER_TIM_PERIOD (u16)(65535) typedef struct bianmadianji
{int coder;u8 mode; }G_ENCODER;static G_ENCODER g_ENCODER={0,0};void Encoder_Init_TIMx(TIM_TypeDef* TIMx);int Read_Encoder(TIM_TypeDef* TIMx);#endif
stm32读取编码器的两种方式相关推荐
- spark消费kafka产生数据堆积怎么处理_SparkStreaming读取Kafka的两种方式
本文主要从以下几个方面介绍SparkStreaming读取Kafka的两种方式: 一.SparkStreaming简介 二.Kafka简介 三.Redis简介(可用于保存历史数据或偏移量数据) 四.S ...
- sparkstreaming 读取mysql_SparkStreaming读取Kafka的两种方式
本文主要从以下几个方面介绍SparkStreaming读取Kafka的两种方式: 一.SparkStreaming简介 二.Kafka简介 三.Redis简介(可用于保存历史数据或偏移量数据) 四.S ...
- nodejs 逐行读取文件的两种方式
nodejs 逐行读取文件的两种方式 通过readline的方式 const fs = require('fs'); const readline = require('readline');let ...
- Java读取证书的两种方式
关于证书基础以及创建.查看.删除.导入.导出以及其他功能详解请参照:Java使用keytool创建CA证书 Java读取证书有两种方式 1.从文件中读取 public static void main ...
- Delphi 读取文本文件的两种方式
用两种方式读取文本文件:文件流读取和文件变量读取 一.文件流方式 {*******************************************************} {功能:读取文本文 ...
- 关于spring读取配置文件的两种方式
很多时候我们把需要随时调整的参数需要放在配置文件中单独进行读取,这就是软编码,相对于硬编码,软编码可以避免频繁修改类文件,频繁编译,必要时只需要用文本编辑器打开配置文件更改参数就行.但没有使用框架之前 ...
- 一行一行读取文件的两种方式
1)方式1 static void Main(string[] args){ using (StreamReader reader = new StreamReader("1.txt&quo ...
- Java代码读取图片的两种方式
不废话在,直接上代码: 方式一: 适用场景: 图片size小 方式二: 适用场景: 图片size大 细节点: java 代码读取图片的方式,从这点入手: 关注我的博客
- 天池实验室|读取数据集的两种方式
读取挂载数据中的数据集 具体代码如下: # 步骤1: !ls datalab/# 步骤2: import os os.chdir('/home/tianchi/datalab/75057') prin ...
最新文章
- 心理所发表关于神经科学研究可信度的评论文章
- React,Redux,React-redux的错综复杂关系
- Docker入门系列8
- SpringMVC简单项目配置
- [bug]超时时间已到。超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小。...
- SIGIR 2019 | 基于人类阅读行为模式的机器阅读理解
- 我的docker随笔10:docker客户端使用其它主机的docker服务器
- Python之网络爬虫(Xpath语法、Scrapy框架的认识)
- java filledrectangle_算法(第4版)-1.1.9 输入输出
- ApsaraDB for SQL Server 混合云场景一种解决方案
- url传值的一个问题解决
- CSS设置居屏幕中间的弹出块
- Solr系列三:solr索引详解(Schema介绍、字段定义详解、Schema API 介绍)
- 如何安全的使用密码登录账号(在不知道密码的情况下)
- Mysql 创建数据库\添加用户\用户授权
- 体育科技文献通报杂志体育科技文献通报杂志社体育科技文献通报编辑部2022年第6期目录
- Windows防火墙无法更改某些设置
- py樱花代码_Python如何画出美丽浪漫的樱花
- Java程序设计-实验6-sdust
- NFTScan 开发者平台推出多链 NFT 数据 Pro API 服务