效果圖:
波形圖軟件是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_PINwhile(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*100)/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,每個人有每個人的寫法,實在不會在評論區回復就行。