好文档 - 专业文书写作范文服务资料分享网站

PID控制算法的C语言实现(完整版)

天下 分享 时间: 加入收藏 我要投稿 点赞

(注意,我这里讨论的前提是输出控制的是电压,不是PWM方波。PWM输出后要经过滤波整形再输出控制。) 前提条件:

输出电压控制电压范围是0-10V。

给定、反馈、输出电压采样输入电压范围是0-5V(经过运放)。 使用单片机AD为10位AD芯片。

那么10位AD芯片电压采集得到的数据范围就是0-1024。

PWM为 8位可调占空比方波,0对应输出占空比为0的方波,255对应输出占空比100%的方波,127对应输出50%的方波。

比如当前给定是2.5V,反馈电压是1V。(KP,KI,KD等系数略,关于PID算法的整数实现我在前文中有论述如何实现)。 那么经过AD采样 1、给定2.5V对应为 512 2、反馈1V对应为 205

假定经过PID计算得到的UK为400

也就意味着输出电压应当为(400*(UPWM峰值电压))/1024 那么UK对应的PWM占空比是多少呢?

我们知道,UK=1024对应占空比为100,也就是PWM的占空比系数为255。可知,PWM系数 = UK/4;

那么400就应当对应系数 400/4=100。 也就是输出电压=400*10/1024=3.9V

同时,由于采样精度以及PWM输出占空比精度控制的问题,将导致输出电压和期望值不是那么线性,所以,我在项目内加入了输出电压采样的控制。 采样AD输入为0-5V,所以,对于输出0-10V有一个缩小的比例。 输出10V则采样值对应为255 输出5V则采样之对应127 可知,3.9V对应AD结果为97

采样输出电压值,可以针对性的调整一下占空比输出,从而得到误差允许范围内的一个控制输出电压。

同时,经过一些加速控制的手段。可以比较迅速的达到控制的目的。

下文中的UK控制方法是针对增量式PID控制而来做的。 /****************************************************/ void PWMProcess(void) {

uint16 idata temp; uint16 idata UKTemp; temp = 0; UKTemp = 0;

if( Pwm.ChangeFlag_Uint8 != 0 ) //判断是否需要改变占空比 { //是否需要改变占空比和你的被控系统特性有关 Pwm.ChangeFlag_Uint8 = 0;

UKTemp = PID.Uk_Uint16 + SwIn.AddValue_Uint16; //计算UK控制量

//控制量和计算值以及一个开关量有关,我这里的开关量是系统需要的时候叠加在控制量上的一个变量。 if(UKTemp>999) {

UKTemp = 999; }

//这里只所以是999封顶而不是1024是因为我的系统PWM的峰值电压是12V导致。

while(1) //如果输出电压和期望电压相差 Delta,则继续调整占空比,直到在误差以内 {

ADChPro(UPWMADCH); //测量输出电压 if( ADPool.Value_Uint16[UPWMADCH] == UKTemp) {

return;

}

if( ADPool.Value_Uint16[UPWMADCH] > UKTemp) //如果当前电压大于输出电压,减小占空比 {

if( ( ADPool.Value_Uint16[UPWMADCH] - UKTemp ) > UDELTA ) {

temp = ADPool.Value_Uint16[UPWMADCH] - UKTemp; // temp = temp / 2; //下降可以加速下降,所以下降参数加倍 if( Pwm.DutyCycle_Uint8 > temp ) {

Pwm.DutyCycle_Uint8 = Pwm.DutyCycle_Uint8 - temp; } else {

Pwm.DutyCycle_Uint8 = 0; } } else {

return; } }

else //如果当前电压小于输出电压 {

if( ( UKTemp - ADPool.Value_Uint16[UPWMADCH] ) > UDELTA ) {

temp = UKTemp - ADPool.Value_Uint16[UPWMADCH];

temp = temp / 4; //上升处理不要超调,所以每次只+一半 if( (255-Pwm.DutyCycle_Uint8) > temp ) {

Pwm.DutyCycle_Uint8 += (temp/2); } else {

Pwm.DutyCycle_Uint8 = 255; } } else {

return; } }

DisPlayVoltage();

PWMChangeDuty(Pwm.DutyCycle_Uint8); //改变占空比 Delay(10,10);

} } }

/*****************************************************/ 附录2

直流电机PWM调速系统中控制电压非线性研究

引言

由于线性放大驱动方式效率和散热问题严重,目前绝大多数直流电动机采用开关驱动方式。开关驱动方式是半导体功率器件工作在开关状态,通过脉宽调制PWM控制电动机电枢电压,实现调速。目前已有许多文献介绍直流电机调速,宋卫国等用89C51单片机实现了直流电机闭环调速;张立勋等用AVR单片机实现了直流电机PWM调速;郭崇军等用C8051实现了无刷直流电机控制;张红娟等用PIC单片机实现了直流电机PWM调速;王晨阳等用DSP实现了无刷直流电机控制。上述文献对实现调速的硬件电路和软件流程的设计有较详细的描述,但没有说明具体的调压调速方法,也没有提及占空比与电机端电压平均值之间的关系。在李维军等基于单片机用软件实现直流电机PWM调速系统中提到平均速度与占空比并不是严格的线性关系,在一般的应用中,可以将其近似地看作线性关系。但没有做深入的研究。本文通过实验验证,在不带电机情况下,PWM波占空比与控制输出端电压平均值之间呈线性关系;在带电机情况下,占空比与电机端电压平均值满足抛物线方程,能取得精确的控制。本文的电机闭环调速是运用Matlab拟合的关系式通过PID控制算法实现。 1 系统硬件设计

本系统是基于TX-1C实验板上的AT89C52单片机,调速系统的硬件原理图如图1所示,主要由AT89C52单片机、555振荡电路、L298驱动电路、光电隔离、霍尔元件测速电路、MAX 232电平转换电路等组成。

图1 闭环控制系统示意图

2 系统软件设计

系统采用模块化设计,软件由1个主程序,3个中断子程序,即外部中断0、外部中断1,定时器0子程序,PID算法子程序,测速子程序及发送数据到串口显示子程序组成,主程序流程图如图2所示。外部中断0通过比较直流电平与锯齿波信号产生PWM波,外部中断1用于对传感器的脉冲计数。定时器0用于对计数脉冲定时。测得的转速通过串口发送到上位机显示,通过PID模块调整转速到设定值。本实验采用M/T法测速,它是同时测量检测时间和在此检测时间内霍尔传感器所产生的转速脉冲信号的个数来确定转速。由外部中断1对霍尔传感器脉冲计数,同时起动定时器0,当计数个数到预定值2 000后,关定时器0,可得到计2 000个脉冲的计数时间,由式计算出转速:

n=60f/K=60N/(KT) (1)

式中:n为直流电机的转速;K为霍尔传感器转盘上磁钢数;f为脉冲频率;N为脉冲个数;T为采样周期。

PID控制算法的C语言实现(完整版)

(注意,我这里讨论的前提是输出控制的是电压,不是PWM方波。PWM输出后要经过滤波整形再输出控制。)前提条件:输出电压控制电压范围是0-10V。给定、反馈、输出电压采样输入电压范围是0-5V(经过运放)。使用单片机AD为10位AD芯片。那么10位AD芯片电压采集得到的数据范围就是0-1024。PWM为8位可调占空比方波,0
推荐度:
点击下载文档文档为doc格式
53adw1dpq51j03u4hzb9
领取福利

微信扫码领取福利

微信扫码分享