学习目标
- 了解编码器的构成
- 理解编码器采样原理
-
学习内容
编码器组成

左侧的减速齿轮
- 中间的电机部分
-
减速齿轮
电路板

电路板中,包含了一个圆形磁体,还有两个霍尔传感器。
电机转动时,圆形的磁体会同步进行转动,传动过程

电机转动时,中轴会转动
- 中轴和圆形磁铁是连在一起的,圆形磁铁也会同步转动
- 中轴的一端和减速齿轮连接在一起,中轴转动会带动齿轮按照一定的比例进行转动(减速比)。
霍尔传感器

开发板中包括了两个霍尔传感器,一个磁铁。
磁铁是由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;}
练习
- 能够读取轮子转速
