专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
STM32
带电位器的直流电机控制位置
2019-07-21 00:25
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
STM32/STM8
3579
10
1115
现有一个带电位器的电机,将采集到的AD值经过PID计算后更新PWM,想要实现精准控制位置(转过的角度),但是调试时一直正反来回转,不像PID控制电机转速那样可以监测到收敛的速度曲线,而是一直震荡的AD值曲线,调了很久PID都不行。请问下大家是怎么调试的,求助,为谢!
友情提示:
此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
10条回答
StayHungry123
2019-07-21 10:25
//PID3初始化参数
pid3.errorSumDownLim = -200; //偏差和下限
pid3.errorSumUpLim = 200; //偏差和上限
pid3.PIDoutDownLim = -80; //PID输出下限(即PWM占空比)
pid3.PIDoutUpLim = 80; //PID输出上限
pid3.errorUpLim = 200; //偏差上限
pid3.errorDownLim = -200; //偏差下限
pid3.delErrorUpLim = 300; //偏差之差上限
pid3.delErrorDownLim = -300; //偏差之差下限
pid3.TargetVal=2000;
pid3.kp=0.2; //先开始调P参数,所以将Ki Kd都置0了
pid3.ki=0;
pid3.kd=0;
void PID3_Calc(void)
{
pid3.error = pid3.TargetVal - pid3.NowVal; //偏差 = 设定 - 当前
if(pid3.error > pid3.errorUpLim) //误差限幅
pid3.error = pid3.errorUpLim;
else if(pid3.error < pid3.errorDownLim)
pid3.error = pid3.errorDownLim;
pid3.errorSum += pid3.error; //偏差求和
if(pid3.errorSum > pid3.errorSumUpLim) //偏差和限幅
pid3.errorSum = pid3.errorSumUpLim;
else if(pid3.errorSum < pid3.errorSumDownLim)
pid3.errorSum = pid3.errorSumDownLim;
pid3.delError = pid3.error - pid3.error1; //偏差微分
pid3.error1 = pid3.error;
if(pid3.delError > pid3.delErrorUpLim) //偏差微分限幅
pid3.delError = pid3.delErrorUpLim;
else if(pid3.delError < pid3.delErrorDownLim)
pid3.delError = pid3.delErrorDownLim;
pid3.Pout = pid3.kp * pid3.error; //比例输出
pid3.Iout = pid3.ki * pid3.errorSum; //积分输出
pid3.Dout = pid3.kd * pid3.delError; //微分输出
pid3.PIDout = pid3.Pout + pid3.Iout+ pid3.Dout; // PID输出
if(pid3.PIDout > pid3.PIDoutUpLim) //PID输出限幅
pid3.PIDout = pid3.PIDoutUpLim;
else if(pid3.PIDout < pid3.PIDoutDownLim)
pid3.PIDout = pid3.PIDoutDownLim;
}
在MAIN()函数中
if(pid3_flag==1) //PID控制标志位 ,每0.1S进定时器中断将pid3_flag置1
{
ADCVAL=Get_Adc_Average(ADC_Channel_1,5);
pid3.NowVal=ADCVAL;
PID3_Calc();
PwmValue3=pid3.PIDout;
pid3_flag=0;
}
加载中...
查看其它10个回答
一周热门
更多
>
相关问题
STM32F4上I2C(在PROTEUS中模拟)调试不通的问题
6 个回答
芯片供应紧张,准备换个MCU,MM32L系列替换STM32L系列的怎么样?
7 个回答
STM32同时使用两个串口进行数据收发时数据丢包的问题
5 个回答
STM32F103串口通信死机问题
4 个回答
STM32WLE5CC连接SX1268在LoRa模式下能与 SX1278互通吗?
2 个回答
相关文章
ST公司第一款无线低功耗单片机模块有效提高物联网设计生产效率
0个评论
如何实现对单片机寄存器的访问
0个评论
通过USB用STM32片内自带Bootloader下载程序及注意事项
0个评论
欲练此功必先自宫之STM32汇编启动,放慢是为了更好的前行
0个评论
×
关闭
采纳回答
向帮助了您的知道网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
STM32
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
×
付费偷看金额在0.1-10元之间
确定
×
关闭
您已邀请
0
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
pid3.errorSumDownLim = -200; //偏差和下限
pid3.errorSumUpLim = 200; //偏差和上限
pid3.PIDoutDownLim = -80; //PID输出下限(即PWM占空比)
pid3.PIDoutUpLim = 80; //PID输出上限
pid3.errorUpLim = 200; //偏差上限
pid3.errorDownLim = -200; //偏差下限
pid3.delErrorUpLim = 300; //偏差之差上限
pid3.delErrorDownLim = -300; //偏差之差下限
pid3.TargetVal=2000;
pid3.kp=0.2; //先开始调P参数,所以将Ki Kd都置0了
pid3.ki=0;
pid3.kd=0;
void PID3_Calc(void)
{
pid3.error = pid3.TargetVal - pid3.NowVal; //偏差 = 设定 - 当前
if(pid3.error > pid3.errorUpLim) //误差限幅
pid3.error = pid3.errorUpLim;
else if(pid3.error < pid3.errorDownLim)
pid3.error = pid3.errorDownLim;
pid3.errorSum += pid3.error; //偏差求和
if(pid3.errorSum > pid3.errorSumUpLim) //偏差和限幅
pid3.errorSum = pid3.errorSumUpLim;
else if(pid3.errorSum < pid3.errorSumDownLim)
pid3.errorSum = pid3.errorSumDownLim;
pid3.delError = pid3.error - pid3.error1; //偏差微分
pid3.error1 = pid3.error;
if(pid3.delError > pid3.delErrorUpLim) //偏差微分限幅
pid3.delError = pid3.delErrorUpLim;
else if(pid3.delError < pid3.delErrorDownLim)
pid3.delError = pid3.delErrorDownLim;
pid3.Pout = pid3.kp * pid3.error; //比例输出
pid3.Iout = pid3.ki * pid3.errorSum; //积分输出
pid3.Dout = pid3.kd * pid3.delError; //微分输出
pid3.PIDout = pid3.Pout + pid3.Iout+ pid3.Dout; // PID输出
if(pid3.PIDout > pid3.PIDoutUpLim) //PID输出限幅
pid3.PIDout = pid3.PIDoutUpLim;
else if(pid3.PIDout < pid3.PIDoutDownLim)
pid3.PIDout = pid3.PIDoutDownLim;
}
在MAIN()函数中
if(pid3_flag==1) //PID控制标志位 ,每0.1S进定时器中断将pid3_flag置1
{
ADCVAL=Get_Adc_Average(ADC_Channel_1,5);
pid3.NowVal=ADCVAL;
PID3_Calc();
PwmValue3=pid3.PIDout;
pid3_flag=0;
}
一周热门 更多>