打印
[STM32MP1]

基于STM32F4系列 之 霍尔编码器减速直流电机

[复制链接]
557|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
前言

这篇博文为作者实验经历写下的笔记,借鉴学习了多位博主的博文,并总结了互联网资料。本篇使用的是JGB37-520减速直流电机并结合USMART调试模块,上位机通信控制PWM输出,如有错误敬请大佬们斧正。


一、关于编码器的介绍

JGB37-520减速直流电机

       编码器是将信号(如比特流)或数据进行编制、转换为可用以通讯、传输和存储的信号形式的设备。编码器把角位移或直线位移转换成电信号,前者称为码盘,后者称为码尺。按照读出方式编码器可以分为接触式和非接触式两种;按照工作原理编码器可分为增量式和绝对式两类。

       增量式编码器是将位移转换成周期性的电信号,再把这个电信号转变成计数脉冲,用脉冲的个数表示位移的大小。绝对式编码器的每一个位置对应一个确定的数字码,因此它的示值只与测量的起始和终止位置有关,而与测量的中间过程无关。


使用特权

评论回复
评论
初级工程渣 2022-7-31 20:28 回复TA
———————————————— 版权声明:本文为CSDN博主「三态门」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/m0_63741844/article/details/121446062 
沙发
初级工程渣|  楼主 | 2022-7-31 20:27 | 只看该作者
按照原理可分为(常见的)

           1,光电编码器(光学式),

           2,触点电刷式

           3,霍尔编码器(磁式)。

使用特权

评论回复
板凳
初级工程渣|  楼主 | 2022-7-31 20:28 | 只看该作者
二、编码器的工作原理(正交式)
       编码器能够将电机的机械几何位移转化为脉冲信号或数字量。本实验采用的编码器为增量式编码器,增量式编码器通常有两个输出信号,分别为A相和B相。电机带动霍尔码盘转动,在码盘的结构位上将电机在转动时会产生A、B两相的脉冲信号,且这两路脉冲信号的相位差为90度(即正交)配置定时器进行捕获计数,测得脉冲频率,再根据脉冲序列的频率确定电机的转速。同时,在此过程中,A,B相位触发的先后顺序可以确定转动的正反方向。

使用特权

评论回复
地板
初级工程渣|  楼主 | 2022-7-31 20:29 | 只看该作者

使用特权

评论回复
5
初级工程渣|  楼主 | 2022-7-31 22:16 | 只看该作者
stm32F4定时器中部分定时器提供了编码器模式,可大大简化解析过程。

高级定时器TIM1和TIM8,通用定时器TIM2-TIM5支持定位用增量(正交)编码器和霍尔传感器电路。

使用特权

评论回复
6
初级工程渣|  楼主 | 2022-7-31 22:16 | 只看该作者
编码器电机的配置

使用特权

评论回复
7
初级工程渣|  楼主 | 2022-7-31 22:17 | 只看该作者
M1与M2为电机电源,通过TB6612FNG等电机驱动输出PWM信号,减速电机的转速。

M1与M2,高/低电平决定电机转动的方向(测试电机:直接向其接入12V以下电源,另一端接地,反之反转)

使用特权

评论回复
8
初级工程渣|  楼主 | 2022-7-31 22:18 | 只看该作者
中间部分为编码盘部分与减速电机可区别开:

GND----接地      VCC----接电源3.3V

C1----霍尔编码器A相位  C2----霍尔编码器B相位

使用特权

评论回复
9
初级工程渣|  楼主 | 2022-7-31 22:28 | 只看该作者
霍尔传感器编码器的测速模块,配有 11 线强磁码盘,A B 双相输出 共同利用下,通过计算可得出车轮转一圈时,脉冲数可达30*11*2=660个,单相也可以达到 330 个.(减速比为30:1)

使用特权

评论回复
10
初级工程渣|  楼主 | 2022-7-31 22:31 | 只看该作者
关于编码器的工作模式:

模式1,即计数器仅在TI1的边沿处计数;

模式2,即计数器仅在TI2的边沿处计数;

模式3,即定时器在TI1、TI2双边沿处计数(具体请参考stm32f4系列中文参考手册)

使用特权

评论回复
11
初级工程渣|  楼主 | 2022-7-31 22:32 | 只看该作者
代码配置部分
本篇使用的是JGB37-520减速直流电机并结合USMART调试模块,上位机通信控制PWM输出。

main.c主函数如下

使用特权

评论回复
12
初级工程渣|  楼主 | 2022-7-31 22:32 | 只看该作者
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "Encoder.h"   //编码器头文件
#include "pwm.h"       //PWM配置头文件
#include "led.h"
#include "lcd.h"        
#include "usmart.h"                //USMART调试组件头文件

unsigned int run;

void set(unsigned int i)//USMART组件注册函数配置
{
        TIM_SetCompare1(TIM14,i);//上位机调节PWM值控制转速
    run=i;       
}

int main(void)
{
        uint32_t encoder; //定义编码值
        float pulse;          //定义电机实际脉冲值
        float speed;          
       
        GPIO_InitTypeDef  GPIO_InitStructure;
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        delay_init(168);  
        uart_init(115200);
        usmart_dev.init(84);         //调试组件初始化
        LCD_Init();
        LED_Init();
        TIM14_PWM_Init(500-1,84-1);        //电机PWM初始化
        encoder_init();       
       
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//配置转速电机方向TB6612FNG工作
                                                         //模式位
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_5;           
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;        
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;   
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;      
        GPIO_Init(GPIOF,&GPIO_InitStructure);            
       
        GPIO_SetBits(GPIOF,GPIO_Pin_6 | GPIO_Pin_7|GPIO_Pin_5);
        GPIO_ResetBits(GPIOF,GPIO_Pin_7);
       
   while(1)
        {       
                TIM_SetCompare1(TIM14,run);
                encoder = read_cnt();       
                pulse = encoder/2;
            speed = encoder/2/6.3/11;

                LCD_ShowString(10,100,50,16,16,"encoder:");
                LCD_ShowNum(90,100,encoder,5,16);
               
                LCD_ShowString(10,130,50,16,16,"pulse:");
                LCD_ShowNum(90,130,pulse,5,16);
               
                LCD_ShowString(10,160,50,16,16,"speed:");
                LCD_ShowNum(90,160,speed,5,16);
               
                printf("encoder:%d \t speed:%lf rps \t",encoder,speed);//上位机显示编码值与转速
                delay_ms(500);//延迟500ms
                LED1=!LED1;        //LED1闪烁
        }
}

使用特权

评论回复
13
初级工程渣|  楼主 | 2022-7-31 22:36 | 只看该作者
encoder.c文件如下:
#include "Encoder.h"
#include "sys.h"

void encoder_init(void)//定时器工作模式为编码器工作模式
{
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
        TIM_ICInitTypeDef TIM_ICInitStructure;
       
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
       
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;//配置A、B相位
        GPIO_Init(GPIOA, &GPIO_InitStructure);                //初始化IO口

        GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_TIM3);   //映射复用定时器
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_TIM3);
       
        TIM_TimeBaseStructure.TIM_Prescaler = 0;         //脉冲值计数                                       
        TIM_TimeBaseStructure.TIM_Period = 65535;                                       
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

        TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
       
        TIM_ICStructInit(&TIM_ICInitStructure);                                               
       
        TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising ,TIM_ICPolarity_Rising);      //A、B均为上升沿触发,为二倍频

        TIM_SetCounter(TIM3, 0);               
        TIM_Cmd(TIM3, ENABLE);                        //使能定时器TIM3
}

uint32_t read_cnt(void)  //定时器计数值读取
{
        uint32_t encoder_cnt;
       
        encoder_cnt = TIM3->CNT;               
        TIM_SetCounter(TIM3, 0);       
       
        return encoder_cnt;                       
}

使用特权

评论回复
14
初级工程渣|  楼主 | 2022-7-31 22:36 | 只看该作者
可通过XCOM软件与STM32通信,向单片机发送数据,调试电机。

usmart.c调试组件配置(部分)如下:

使用特权

评论回复
15
初级工程渣|  楼主 | 2022-7-31 22:38 | 只看该作者
// 
#include "delay.h"               
#include "sys.h"
#include "lcd.h"
#include "pwm.h"

extern void set(unsigned int i);//注册PWM控制函数

struct _m_usmart_nametab usmart_nametab[]=   //添加进调试库            
{
        (void*)set,"set(unsigned int i)",                                              
};                                                  
///END///

使用特权

评论回复
16
Bblythe| | 2022-10-4 07:30 | 只看该作者

利用协议、加密算法或这些算法中的安全漏洞来进行攻击

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

55

主题

610

帖子

0

粉丝