一.控制原理
你要想掌握好这个东西,首先必须得明白它其中的原理。首先一点,你要明白编码器返还的数据是什么?能够怎么用?
常用的编码器:两相编码器由 A 相和 B 相组成,相位差为 90 度。当旋转方向为顺时针时,A 相先变化,然后 B 相变化;当旋转方向为逆时针时,B 相先变化,然后 A 相变化。通过检测相位差变化,可以确定旋转的方向。
编码器的两个输入引脚,就是每个定时器的CH1和CH2引脚,最终的实验现象,编码器有两个输出,一个是A相,一个是B相,然后接入到STM32,定时器的编码器接口,编码器的接口自动控制定时器时基单元中的CNT计数器,进行自增或自减。比如初始化之后,CNT初始值为0,然后编码器右转,CNT就++,右转产生一个脉冲,CNT就加一次,比如右转产生10个脉冲后,停下来,那么这个过程CNT就由0自增到10,停下来,编码器左转,CNT就–,左转产生一个脉冲,CNT就自减一次, 比如编码器再左转产生5个脉冲,那CNT就在原来10的基础上自减5,停下来。
编码器接口,其实就相当于是一个带有方向控制的外部时钟,同时控制着CNT的计数时钟和计数方向,这样CNT的值就表示了编码器的位置。如果我们每隔一段时间取一次编码器的值,再把CNT清零,那么每次取出来的值就表示了编码器的速度。
编码器测速实际上就是测频法测正交脉冲的频率,CNT计次,然后每隔一段时间取一次计次,这就是测频法的思路。编码器计次能根据旋转方向,不仅能自增计次还能自减计次,是一个带方向的测速。此处编码器计数的原理的说明来自于:https://blog.csdn.net/qq_48361010/article/details/135413772
这里就相当于每隔10ms查看一下记录的脉冲数,让后拿出来与你自己设置的目标速度做比较,偏大减小pwm,偏小增大pwm。也就是我们用的pid处理(差分,微分,积分)然后你需要什么速度就可以增加相对应的比例,最终达到一个动态平衡的状态。
二.具体代码
1编码器的读取,记录脉冲数
#include "encoder.h"
#include "stm32f4xx.h"
#include "led.h"
//B6 B7 A0 A1
void Encoder1_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP ;//Íâ½ÓÄ£¿éĬÈϵçƽ
GPIO_InitStruct.GPIO_Speed=GPIO_High_Speed ;
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_TIM5);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource1,GPIO_AF_TIM5);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period=65535-1;//arr
TIM_TimeBaseInitStructure.TIM_Prescaler=0;
TIM_TimeBaseInit(TIM5,&TIM_TimeBaseInitStructure);//³õʼ»¯TIM3ʱ»ùµ¥Ôª
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICStructInit(&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel= TIM_Channel_1 ;
TIM_ICInitStructure.TIM_ICFilter= 0x0 ;
TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising ;
//²»´ú±íÉÏÉýÑØÓÐЧ£¬±àÂëÆ÷½Ó¿ÚʼÖÕ¶¼ÊÇÉÏÉýÑØϽµÑØÓÐЧ
//´Ë´¦ÉÏÉýÑزÎÊý´ú±í¸ßµÍµçƽ¼«ÐÔ²»·´×ª//ÉÏÉýÑؼ´Îª·µÏò£¬Ï½µÑؼ´Îª²»·´Ïò
//TIM_ICInitStructure.TIM_ICPrescaler= TIM_ICPSC_DIV1 ;//²»·ÖƵ
//TIM_ICInitStructure.TIM_ICSelection= TIM_ICSelection_DirectTI ;
//Ö»ÐèÅäÖÃͨµÀÓ뼫ÐÔ
TIM_ICInit(TIM5,&TIM_ICInitStructure);//³õʼ»¯ÊäÈ벶»ñµ¥Ôª
TIM_ICInitStructure.TIM_Channel= TIM_Channel_2 ;
TIM_ICInitStructure.TIM_ICFilter= 0x0 ;
TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Falling ;
TIM_ICInit(TIM5,&TIM_ICInitStructure);//³õʼ»¯Í¨µÀ¶þ
TIM_EncoderInterfaceConfig(TIM5,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising );
//TIM_ICPolarity_Rising¼´Îª²»·´Ïò£¬falling¼´Îª·µÏò
TIM_Cmd(TIM5,ENABLE);
}
void Encoder2_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB,&GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource6 ,GPIO_AF_TIM4);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource7 ,GPIO_AF_TIM4);
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //
TIM_TimeBaseInitStructure.TIM_Period=65536-1;
TIM_TimeBaseInitStructure.TIM_Prescaler=1-1;
TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);
TIM_ICInitTypeDef TIM_ICInitStructure; //¶¨Òå½á¹¹Ìå±äÁ¿
TIM_ICStructInit(&TIM_ICInitStructure); //½á¹¹Ì帽³õʼֵ
TIM_ICInitStructure.TIM_Channel=TIM_Channel_1;
TIM_ICInitStructure.TIM_ICFilter=0x0;
TIM_ICInit(TIM4,&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel=TIM_Channel_2;
TIM_ICInitStructure.TIM_ICFilter=0x0;
TIM_ICInit(TIM4,&TIM_ICInitStructure);
TIM_EncoderInterfaceConfig(TIM4,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);
TIM_Cmd(TIM4,ENABLE);
}
int16_t Encoder1_Get(void)
{
int16_t Temp1;
Temp1=TIM_GetCounter(TIM5);
TIM_SetCounter(TIM5,0);
return Temp1;
}
int16_t Encoder2_Get(void)
{
int16_t Temp2;
Temp2=TIM_GetCounter(TIM4);
TIM_SetCounter(TIM4,0);
return Temp2;
}
2. 定时获取编码器中的实际速度
#include "timer.h"
#include "usart.h"
#include "sys.h"
#include "delay.h"
#include "pwm.h"
#include "oled.h"
#include "myiic.h"
#include "mpu6050.h"
#include "inv_mpu.h"
#include "inv_mpu_dmp_motion_driver.h"
#include "encoder.h"
#include "serve.h"
#include "control.h"
//#define ARR 120-1
//#define PRESCARE 42-1
#define SPEED_Y 60
#define SPEED_Z 80
#define NUM 10
u16 ab[460];
u32 a=0,t=0,TEXT_LENTH=0,SIZE=0;
int adcvalue;
int shuchu;
int shuru;
extern int Bluetooth_data;
float pitch,roll,yaw; //Å·À½Ç ¸©Ñö½Ç¡¢ºá¹ö½Ç¡¢Æ«º½½Ç
short aacx,aacy,aacz; //¼ÓËٶȴ«¸ÐÆ÷ÔʼÊý¾Ý
short gyrox,gyroy,gyroz; //ÍÓÂÝÒÇÔʼÊý¾Ý
float PWM_out;
int Vertical_out,Velocity_out,Turn_out;
//
int16_t speedleft;
int16_t speedright;
void TIM3_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); ///ʹÄÜTIM3ʱÖÓ
TIM_TimeBaseInitStructure.TIM_Period = arr; //×Ô¶¯ÖØ×°ÔØÖµ
TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //¶¨Ê±Æ÷·ÖƵ
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //ÏòÉϼÆÊýģʽ
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//³õʼ»¯TIM3
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //ÔÊÐí¶¨Ê±Æ÷3¸üÐÂÖжÏ
TIM_Cmd(TIM3,ENABLE); //ʹÄܶ¨Ê±Æ÷3
NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //¶¨Ê±Æ÷3ÖжÏ
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x02; //ÇÀÕ¼ÓÅÏȼ¶1
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //×ÓÓÅÏȼ¶3
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
float Target_Speed=0; // ÆÚÍûËٶȡ£---¶þ´Î¿ª·¢½Ó¿Ú£¬ÓÃÓÚ¿ØÖÆС³µÇ°½øºóÍ˼°ÆäËٶȡ£
float Turn_Speed=0; // ×óÓÒÒ£¿ØÊý¾Ý
extern float Med_Angle;
u8 Fore,Back,Left,Right;
extern float Turn_Kp,Turn_Kd;
void TIM3_IRQHandler(void) //
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //Òç³öÖжÏ
{
while(mpu_dmp_get_data(&pitch,&roll,&yaw)!=0)
{}
MPU_Get_Accelerometer(&aacx,&aacy,&aacz); //µÃµ½¼ÓËٶȴ«¸ÐÆ÷Êý¾Ý
MPU_Get_Gyroscope(&gyrox,&gyroy,&gyroz); //µÃµ½ÍÓÂÝÒÇÊý¾Ý
OLED_ShowString(0,0,"pitch:",12);
OLED_ShowString(0,20,"roll:",12);
OLED_ShowString(0,40,"yaw:",12);
OLED_ShowFloatNumber(40,0,pitch,12);
// OLED_ShowFloatNumber(40,40,Back,12);
OLED_ShowNum(40,40,Back,3,12);
OLED_Refresh_Gram();
speedleft=Encoder2_Get(); //µÃµ½×óÓÒÂÖµÄËÙ¶È
speedright=Encoder1_Get();
if((Fore==0)&&(Back==0))Target_Speed=0; // δ½ÓÊÕµ½Ç°½øºóÍËÖ¸Áî->ËÙ¶ÈÇåÁ㣬ÎÈÔÚÔµØ
if(Fore==1)Target_Speed=30; // Ç°½ø±ê־λΪ1->ÐèҪǰ½ø
if(Back==1)Target_Speed=-30; // ºóÍ˱ê־λΪ1->ÐèÒªºóÍË
Target_Speed=Target_Speed>SPEED_Y?SPEED_Y:(Target_Speed<-SPEED_Y?(-SPEED_Y):Target_Speed); // ÏÞ·ù
/*×óÓÒ*/
if((Left==0)&&(Right==0))Turn_Speed=0;
if(Left==1)Turn_Speed=100; // ×óת±ê־λΪ1->ÐèÒª×óת
if(Right==1)Turn_Speed=-100; // ÓÒת±ê־λΪ1->ÐèÒªÓÒת
Turn_Speed=Turn_Speed>SPEED_Z?SPEED_Z:(Turn_Speed<-SPEED_Z?(-SPEED_Z):Turn_Speed); // ÏÞ·ù
/*תÏòÔ¼Êø*/
if((Left==0)&&(Right==0))Turn_Kd=-2.4; // ÈôÎÞ×óÓÒתÏòÖ¸ÁÔò¿ªÆôתÏòÔ¼Êø
else if((Left==1)||(Right==1))Turn_Kd=0; // Èô×óÓÒתÏòÖ¸Áî½ÓÊÕµ½£¬ÔòÈ¥µôתÏòÔ¼Êø
Velocity_out=Velocity(Target_Speed,speedleft,speedright); //ËÙ¶È
Vertical_out=Vertical(2.8,pitch,gyroy) ; //Ö±Á¢»·
Turn_out=Turn(gyroz,Turn_Speed) ;
PWM_out=Vertical_out +Velocity_out;
Set_Pwm(PWM_out+Turn_out+990,PWM_out-Turn_out+990); //800 900
}
TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //Çå³ýÖжϱê־λ
}
3pid的调控
#include "control.h"
float Med_Angle=0; // »úеÖÐÖµ£¬ÄÜʹµÃС³µÕæÕýƽºâסµÄ½Ç¶È
float
Vertical_Kp=415
, // 800 4 480,2.4 520,3.6
Vertical_Kd=4
; // Ö±Á¢»·Kp¡¢Kd
float
Velocity_Kp=515
,
Velocity_Ki=7
; // ËٶȻ·Kp¡¢Kd
float
Turn_Kd=-2.4,
Turn_Kp=20;
/*****************
Ö±Á¢»·PD¿ØÖÆÆ÷£ºKp*Ek+Kd*Ek_D
Èë¿Ú£ºMed:»úеÖÐÖµ(ÆÚÍû½Ç¶È)£¬Angle:Õæʵ½Ç¶È£¬gyro_Y:Õæʵ½ÇËÙ¶È
³ö¿Ú£ºÖ±Á¢»·Êä³ö
******************/
int Vertical(float Med,float Angle,float gyro_Y)
{
int PWM_out;
PWM_out = Vertical_Kp*(Angle-Med)+Vertical_Kd*(gyro_Y-0);
return PWM_out;
}
/*****************
ËٶȻ·PI¿ØÖÆÆ÷£ºKp*Ek+Ki*Ek_S(Ek_S£ºÆ«²îµÄ»ý·Ö)
******************/
int Velocity(int Target,int speedleft,int speedright)
{
//¶¨Ò徲̬±äÁ¿£¬±£´æÔÚ¾²Ì¬´æ´¢Æ÷£¬Ê¹µÃ±äÁ¿²»¶ªµô
static int PWM_out,Encoder_Err,Encoder_S,EnC_Err_Lowout,EnC_Err_Lowout_last;
float a=0.7;
//1.¼ÆËãËÙ¶ÈÆ«²î
//ÉáÈ¥Îó²î--Äܹ»ÈÃËÙ¶ÈΪ0µÄ½Ç¶È£¬¾ÍÊÇ»úеÖÐÖµ
Encoder_Err = ((speedleft+speedright)-Target);
//2.¶ÔËÙ¶ÈÎó²î½øÐеÍͨÂ˲¨
//Low_out=(1-a)*Ek+a*Low_out_Last
EnC_Err_Lowout = (1-a)*Encoder_Err+a*EnC_Err_Lowout_last; //ʹ²¨Ðθü¼Óƽ»¬£¬Â˳ý¸ßƵ¸ÉÈÅ£¬·ÀÖ¹ËÙ¶ÈÍ»±ä
//3.¶ÔËÙ¶ÈÆ«²î»ý·Ö³öλÒÆ
Encoder_S += EnC_Err_Lowout;
//4.»ý·ÖÏÞ·ù
Encoder_S=Encoder_S>10000?10000 : (Encoder_S<(-10000)?(-10000) : Encoder_S);
//5.ËٶȻ·¿ØÖÆÊä³ö
PWM_out=Velocity_Kp*EnC_Err_Lowout+Velocity_Ki*Encoder_S;
return PWM_out;
}
//תÏò»»£¬¿ØÖÆÁ½¸öÂÖ×ÓÕý·´×ª
/*****************
תÏò»·£ºÏµÊý*ZÖá½ÇËÙ¶È
******************/
int Turn(int gyro_Z,int RC)
{
int PWM_out;
// ²»ÊÇÑϸñµÄPD¿ØÖÆÆ÷£¬KdÕë¶ÔµÄÊÇתÏò»·µÄÔ¼Êø£¬µ«KpÕë¶ÔµÄÊÇÒ£¿ØµÄתÏò
PWM_out = Turn_Kd*gyro_Z+Turn_Kp*RC;
return PWM_out;
}
4.pwm的输出
#include "pwm.h"
#include "led.h"
#include "usart.h"
//TIM14 PWM²¿·Ö³õʼ»¯
//PWMÊä³ö³õʼ»¯
//arr£º×Ô¶¯ÖØ×°Öµ
//psc£ºÊ±ÖÓÔ¤·ÖƵÊý
void TIM14_PWM_Init(u32 arr,u32 psc) //
{
//´Ë²¿·ÖÐèÊÖ¶¯ÐÞ¸ÄIO¿ÚÉèÖÃ
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE); //TIM14ʱÖÓʹÄÜ
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); //ʹÄÜPORTFʱÖÓ
GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14); //GPIOF9¸´ÓÃΪ¶¨Ê±Æ÷14
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //GPIOF9
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //¸´Óù¦ÄÜ
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //ËÙ¶È100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //ÍÆÍ츴ÓÃÊä³ö
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //ÉÏÀ
GPIO_Init(GPIOF,&GPIO_InitStructure); //³õʼ»¯PF9
TIM_TimeBaseStructure.TIM_Prescaler=psc; //¶¨Ê±Æ÷·ÖƵ
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //ÏòÉϼÆÊýģʽ
TIM_TimeBaseStructure.TIM_Period=arr; //×Ô¶¯ÖØ×°ÔØÖµ
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM14,&TIM_TimeBaseStructure);//³õʼ»¯¶¨Ê±Æ÷14
//³õʼ»¯TIM14 Channel1 PWMģʽ
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //Ñ¡Ôñ¶¨Ê±Æ÷ģʽ:TIMÂö³å¿í¶Èµ÷ÖÆģʽ2 ͨµÀ1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //±È½ÏÊä³öʹÄÜ
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //Êä³ö¼«ÐÔ:TIMÊä³ö±È½Ï¼«ÐÔ¸ß
TIM_OC1Init(TIM14, &TIM_OCInitStructure); //¸ù¾ÝTÖ¸¶¨µÄ²ÎÊý³õʼ»¯Íâ333333333333333ÉèTIM1 4OC1
TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable); //ʹÄÜTIM14ÔÚCCR1ÉϵÄԤװÔؼĴæÆ÷
TIM_ARRPreloadConfig(TIM14,ENABLE);//ARPEʹÄÜ
TIM_Cmd(TIM14, ENABLE); //ʹÄÜTIM14
}
void TIM13_PWM_Init(u32 arr,u32 psc)
{
//´Ë²¿·ÖÐèÊÖ¶¯ÐÞ¸ÄIO¿ÚÉèÖÃ
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM13,ENABLE); //TIM13ʱÖÓʹÄÜ
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); //ʹÄÜPORTFʱÖÓ
GPIO_PinAFConfig(GPIOF,GPIO_PinSource8,GPIO_AF_TIM13); //GPIOF8¸´ÓÃΪ¶¨Ê±Æ÷13
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //GPIOF8
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //¸´Óù¦ÄÜ
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //ËÙ¶È100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //ÍÆÍ츴ÓÃÊä³ö
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //ÉÏÀ
GPIO_Init(GPIOF,&GPIO_InitStructure); //³õʼ»¯PF8
TIM_TimeBaseStructure.TIM_Prescaler=psc; //¶¨Ê±Æ÷·ÖƵ
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //ÏòÉϼÆÊýģʽ
TIM_TimeBaseStructure.TIM_Period=arr; //×Ô¶¯ÖØ×°ÔØÖµ
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM13,&TIM_TimeBaseStructure);//³õʼ»¯¶¨Ê±Æ÷13
//³õʼ»¯TIM13 Channel1 PWMģʽ
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //Ñ¡Ôñ¶¨Ê±Æ÷ģʽ:TIMÂö³å¿í¶Èµ÷ÖÆģʽ2 ͨµÀ1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //±È½ÏÊä³öʹÄÜ
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //Êä³ö¼«ÐÔ:TIMÊä³ö±È½Ï¼«ÐÔ¸ß
TIM_OC1Init(TIM13, &TIM_OCInitStructure); //¸ù¾ÝTÖ¸¶¨µÄ²ÎÊý³õʼ»¯Íâ333333333333333ÉèTIM1 4OC1
TIM_OC1PreloadConfig(TIM13, TIM_OCPreload_Enable); //ʹÄÜTIM13ÔÚCCR1ÉϵÄԤװÔؼĴæÆ÷
TIM_ARRPreloadConfig(TIM13,ENABLE);//ARPEʹÄÜ
TIM_Cmd(TIM13, ENABLE); //ʹÄÜTIM13
}
5.电机正反转的控制和初始化
#include "serve.h"
/***************************************************/
/*IN1-PB6
IN2-PB7
IN3-PD2
IN4-PD3*/
int motorLeft = 0;
int motorRight = 0;
void SERVE_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//ʹÄÜGPIOFʱÖÓ
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
//GPIOF9,F10³õʼ»¯ÉèÖÃ
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//ÆÕͨÊä³öģʽ
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//ÍÆÍìÊä³ö
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//ÉÏÀ
GPIO_Init(GPIOB, &GPIO_InitStructure);//³õʼ»¯
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//ÆÕͨÊä³öģʽ
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//ÍÆÍìÊä³ö
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//
GPIO_Init(GPIOD, &GPIO_InitStructure);//³õʼ»¯
}
//È¡¾ø¶ÔÖµ
int myabs(int a)
{
int temp;
if(a<0)
temp=-a;
else
temp=a;
return temp;
}
//¸³ÖµPWM
void Set_Pwm(int motorLeft,int motorRight)
{
if(motorLeft>=0)
{
GPIO_SetBits(GPIOB, GPIO_Pin_5);
GPIO_ResetBits(GPIOB, GPIO_Pin_4);
GPIO_SetBits(GPIOD, GPIO_Pin_2);
GPIO_ResetBits(GPIOD, GPIO_Pin_3);
TIM_SetCompare1(TIM14,myabs(motorLeft));
TIM_SetCompare1(TIM13,myabs(motorRight));
}
if(motorLeft<0)
{
GPIO_SetBits(GPIOB, GPIO_Pin_4);
GPIO_ResetBits(GPIOB, GPIO_Pin_5);
GPIO_SetBits(GPIOD, GPIO_Pin_3);
GPIO_ResetBits(GPIOD, GPIO_Pin_2);
TIM_SetCompare1(TIM14,myabs(motorLeft)+300);
TIM_SetCompare1(TIM13,myabs(motorRight)+300);
}
}
三.一些注意的地方
新手在刚开始用用编码器的时候最容易搞错ab项或者左右轮弄反了,然后就就会出现一些比较奇怪的现象。为了防止这种低级错误,在弄的时候就需要一步一步的来。开始首先确定一个轮子ab项也就是通过正反转,以及电机初始化自己规定正转或者反转可以判断其是否接反了。一个轮子确定好了之后然后就如法炮制第二个也就一样的完成了,这样就不会有大的问题。