stm32平衡小车(2)-----编码器电机驱动
创始人
2024-05-13 09:25:31
0

前言:之前做arduino小车的时候使用的是L298N电机,没有用过编码器,这次第一次用编码器,还是比较懵圈,记录一下学的整个过程。

1.编码器的简介

霍尔编码器是一种通过磁电转换将输出轴上的机械几何位移量转换成脉冲或数字量的传感器。

霍尔编码器是由霍尔码盘(磁环)和霍尔元件组成。

霍尔码盘是在一定直径的圆板上等分地布置有不同的磁极。霍尔码盘与电动机同轴,电动机旋转时,霍尔元件检测输出若干脉冲信号,为判断转向,一般输出两组存在一定相位差的方波信号

编码器为了获得每一圈的脉冲数,通过公式可以将其转化为当前电机的转速,从而达到测速的目的。

2.接线方式:

我买的是tb6612的一个综合体驱动模块,这样接线比较方便。

 v---5v电源        G----GND【接地】    A和B则是编码器的A,B相。

M1和M2则和电机的E1A和E1B相连接   

3.编码器的倍频原理

 正常的情况都是去捕获一个相位的上升沿或者下降沿,这样每个周期只能捕获一次

编码器的四倍频技术就是,单个周期内,同时捕获A和B的上升沿和下降沿,这样单个周期内就可以捕获四次,翻了四倍,当A因为跳变触发了外部中断,在中断里面判断B是什么电平,从而来判断当前轮子是正转还是反转。

4.编码器的计数原理

编码器选择的是四倍频技术,即在T1和T2同时进行计数。

借助这个计数,可以算出固定周期内的编码器的脉冲数,借助M测速法,算出当前的电机的速度。

同时根据图可以发现,A相在前就是轮子正转,B相在前就是轮子反转。

5.编码器代码理解

 设置为65536,为了增大计数周期,且计数频率加快,保证了系统的不管轮子转速多块都可以检测到当前的脉冲次数

 TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);

第一个:定时器的选择

第二个:选择是T1和T2,进行双通道的上下沿计数。

第三,四个:反相or不反相

不反相:正转,计数++,反转,计数--。

反相:正转,计数--,反转,计数++。 

 这里将其中的一个脉冲值的读入前面加入负号,因为两个轮子安装是相反的,这样是为了保持极性的一致。

此时计数器的数值便是在TIM4定时器单个周期内,计算左右轮子的脉冲数。

某乎的这张图很清晰的介绍了霍尔编码器的运行方式。

 6.PWM输出使能

设置定时器的通道PWM输出使能,然后设置IO口控制电平的输出。

设置输出通道的极性,和PWM输出模式。

void TIM1_PWM_Init(u16 arr,u16 psc)
{  GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;TIM_OCInitTypeDef  TIM_OCInitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);  //使能GPIO外设时钟使能//设置该引脚为复用输出功能,输出TIM1 CH1 CH4的PWM脉冲波形GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_11; //TIM_CH1 //TIM_CH4GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	 TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  不分频TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能TIM_OCInitStructure.TIM_Pulse = 0;                            //设置待装入捕获比较寄存器的脉冲值TIM_OCInitStructure.TIM_Pulse = arr >> 1;TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;     //输出极性:TIM输出比较极性高TIM_OC1Init(TIM1, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMxTIM_OC4Init(TIM1, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMxTIM_CtrlPWMOutputs(TIM1,ENABLE);	//MOE 主输出使能	TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);  //CH1预装载使能	 TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);  //CH4预装载使能	 TIM_ARRPreloadConfig(TIM1, ENABLE); //使能TIMx在ARR上的预装载寄存器TIM_Cmd(TIM1, ENABLE);  //使能TIM1
}

设置IO口进行电平的输出。

void Motor_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB端口时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;	//端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     //50MHZGPIO_Init(GPIOB, &GPIO_InitStructure);					      //根据设定参数初始化GPIOB AIN1=0,AIN2=0;BIN1=0,BIN1=0;
}

通过设置AIN进行轮子的正转和反转。

相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...