下图是这次使用的旋转编码器模块
STM32F103C8T6驱动旋转编码器模块
- 产品说明
- 使用测试
- 硬件连接
- 代码如下
- main.c
- rotary_encoder.h.c
- rotary_encoder.h.h
- 脉冲数和正反转演示图
- 工程文件
产品说明
旋转编码器可通过旋转,可以计数正方向和反方向 转动过程中输出脉冲的次数,旋转计数不像电位计, 这种转动计数是没有限制的。配合旋转编码器上的 按键,可以复位到初始状态,即从0开始计数。
使用测试
增量式编码器:因为通过检测脉冲的数量和方向来确定旋转的角度和方向。每个脉冲代表一个固定的角度变化,通常有A相和B相两个信号输出,可以通过脉冲的相位差来确定旋转方向。
所以我就先直接拿逻辑分析仪测试了一下,将+接到3.3V或者5V,将GND接到地。将SW,DT,CLK接到逻辑分析仪端口,效果如图所示。
可以清晰的看出来规律,正转DT下降沿CLK=0,DT上升沿CLK=1。反转DT下降沿CLK=1,DT上升沿CLK=0。SW按下为低电平,所以利用这点就可以编写代码了。
硬件连接
接线如下所示
STM32 | 编码器 |
---|---|
3.3V | + |
GND | GND |
PB12 | SW |
PB13 | DT |
PB14 | CLK |
代码如下
功能:串口打印出脉冲数和正反转和SW的状态
使用说明:由于有些文件没有给,自行补充uart打印和引用bool的头文件
main.c
#include "system.h"int main()
{system_init();//USER_LED_Set(1);while(1){if(SW_Get()==0){//USER_LED_Set(0);printf("编码器被按下\r\n");while(SW_Get()==0);}//else USER_LED_Set(1);}
}
rotary_encoder.h.c
#include "rotary_encoder.h"/*
PB12 -- SW
PB13 -- DT
PB14 -- CLK
*/
void rotary_encoder_init(void)
{RCC->APB2ENR|=(1<<3); //使能GPIOB时钟//初始化PB12 PB13 PB14 上拉输入GPIOB->CRH &=0xf000ffff; GPIOB->CRH |=0x08880000; GPIOB->ODR |=(7<<12);//初始化PB13 PB14 SW 上拉输入RCC->APB2ENR|=(1<<0); //开启AFIO时钟AFIO->EXTICR[3] |=(1<<4); //选择EXTI13外部中断的输入源为GPIOB13
// AFIO->EXTICR[3] |=(1<<8); //选择EXTI14外部中断的输入源GPIOB14EXTI->FTSR |=(1<<13);//EXTI13下降沿引起中断EXTI->RTSR |=(1<<13);//EXTI13上升沿引起中断
// EXTI->FTSR |=(1<<14);//EXTI14下降沿引起中断EXTI->IMR |=(1<<13);//打开EXTI13中断
// EXTI->IMR |=(1<<14);//打开EXTI14中断NVIC->ISER[1] |=(1<<8);//启用EXTI10-15中断NVIC->IP[40] &=0x00; //清空优先级NVIC->IP[40] |=((0X03<<4)|0X03);//抢占优先级和响应优先级
}bool positive_status=0;
bool reversal_status=0;
uint16_t positive_num=0;
uint16_t reversal_num=0;
void EXTI15_10_IRQHandler(void)
{if(EXTI->PR&(1<<13)){if(!(GPIOB->IDR&(1<<13))) //下降沿触发{if(CLK_Get()==0)positive_status=1;else reversal_status=1;}else //上升沿触发{if((CLK_Get()==1)&&(positive_status==1)){positive_status=0;positive_num++;printf("正转\r\n");printf("正转脉冲数:%d\r\n",positive_num);}if((CLK_Get()==0)&&(reversal_status==1)){reversal_status=0;reversal_num++;printf("反转\r\n");printf("反转脉冲数:%d\r\n",reversal_num);} }EXTI->PR|=(1<<13); //清除中断标志位}
}
rotary_encoder.h.h
#ifndef __rotary_encoder_h_
#define __rotary_encoder_h_#include "system.h"/*
PB12 -- SW
PB13 -- DT
PB14 -- CLK
*///SW
#define SW_Get() (((GPIOB->IDR)&(1<<12))?1:0)
//DT
#define DT_Get() (((GPIOB->IDR)&(1<<13))?1:0)
//CLK
#define CLK_Get() (((GPIOB->IDR)&(1<<14))?1:0)void rotary_encoder_init(void);#endif
脉冲数和正反转演示图
工程文件
代码百度云版
代码CSDN版