3 speed2?cesu2?
5由于本设计中所采用的直流电机额定速度达到500转/分,已经超出了一个字节的范围,用这个数值进行偏差计算仍然需要定义一个16位的整形变量来表示,并不能简化计算量。在500转/分的额定转速下能测到的脉冲个数能达到834,输出控制量是8位PWM的占空比,其范围是0到255,为了提高控制精度,在计算左电机速度偏差时采用了测量脉冲数,这就要求将左电机的设定速度转化成0.1秒下单片机应计的标准脉冲个数shd进行偏差计算。例如要求电机的转速为shj,
其转化公式为:
5 shd?shj?
3开始 i 自加1 将T2计数值存入数组 CS1并将T2清0 将T3计数值存入数组 CS2并将T3清0 TF4清0 i>=4 选出CS1中最大最小值 计算cesu1 选出CS2中最大最小值 计算cesu2 将i清0,j置1 中断返回
图7.2 测速子程序流程图
7.2.3 主程序
PID控制算法是在主程序中完成的。在主程序中不断地以0.1秒的周期循环计算控制量,即主从电机PWM的占空比,通过改变占空比来调节电机的速度。其流程图如图7.4所示。
j作为主程序的循环标志,每当Timer4循环4次(计时0.1秒)时在T4中断中被置1,在主程序中进入if语句执行一次控制算法,并被清0。下一次主程序循环过来时if语句就不会再执行了,直到过了0.1秒后j再次被置1,这样就保证了0.1秒内只计算一次。
在主程序中,左电机的设定速度转化成的标准脉冲数减去其实测脉冲数,其结果作为当前时刻主电机的速度偏差值,从电机把主电机的实测脉冲数作为自己的设定速度值,用其减去从电机的实测脉冲数,结果作为其当前时刻的速度偏差值,以实现跟踪主电机。
改进的PID算法采用了遇限削弱积分法和积分分离法。主电机积分饱和的条件为:e13>300或u1=255且e13>0, 即当左电机速度偏差达到300或主电机控制量已达到上限且偏差为正时,除去主电机控制算法中的积分项。从电机积分饱和的条件为:e23>300或u2=255且e23>0,即当右电机速度偏差达到200或右电机控制量已达到上限且偏差为正时,除去从电机控制算法中的积分项。
为了避免主从电机稳定情况下频繁地修改控制量并减小计算工作量,主程序采用了带死区的控制算法,当主从电机的速度偏差满足以下条件|ei3|<2且|ei3-ei2|<2时,认为主从电机速度处在稳定域内,不执行修改控制量的指令。
开 始 主电机速度初始值设定 控制参数初始设置 J=1 计算主电机近三次速度偏差 计算从电机近三次速度偏差 主电机积分饱和 K1=0去除主电机积分项 从电机积分饱和 K2=0去除从电机积分项 主电机偏差稳定域内 计算主电机控制量u1 从电机偏差稳定域内 计算从电机控制量u2
图7.3 主程序流程图
7.3 总程序
#include \typedef unsigned int uint; typedef unsigned char uchar; typedef unsigned long ulong;
uint cesu1=0,cesu2=0; //0.1秒所测主从电机的脉冲个数 uchar temppage;
uchar i=0,j=0; //i为T4循环标志,j为主程序运算标志 uchar cs1[4],cs2[4]; //cs1,cs2保存主从电机的速度脉冲 uchar js[3],fs[6]; //发送和接收数据数组
uint shd,shj; //主电机设定速度及对应的标准脉冲值 uint speed1=0,speed2=0; //主从电机实际速度
xdata float T1,T2,Ti1,Ti2,Td1,Td2; //采样积分微分时间常数 xdata float A11,A12,A13,A21,A22,A23,Kp1,Kp2; //PID运算系数
void t4ISR(); //T4中断程序说明
void pwm_set() //PCA0初始化 {
SFRPAGE=0x00; //PCA0特殊功能寄存器所在分页 PCA0MD=0X04; //禁止PCA定时器中断,时基为Timer0 PCA0CPM0=0X42; //模块0:8为PWM模式,禁止中断 PCA0CPL0=0XFF; //PWM0赋初值 PCA0CPH0=0XFF;
PCA0CPM1=0X42; //模块1:8位PWM,禁止中断 PCA0CPL1=0XFF; //PWM1赋初值