Bootstrap

MSPM0G3507(三十六)——超声波PID控制小车固定距离

效果图:

波形图软件是VOFA,B站有教程 ,虽然有缺点但是非常简单。

视频效果:

PID控制距离

之前发过只有超声波测距的代码,MSPM0G3507(三十二)——超声波模块移植代码-CSDN博客

 SYSCFG配置:

 ultrasonic_two.c

#include "ti_msp_dl_config.h"
#include "Delay_two.h"
#include "motor_two.h"
int distance=0;
int overcount=0;      //记录定时器溢出次数  
int  Senor_Using();
extern int MOTO1,MOTO2;
int left_pwm=0;
    int right_pwm=0;
//PID控制距离      (速度环)             第二题的PID
int Senor_control_PID(int true_distance,int Target_distance)
{ 	
	 float Position_KP=40,Position_KI=0.2,Position_KD=1.2;
	 static float Bias,Pwm,Integral_bias,Last_Bias;
	 Bias=Target_distance-true_distance;                                  //计算偏差
	 Integral_bias+=Bias;	                                 //求出偏差的积分
	 Pwm=-(Position_KP*Bias+Position_KI*Integral_bias+Position_KD*(Bias-Last_Bias));       //位置式PID控制器
	 Last_Bias=Bias;                                       //保存上一次偏差 
	 return Pwm;                                           //增量输出


}


void Senor_control()
{
    
    distance=Senor_Using();
   
    left_pwm= Senor_control_PID(distance,15);;
    right_pwm= Senor_control_PID(distance,15);;
MOTO1=left_pwm;
MOTO2= right_pwm;

    Limit(&MOTO1,&MOTO2);	//速度限幅
    Load(MOTO1,MOTO2);		 //加载到电机上。

}



//测距函数
int  Senor_Using() 
{
		unsigned int sum=0;
		unsigned int tim;
		unsigned int i=0;
		unsigned int length;
		int cnt_i=0;
		while(i!=3)        
		{
			DL_GPIO_setPins( ultrasonic_Port_PORT ,ultrasonic_Port_TRIG_Pin_PIN );                     //TRIG=1;              //给发送端高电平
			delay_us(20);    
			 DL_GPIO_clearPins(ultrasonic_Port_PORT ,ultrasonic_Port_TRIG_Pin_PIN );               //TRIG=0;              //给发送端低电平
			cnt_i=0;

          //DL_GPIO_readPins(xunji_PORT_PIN1_PORT                 , xunji_PORT_PIN1_PIN       )==xunji_PORT_PIN1_PIN
			while(DL_GPIO_readPins(ultrasonic_Port_PORT,ultrasonic_Port_MCHO_Pin_PIN)!=ultrasonic_Port_MCHO_Pin_PIN)    //当接收端为0,一直循环      while(ECHO==0)
			{
				cnt_i++;
				delay_us(1);
				if(cnt_i>300)
				{	
                                             
                      DL_GPIO_setPins( ultrasonic_Port_PORT ,ultrasonic_Port_TRIG_Pin_PIN );        // TRIG=1;        发送端给高电平  
					delay_us(20);


					 DL_GPIO_clearPins(ultrasonic_Port_PORT ,ultrasonic_Port_TRIG_Pin_PIN );                //TRIG=0;    发送端给低电平
                    
                    cnt_i=0;          
				}
			} 

                //跳出循环说明已经接收到信号,开启定时器记录时间
			DL_Timer_startCounter(TIMER_ultrasonic_INST    );     //  TIM_Cmd(TIM3,ENABLE);      使能定时器                                         
			
			i+=1;                     
			
			while(DL_GPIO_readPins(ultrasonic_Port_PORT,ultrasonic_Port_MCHO_Pin_PIN)==ultrasonic_Port_MCHO_Pin_PIN)	          //这里是知道信号结束,等待定时器计时      while(ECHO==1);	     
            {

            }



			 DL_Timer_stopCounter(TIMER_ultrasonic_INST) ;                  //TIM_Cmd(TIM3,DISABLE);         失能定时器                     
			
			 tim=DL_Timer_getTimerCount(TIMER_ultrasonic_INST) ;                  //tim=TIM_GetCounter(TIM3);         得到时计单元个数
			length=(tim*50)/58.0;                                               //微秒计算法求距离
			sum=length+sum;
			DL_Timer_setTimerCount(TIMER_ultrasonic_INST,0) ;                          //TIM3->CNT=0;     将计数值清零
			overcount=0;                                        //一般来说没有超过一个定时器周期该值不需要调用,一直给0即可
			//delay_ms(10);
		}
		length=sum/3;                                           //三次作为平均值
		return length; 
}

//测距定时器中断服务函数
void TIMER_ultrasonic_INST_IRQHandler (void)
{
        switch (DL_TimerA_getPendingInterrupt(TIMER_ultrasonic_INST))
    {
        case DL_TIMER_IIDX_ZERO:
                overcount++;




            break;
        default:
            break;
    }




}














ultrasonic_two.h

#ifndef __ultrasonic_two_H
#define	__ultrasonic_two_H




#include "ti_msp_dl_config.h"

int Senor_Using() ;
void TIMER_ultrasonic_INST_IRQHandler (void);
int Senor_control_PID(int true_distance,int Target_distance);
void Senor_control();

#endif

主函数中while循环调用  Senor_control();即可

这里只列出了超声波的所有代码

有些函数没有列出来,大家可以自己给他加上去,就是驱动电机的程序,非常简单。比如limit和load 一个是速度限幅一个是给电机加载PWM,每个人有每个人的写法,实在不会在评论区回复就行。

;