农业网站如何建设,企业网站带后台,WordPress中菜单变色,营销推广计划本例使用的是LPC21XX系列芯片提供的PWM功能实现稳定的温度控制。首先我们获得当前环境温度之后#xff0c;再用设定的温度与当前温度相减#xff0c;通过PID算法计算出当前输出脉宽#xff0c;并将其输出到L298N模块中#xff0c;使加热丝发热#xff0c;形成闭环#xf… 本例使用的是LPC21XX系列芯片提供的PWM功能实现稳定的温度控制。首先我们获得当前环境温度之后再用设定的温度与当前温度相减通过PID算法计算出当前输出脉宽并将其输出到L298N模块中使加热丝发热形成闭环经过一段时间温度稳定在预设值。 概念说明
PWMPWMPulse Width Modulation简称脉宽调制是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。PWM输出的是周期信号其中PWM频率指的是1秒内PWM的周期次数占空比指的是一个脉冲周期内高电平的时间与整个周期时间的比例。PWM可通过其不同的占空比配置来实现LED呼吸灯电机转速等应用 PID算法就是“比例proportional、积分integral、微分derivative”是一种常见的“保持稳定”控制算法在闭环系统的控制中可自动对控制系统进行准确且迅速的校正是工业应用中最广泛算法之一。PID算法主要涉及三个最基本的参数最终PID输出值是三部分调节增益之和PoutIoutDout Kp比例增益已知当前环境温度与用户设定值之间的差值EkKp与Ek在Pout的计算中为乘法关系其大小将直接影响系统的响应速度Kd微分增益两次差值之差可表示DkKd与Dk也是乘法关系其作用有让其变化速度趋于0即类似阻尼的作用。Ki积分增益Ki积分控制考虑过去误差将误差值过去一段时间之和误差和乘以一个正值的常数Ki其作用是减小静态情况下的误差让受控物理量尽可能接近目标值。 L298NL298N是意法半导体集团旗下量产的一种电机驱动芯片拥有工作电压高、输出电流大、驱动能力强、发热量低、抗干扰能力强等特点通常用来驱动继电器、螺线管、电磁阀、直流电机以及步进电机。本例我们用来驱动一个加热丝来进行发热。 实现原理
嵌入式代码运行在LPC21XX系列芯片平台上使用平台提供的PWM通道进行控制信号输出实现原理如下图所示 嵌入式程序
LPC21XX平台使用PWM功能涉及的步骤如下
首先是配置 PLL以生成时钟因为它根据程序员的需要设置 LPC2148 的系统时钟和外设时钟。LPC2148 的最大时钟频率为 60Mhz。接下来是使用 PINSEL 寄存器选择 LPC2148 的 PWM 引脚和 PWM 功能。我们使用 PINSEL0因为我们使用 P0.0 作为 LPC2148 的 PWM 输出。接下来我们需要使用 PWMTCR定时器控制寄存器重置定时器然后设置决定 PWM 分辨率的预分频值。我将它设置为零。接下来我们需要设置 PWMMCRPWM 匹配控制寄存器因为它设置了复位等操作PWMMR0 的中断。使用 PWMMR 设置 PWM 通道的最大周期。接下来我们需要使用 PWMLER 将 Latch Enable 设置为相应的匹配寄存器。要使 PWM 输出到引脚我们需要使用 PWMTCR 来启用 PWM 定时器计数器和 PWM 模式。
代码如下提供UpdatePWMDutyRatio接口可以实时调整占空比
#include lpc214x.h
#include stdint.h
#include string.hunsigned int PWMvalue0;void initilizePLL(void);
void initilizePWM(unsigned int periodPWM);
void delaytime(uint16_t j);
void UpdatePWMDutyRatio();void initilizePLL (void) //Function to use PLL for clock generation
{PLL0CON 0x01; PLL0CFG 0x24;PLL0FEED 0xAA;PLL0FEED 0x55;while(!(PLL0STAT 0x00000400));PLL0CON 0x03;PLL0FEED 0xAA;PLL0FEED 0x55;VPBDIV 0x01;} void delaytime(uint16_t j) // fucntion to generate 1 milisecond delay{uint16_t x,i;for(i0;ij;i){for(x0; x6000; x); }}void initilizePWM(unsigned int PWMvalue) {PINSEL0 0x00000002; //Setting pin P0.0 for PWM outputPWMTCR (11); //Setting PWM Timer Control Register as counter resetPWMPR 0X00; //Setting PWM prescale valuePWMMCR (10)|(11); //Setting PWM Match Control RegisterPWMMR0 PWMvalue; //Giving PWM value Maximum valuePWMLER (10); //Enalbe PWM latchPWMTCR (10) | (13); //Enabling PWM and PWM counter}
void UpdatePWMDutyRatio()
{PWMTCR ~((10) | (13)); //Disable PWM and PWM counterPWMMR0 PWMvalue; //Giving PWM value PWMTCR (10) | (13); //Enabling PWM and PWM counter}
PID.h文件内是PID算法因子结构体定义代码就不再往这里贴了。下面是PID算法实现的代码代码中用中文帮助您理解
#include PID.hPID pid;
void PID_Init()
{pid.Sv38;//用户设定温度pid.Kp30;pid.T400;//PID计算周期pid.Ti4000000;//积分时间pid.Td1000;//微分时间pid.pwmcycle200;//pwm周期200pid.OUT01;pid.C1ms0;
}
void PID_Calc() //pid计算
{float DelEk;float ti,ki;float td;float kd;float out;if(pid.C1ms(pid.T)) //计算周期未到{return ;} pid.Ekpid.Sv-pid.Pv; //得到当前的偏差值pid.Poutpid.Kp*pid.Ek; //比例输出pid.SEkpid.Ek; //历史偏差总和DelEkpid.Ek-pid.Ek_1; //最近两次偏差之差tipid.T/pid.Ti;kiti*pid.Kp;pid.Ioutki*pid.SEk; //积分输出tdpid.Td/pid.T;kdpid.Kp*td;pid.Doutkd*DelEk; //微分输出out pid.Pout pid.Iout pid.Dout;if(outpid.pwmcycle){pid.OUTpid.pwmcycle;}else if(out0){pid.OUTpid.OUT0; }else {pid.OUTout;}pid.Ek_1pid.Ek; //更新偏差pid.C1ms0;
}下面是此例的main函数,通过上面封装的接口对温度进行控制稳定的达到目标温度
#include PID.h
#include PWMOUT.hexyern unsigned int PWMvalue;#define PERIOD 400int main()
{unsigned int num0;PID_Init();initilizePLL(); while(1){while(获取当前温度赋值到pid.pv中);PID_Calc();//计算PID的值num(((pid.OUT*PERIOD)/pid.pwmcycle)-1);//获取当前的PWM脉冲占空比PWMvaluenum;UpdatePWMDutyRatio(); }
} 十六宿舍 原创作品转载必须标注原文链接。 ©2023 Yang Li. All rights reserved. 欢迎关注 『十六宿舍』大家喜欢的话给个更多关于嵌入式相关技术的内容持续更新中。