医院网站源码asp,wordpress 函数教程,如何做网站哪个站推广,下载企查查企业查询使用芯片#xff1a;STM32 F103 C8T6
今日继续我的二路平衡小车开发之路#xff0c;今日编写的是二轮平衡小车的PID速度环#xff0c;我准备了纸飞机串口助手软件来辅助测试调节PID。
本文主要贴代码#xff0c;之前的文章都有原理#xff0c;代码中相应初始化驱动部分也…使用芯片STM32 F103 C8T6
今日继续我的二路平衡小车开发之路今日编写的是二轮平衡小车的PID速度环我准备了纸飞机串口助手软件来辅助测试调节PID。
本文主要贴代码之前的文章都有原理代码中相应初始化驱动部分也有注释~~
文章提供源码解释以及工程下载测试效果视频。 PID基础概念 这里简单介绍一下PID算法是反馈调节的算法只需输入期望值与传感器反馈值即可实现自动调节电机PWM控制速度始终在期望值附近即反馈小了就加占空比反馈大了就减占空比但却不是简单的加减运算。
原理之前写过这里直接贴出文章连接 PID输出反馈回路调控算法原理_NULL指向我的博客-CSDN博客 编码器测速逻辑
此处贴出函数相关逻辑在之前的文章讲过 MSP432自主开发笔记1:编码器测速_外部中断捕获法测速\测正反转_msp432编码器_NULL指向我的博客-CSDN博客 对于速度单位的理解与计算有各种各样有喜欢算到 cm/s m / s (rad / second )等等需要通过不同电机转速需求来选定。
这里我是用的电机减速比比较大扭矩与载重大但因此转速就慢因此我采用每25ms采样的脉冲数作为速度来比较使速度环闭合。
//定时器3中断服务程序 (编码器捕获脉冲数)
void TIM3_IRQHandler(void)
{ if(TIM_GetITStatus(TIM3, TIM_IT_CC1)) //通道1发生捕获事件{ Wheel[2].CAPTURE;TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);} //每次进入中断都要清空中断标志否则主函数将无法正常执行if(TIM_GetITStatus(TIM3, TIM_IT_CC2)) //通道2发生捕获事件{Wheel[2].CAPTURE;TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);} //每次进入中断都要清空中断标志否则主函数将无法正常执行 if(TIM_GetITStatus(TIM3, TIM_IT_CC3)) //通道3发生捕获事件{Wheel[1].CAPTURE;TIM_ClearITPendingBit(TIM3, TIM_IT_CC3);} //每次进入中断都要清空中断标志否则主函数将无法正常执行 if(TIM_GetITStatus(TIM3, TIM_IT_CC4)) //通道4发生捕获事件{Wheel[1].CAPTURE;TIM_ClearITPendingBit(TIM3, TIM_IT_CC4);} //每次进入中断都要清空中断标志否则主函数将无法正常执行
}void calculate_speed(void)
{uint16_t tt;tt50;if(SPEED_flag1){SPEED_flag0;Wheel[1].SPEEDWheel[1].CAPTURE;Wheel[2].SPEEDWheel[2].CAPTURE;// printf(V1%d,V2%d\r\n,Wheel[1].SPEED,Wheel[2].SPEED);printf(P1%d,P2%d\r\n,Wheel[1].PWM_DIV,Wheel[2].PWM_DIV);PRINT(plotter, %d, %d, %d,Wheel[1].SPEED,Wheel[2].SPEED,tt); PID_guide_peed(tt,tt);set_wheels(Wheel[1].PWM_DIV,Wheel[2].PWM_DIV,1,1);Wheel[1].CAPTURE0; Wheel[2].CAPTURE0;}
} PID算法贴出 参数需要自己调玄学调参......
#include PID.hPID_TYPE suduhuan1;
PID_TYPE suduhuan2;//PID 1~4号轮设置期望速度
void PID_guide_peed(uint16_t w1,uint16_t w2)
{Pid_increment_Cal(suduhuan1,w1,Wheel[1].SPEED);Pid_increment_Cal(suduhuan2,w2,Wheel[2].SPEED); Wheel[1].PWM_DIVsuduhuan1.OutPut;Wheel[2].PWM_DIVsuduhuan2.OutPut;
}PID_结构体 target_目标 measure_当前值
void Pid_increment_Cal(PID_TYPE *PID, int target, int measure)
{PID-Error target - measure; // 误差PID-Pout PID-P * (PID-Error - PID-PreError); // 比例控制PID-Iout PID-I * PID-Error; // 积分控制PID-Dout PID-D * (PID-Error - 2 * PID-PreError PID-PrePreError); // 微分控制// 比例 积分 微分总控制if (PID-Iout PID-Irang) // 积分限幅PID-Iout PID-Irang;if (PID-Iout -PID-Irang) // 积分限幅PID-Iout -PID-Irang;PID-OutPut PID-Pout PID-Iout PID-Dout;PID-PrePreError PID-PreError; // 记忆e(k-2)PID-PreError PID-Error; // 记忆e(k-1)}void PidParameter_init(void)
{suduhuan1.P 38;suduhuan1.I18;suduhuan1.D0;suduhuan1.PreError0;suduhuan1.PrePreError0;suduhuan1.Irang12;suduhuan1.OutPut0;suduhuan2.P 38;suduhuan2.I18;suduhuan2.D0;suduhuan2.PreError0;suduhuan2.PrePreError0;suduhuan2.Irang12;suduhuan2.OutPut0;
}#ifndef _PID_H_
#define _PID_H_#include headfire.htypedef struct PID
{int P; //参数int I;int D;float Error; //比例项e(k)float Integral; //积分项int Differ; //微分项int PreError; //e(k-1)int PrePreError;//e(k-2)float Ilimit;float Irang;int Pout;int Iout;int Dout;int OutPut;uint8_t Ilimit_flag; //积分分离
}PID_TYPE;extern PID_TYPE suduhuan1;
extern PID_TYPE suduhuan2;PID_结构体 target_目标 measure_当前值
void Pid_increment_Cal(PID_TYPE *PID, int target, int measure);
void PidParameter_init(void); //PID参数初始化 //PID 设置期望速度
void PID_guide_peed(uint16_t w1,uint16_t w2);#endif