电赛模块的准备基于STM32F407的pid控制电机匀速转动(定时器10ms计算一次)利用32自带的编码器模式

一.控制原理

        你要想掌握好这个东西,首先必须得明白它其中的原理。首先一点,你要明白编码器返还的数据是什么?能够怎么用?

        常用的编码器:两相编码器由 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项也就是通过正反转,以及电机初始化自己规定正转或者反转可以判断其是否接反了。一个轮子确定好了之后然后就如法炮制第二个也就一样的完成了,这样就不会有大的问题。
                        

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

电赛张小七

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值