采用PID控制算法的液晶屏加热电路、程序
几年前,我设计了一款带有LCD显示屏的产品。
通常LCD 液晶屏的工作温度,常温型的为0-50 °C,宽温型的为-20-70 °C,超宽温型的为-30-80 °C。
大家知道,俄罗斯和北欧国家一到冬天就被冰雪覆盖,地冻天寒,即使在白天气温也可能低至-50°C。
因此,该款产品的工作温度要求为-40°C-70°C,即要求液晶屏在-40°C仍然能正常工作。
我们的解决方案是通过NTC检测温度,采用PWM驱动功率电阻产生热量加热。
所幸产品体积比较小,而且电路板以及液晶屏被密闭在外壳内,所以只需消耗很小的功率就能实现较好加热效果。
其实在这款产品之前,公司也有类似的由他人设计的产品,当初的方案是根据阈值控制功率电阻的导通或断开,即:
检测到温度低于-15°C时,MCU的IO口输出高电平让NMOS导通给功率电阻供电使其发出热量;
当检测到温度高于-5°C时,则输出低电平让NMOS断开使功率电阻停止加热。
这一简陋的模糊控制的方法,不但浪费电,而且不能在低温情况下给电子元器件和液晶屏提供-10°C的恒温工作环境。
工作环境不好,影响了这些器器件的心情。搞不好它们就要罢工或者提前退休。
作为有几十年工作经验的工程师,我深知“细节决定成败”的真谛,所以对这个加热的方案做了一些创新:
- 电路还是那个电路,器件还是那个器件;
温度检测以及电阻加热电路原理图
温度检测比较简单,+3.3V的基准电压经过NTC以及R2分压之后送入单片机的ADC口。
MCU的PWM口通过R4限流,R5的泄流控制NMOS Q1驱动功率电阻10ohm的R3发热。
- 控制NMOS的端口由普通的IO口改到PWM
采用频率为1KHz,占空比0%-100%可调的PWM信号驱动NMOS使功率电阻R3产生可调的热量;
- 编写MCU程序实现增量式PID控制,并根据PID算法计算的数值设定PWM的占空比
将设定温度固定为-10°C
从ADC口读取出当前温度对应的ADC值
计算设定温度与当前温度的差值
从其内部存储器读出事先整定好的比例,积分系数,算出控制量。
增量式PID控制算法
- 对比例系数、积分系数进行整定
PID参数的整定非常考虑能力和经验,我的经验是,先整定比例系数,先把控制闭环断开,测试整个系统中输入为1个单位时,所控制的输出能产生多少个单位的变化。选定比例系数,使得1个单个的输入能使输出产生0.1左右的单位的变化。
接下选定积分系数,积分系数大概为比例系数的1/20,可采用二分法,根据测试的结果不断调整。使得控制效果最佳,既不产生振荡,又不致使系统的反应太慢。
增量式PID控制算法如下:
void pid_init(void) { INT32 m_lCF, m_lCI, m_lCurU; pidcon.m_iDU = (INT16)pidcon.m_uiSetAD - (INT16)pidcon.m_uiCurAD;m_lCF = (INT32)pidcon.m_uiKP * pidcon.m_iDU;m_lCI = (INT32)pidcon.m_uiKI * pidcon.m_iDU;m_lCurU = m_lCF + m_lCI;pidcon.m_ulCurU = m_lCurU; } #define HT_AD_CURU_MIN 0 #define HT_AD_CURU_MAX ((INT32)HT_PWM_PERIOD * 512) void pid_cal(void) { INT16 m_iDU, m_iDDU;INT32 m_lCF, m_lCI, m_lCurU; m_iDU = (INT16)pidcon.m_uiSetAD - (INT16)pidcon.m_uiCurAD;m_iDDU = m_iDU - pidcon.m_iDU;pidcon.m_iDU = m_iDU;m_lCF = (INT32)pidcon.m_uiKP * m_iDDU;m_lCI = (INT32)pidcon.m_uiKI * m_iDU;m_lCurU = m_lCF + m_lCI;pidcon.m_ulCurU += m_lCurU;if(pidcon.m_ulCurU < HT_AD_CURU_MIN){pidcon.m_ulCurU = HT_AD_CURU_MIN;}if(pidcon.m_ulCurU > HT_AD_CURU_MAX){pidcon.m_ulCurU = HT_AD_CURU_MAX;} } void pid_conduty(void) { U32 lduty; lduty = 0;pidcon.m_uiDuty = 0;if(pidcon.m_ulCurU > 0){lduty = (U32)pidcon.m_ulCurU / 512;}if(lduty >= HT_PWM_PERIOD){pidcon.m_uiDuty = HT_PWM_PERIOD;}else{pidcon.m_uiDuty = (U16)lduty;}updateduty(pidcon.m_uiDuty); }
最终效果非常完美
把产品放置到高低温试验箱,把温度设置为-30°C,测得产品外壳内部的温度曲线如下:
温度变化曲线,实现了完美的跟踪