基于stm32cubeMX的平衡小车HAL库+蓝牙遥控+直立环+速度环+转向环
一、代码工程链接
我的平衡车代码,HAL库,cubeMX配置,主控stm32f103,程序代码容易移植,建议先看完正文
https://download.youkuaiyun.com/download/cubejava/51301223
二、配置部分
我自己在cuebmx所配置的用到的资源:
Keil中的调用控制代码页面
三、平衡小车控制类代码整体框架
以下是平衡小车控制类代码整体框架,我觉得很好,很有学习的必要。向平衡小车之家致敬
主程序
void main(void)
{
Encoder_Left=Read_Encoder(2);//===读取编码器的值
Encoder_Right=Read_Encoder(4);//===读取编码器的值
Balance_Pwm =balance(Angle_Balance,Gyro_Balance);//===平衡PID控制
Velocity_Pwm=velocity(Encoder_Left,Encoder_Right);//===速度环PID控制.记住,速度反馈是正反馈,就是小车快的时候要慢下来就需要再跑快一
Moto1=Balance_Pwm+Velocity_Pwm-Turn_Pwm;//===计算左轮电机最终PWM
Moto2=Balance_Pwm+Velocity_Pwm+Turn_Pwm;//===计算右轮电机最终PWM
Xianfu_Pwm();//===PWM限幅
Set_Pwm(Moto1,Moto2);//===赋值给PWM寄存器
}
平衡环的控制函数如下
int balance(float Angle,float Gyro)
{
float Bias,kp=300,kd=1;
int balance;
Bias=Angle-ZHONGZHI; //===求出平衡的角度中值 和机械相关
balance=kp **Bias+Gyro* *kd; //===计算平衡控制的电机PWM PD控制 kp是P系数 kd是D系数
return balance;
}
速度环的控制函数如下
int velocity(int encoder_left,int encoder_right)
{
static float Velocity,Encoder_Least,Encoder,Movement;
static float Encoder_Integral;
float kp=80,ki=0.4;
//=============速度PI控制器=======================//
Encoder_Least =(encoder_left+encoder_right)-0;//===获取最新速度偏差==测量速度(左右编码器之和)-目标速度(此处为零)
Encoder *= 0.8;//===一阶低通滤波器
Encoder += Encoder_Least*0.2;//===一阶低通滤波器
Encoder_Integral +=Encoder;//===积分出位移 积分时间:10ms
Encoder_Integral=Encoder_Integral-Movement;//===接收遥控器数据,控制前进后退
if(Encoder_Integral>10000) Encoder_Integral=10000;//===积分限幅
if(Encoder_Integral<-10000) Encoder_Integral=-10000;
Velocity=Encoder*kp+Encoder_Integral*ki; //===速度控制
return Velocity;
}
赋值pwm给电机
void Set_Pwm(int moto1,int moto2)
{
if(moto1>0) AIN2=0, AIN1=1;
else AIN2=1, AIN1=0;
PWMA=myabs(moto1);
if(moto2>0) BIN1=0, BIN2=1;
else BIN1=1, BIN2=0;
PWMB=myabs(moto2);
}
运用函数的封装更加简洁。控制电机。
限幅PWM
void Xianfu_Pwm(void)
{
int Amplitude=6900; //===PWM满幅是7200 限制在6900
if(Moto1<-Amplitude) Moto1=-Amplitude;
if(Moto1>Amplitude) Moto1=Amplitude;
if(Moto2<-Amplitude) Moto2=-Amplitude;
if(Moto2>Amplitude) Moto2=Amplitude;
}
异常关闭电机
u8 Turn_Off(float angle, int voltage)
{
u8 temp;
if(angle<-40||angle>40) //===倾角大于40度关闭电机
{
temp=1;
AIN1=0;
AIN2=0;
BIN1=0;
BIN2=0;
}
else
temp=0;
return temp;
}
获取角度函数
void Get_Angle(void)
{
Read_DMP(); //===读取加速度、角速度、倾角
Angle_Balance=-Roll; //===更新平衡倾角
Gyro_Balance=-gyro[0]; //===更新平衡角速度
}
绝对值函数
int myabs(int a)
{
int temp;
if(a<0) temp=-a;
else temp=a;
return temp;
}
感谢平衡小车之家领我们进平衡小车的大门,大家可以参考一下。
手工主控板:
开的主控板:
因为自己也是花费了不少精力才完成的工程,设置了付费,望理解
https://download.youkuaiyun.com/download/cubejava/51301223