1.材料清单
STM32F103C8T6开发板(黑色板)、旋转编码器、microUSB数据线、导线及面包板
2.旋转编码器原理
旋转编码器是一种位置传感器,用于确定旋转轴的角位置,它根据旋转运动生成模拟或数字电信号。旋转编码器有许多不同类型,它们根据输出信号或传感技术进行分类。我们将使用的旋转编码器是增量式旋转编码器,如下图,它是测量旋转的最简单的位置传感器。
方波脉冲的产生方式如下:编码器的磁盘上有均匀分布的接触区,分别连接到公共引脚C和另外两个单独的接触引脚A和B,如下所示。
当磁盘逐步开始旋转时,引脚A和B将开始与公共引脚接触,并且将相应地产生两个方波输出信号。
如果仅对信号的脉冲进行计数,则可以使用两个输出中的任何一个来确定旋转位置。但是,如果我们也要确定旋转方向,则需要同时考虑两个信号。A和B信号的输出波形如下:
我们可以注意到,两个输出信号相位彼此之间相差90度。如果编码器顺时针旋转,则输出A将在输出B之前;如果编码器逆时针旋转,则输出A将在输出B之后。
进一步地,A信号从高到低或从低到高变化的时刻,我们注意到如果编码器顺时针旋转,那么两个输出信号的值相反;如果编码器逆时针旋转,则输出信号具有相等的值。因此,我们可以轻松地对控制器进行编程以读取编码器的位置和旋转方向。
编码器的按钮在未按下时为高电平,按下时则为低电平,对SW引脚进行电平检测即可判断按钮是否按下。
Let's get started!
3.电路连接
4.Arduino程序
需要注意的是由于机械原因,按键会产生抖动,故用50ms延时消抖(debounce)。
/* 编码器读取demo
* 电路连接:
* GND-G
* + --5V
* SW-PA7:按钮检测
* DT-PB0:B信号序列
* CLK-PB1:A信号序列
* 参考:https://www.youtube.com/watch?v=cYCTMdUi8P0
* https://www.youtube.com/watch?v=v4BbSzJ-hz4&t=2s
*/
#define CLK PB1
#define DT PB0
#define SW PA7
int counter = 0;
int aState;
int aLastState;
int bState;
int bLastState;
int SWState;
int SWLastState;
void setup() {
pinMode(CLK,INPUT);
pinMode(DT,INPUT);
pinMode(SW,INPUT_PULLUP);
Serial.begin (9600);
// Reads the initial state of the CLK
aLastState = digitalRead(CLK);
bLastState = digitalRead(DT);
SWLastState = digitalRead(SW);
}
void loop() {
SWState = digitalRead(SW); // 按钮输出状态
aState = digitalRead(CLK); // CLK的输出状态0/1
bState = digitalRead(DT); // DT的输出状态0/1
if (aState != aLastState){ //变化检测
delay(50);//消抖
if (aState != bState) { // 如果A!=B,则表示编码器正在顺时针旋转
counter ++;
}
else{ // 如果A=B,则表示编码器正在逆时针旋转
counter --;
}
Serial.print("num: ");
Serial.println(counter);
}
if (SWState == 0 and SWLastState == 1){
delay(50);//消抖
Serial.println("num: 0");
counter = 0;
while (digitalRead(SW) == 0);//等待按钮抬起
delay(200);
}
// Serial.print("nowSW: ");
// Serial.println(SWState);
aLastState = aState;
SWLastState = SWState;
}