学习目标
- 了解编码器的构成
- 理解编码器采样原理
-
学习内容
编码器组成
左侧的减速齿轮
- 中间的电机部分
-
减速齿轮
电路板
电路板中,包含了一个圆形磁体,还有两个霍尔传感器。
电机转动时,圆形的磁体会同步进行转动,传动过程
电机转动时,中轴会转动
- 中轴和圆形磁铁是连在一起的,圆形磁铁也会同步转动
- 中轴的一端和减速齿轮连接在一起,中轴转动会带动齿轮按照一定的比例进行转动(减速比)。
霍尔传感器
开发板中包括了两个霍尔传感器,一个磁铁。
磁铁是由7对N极和S极组成的。
- 当电机转动时,磁铁也转动。
- 当磁铁的N极正对霍尔传感器时,霍尔传感器会将这个信号转化为高电平。
- 当磁铁的S极正对霍尔传感器时,霍尔传感器会将这个信号转化为低电平。
- 通过记录高低电平变换次数,可以得到电机中轴转动的速度。
重要的概念名称
减速比和额定转速
以下是以N20电机为例,N20的规格参数,其中我们关注额定转速和减速比。
额定转速:rpm,全称Revolutions Per Minute
,每分钟转动的圈数,说的时末端连接轴的转速。
减速比:电机中轴连接了齿轮,当中轴转动时,齿轮随着中轴转动而转动,最终传导到末端连接轴。末端连接轴的速度,被减速齿轮降低了,末端连接轴和中轴的速度比就是减速比。例如rpm为300,减速比为50,那么电机中轴的转速为300*50 = 15000转/分轮子行进速度
我们知道,速度=距离/时间
轮子是和末端连接轴连接在一起的,RPM为300时,轮子1分钟可以转300圈,那轮子可以走过的距离我们是可以求出来的。
转一圈,就是轮子的一个周长,周长=2ΠR
因此,在RPM为300时,轮子的速度为 300(rpm) x 43(直径) x Π / 60
得出结果为 675.442409 mm/s,换算下来差不多为 0.6到0.7米/秒
霍尔传感器采样
两个霍尔传感器加上磁铁,可以测出电机的转速和方向。
- 当A传感器是上升沿时,如果B此时为低电平,那么就是反转。
- 当A传感器是上升沿时,如果B此时为高电平,那么就是正转。
- 产生一次上升沿或者下降沿,就记一次数,通过时间就可以测出当前的转速了。
对于霍尔采样,我们可以通过外部中断方式进行实现,代码如下:
#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>
#include "main.h"
#include "Usart.h"
#include "I2C.h"
#include "bsp_mpu6050.h"
#include "inv_mpu.h"
#include "inv_mpu_dmp_motion_driver.h"
FlagStatus pre = RESET;
int8_t dir = 1;
int32_t cnt = 0;
void Usart0_recv(uint8_t* data, uint32_t len) {
printf("recv: %s\r\n", data);
}
static void EXTI8_config() {
uint32_t extix = EXTI_8;
uint32_t extix_irq = EXTI5_9_IRQn;
uint32_t extix_irq_pre = 1;
uint32_t extix_irq_sub = 1;
uint32_t extix_trig = EXTI_TRIG_RISING;
uint32_t extix_rcu = RCU_GPIOB;
uint32_t extix_port = GPIOB;
uint32_t extix_pin = GPIO_PIN_8;
uint32_t extix_pupd = GPIO_PUPD_NONE;
uint32_t extix_src_port = EXTI_SOURCE_GPIOB;
uint32_t extix_src_pin = EXTI_SOURCE_PIN8;
/*************** gpio ****************/
// PA0,
// 时钟初始化
rcu_periph_clock_enable(extix_rcu);
// 配置GPIO模式
gpio_mode_set(extix_port, GPIO_MODE_INPUT, extix_pupd, extix_pin);
/*************** exti ****************/
// 时钟配置
rcu_periph_clock_enable(RCU_SYSCFG);
// 配置中断源
syscfg_exti_line_config(extix_src_port, extix_src_pin);
// 中断初始化
exti_init(extix, EXTI_INTERRUPT, extix_trig);
// 配置中断优先级
nvic_irq_enable(extix_irq, extix_irq_pre, extix_irq_sub);
// 使能中断
exti_interrupt_enable(extix);
// 清除中断标志位
exti_interrupt_flag_clear(extix);
}
void EXTI5_9_IRQHandler() {
// 判断寄存器状态
if(SET == exti_interrupt_flag_get(EXTI_8)) {
FlagStatus current = gpio_input_bit_get(GPIOB, GPIO_PIN_9);
if(RESET == current && SET == pre) {
pre = current;
dir = 1;
//cnt = 0;
} else if(SET == current && RESET == pre) {
pre = current;
dir = -1;
//cnt = 0;
}
cnt += dir;
printf("cnt: %d\r\n", cnt);
// 清除中断标志位
exti_interrupt_flag_clear(EXTI_8);
}
}
static void GPIO_config() {
rcu_periph_clock_enable(RCU_GPIOB);
gpio_mode_set(GPIOB, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_9);
}
int main(void)
{
nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);
systick_config();
GPIO_config();
Usart_init();
EXTI8_config();
while(1) {
}
}
正交编码
正交编码是一种用于测量旋转位置或速度的技术。它通常涉及到两个相位差90度的信号(A相和B相)。这两个信号通过光电传感器、磁性传感器或其他位置传感器生成。正交编码的主要原理是通过检测A相和B相信号的相对相位变化来确定旋转的方向和步数。
A相和B相信号: A相和B相信号是两个相位差90度的正弦波形或方波形。这两个信号的变化在旋转方向上具有差异。
相位关系: 如果A相先于B相发生变化,系统会认为是顺时针旋转;如果B相先于A相发生变化,系统会认为是逆时针旋转。通过检测这两个信号的相对相位变化,可以确定旋转的方向。
脉冲计数: 在正交编码器中,每个脉冲表示一个步进。通过计数脉冲的数量,可以确定旋转的总步数。
增量式测量: 正交编码器提供的是增量式的测量,而不是绝对位置。为了得到绝对位置,通常需要在系统启动时将编码器归零,然后开始测量。
当前的电机测速传感器满足这种结构和表现。
在GD32中,配置正交编码如下:
// 输入配置
timer_ic_parameter_struct tips;
timer_channel_input_struct_para_init(&tips);
tips.icfilter = 10;
timer_input_capture_config(timerx, TIMER_CH_0, &tips);
timer_quadrature_decoder_mode_config(timerx,
TIMER1_QUADRATURE_DECODER_MODE,
TIMER1_QUADRATURE_DECODER_IC0,
TIMER1_QUADRATURE_DECODER_IC1);
对于正交编码采样逻辑如下:
short Timer1_input_read() {
uint32_t timerx = TIMER1;
short value = 0;
value = (short)timer_counter_read(timerx);
timer_counter_value_config(timerx, 0);
return value;
}
练习
- 能够读取轮子转速