资源描述
摘 要
在运动控制系统中,电机转速控制占有至关重要的作用,其控制算法和手段有很多,模拟PID控制是最早发展起来的控制策略之一,长期以来形成了典型的结构,并且参数整定方便,能够满足一般控制的要求,但由于在模拟PID控制系统中,参数一旦整定好后,在整个控制过程中都是固定不变的,而在实际中,由于现场的系统参数、温度等条件发生变化,使系统很难达到最佳的控制效果,因此采用模拟PID控制器难以获得满意的控制效果。随着计算机技术与智能控制理论的发展,数字PID技术渐渐发展起来,它不仅能够实现模拟PID所完成的控制任务,而且具备控制算法灵活、可靠性高等优点,应用面越来越广。
本文章介绍了由51单片机以及直流电机、矩阵键盘、LCD和传感器构成的转速闭环控制系统。其中传感器负责对电机转速进行测量,并将测量的结果反馈给控制中心,并由控制中心将之与设定值进行比较得到偏差,再由偏差产生直接控制作用去消除偏差。文章不但介绍了基于单片机的转速控制系统的软件设计,还涉及了硬件设计方法。文中介绍系统不但可以实现手动控制,还有无人值守,自动调速功能。
关键词:直流电机 闭环控制 单片机 矩阵键盘 LCD
目 录
第1章 绪论 1
第2章 课程设计的方案 2
2.1 概述 2
2.2 系统组成总体结构 2
第3章 硬件设计 3
3.1 控制器 3
3.2 测速发电机 3
3.3 A/D转换和D/A转换器 3
3.4 晶闸管整流控压 4
3.5 键盘模块 5
3.6 显示器 6
3.7 整体结构原理图 7
第4章 软件设计 8
4.1 主流程设计 8
4.2 按键功能部分 9
4.3 PID控制部分 9
4.4 参数确认 10
4.5 LCD显示部分 11
第5章 实验试验结果 12
第6章 课程设计总结 13
参考文献 14
部分程序 15
第1章 绪论
直流电气传动系统中需要有专门的可控直流电源,常用的可控直流电源有以下几种:第一,最初的直流调速系统是采用恒定的直流电压向直流电动机电枢供电,通过改变电枢回路中的电阻来实现调速。这种方法简单易行,设备制造方便,价格低廉。但缺点是效率低、不能在较宽范围内平滑调速,所以目前极少采用。第二,三十年代末,出现了发电机—电动机(也称为旋转变流组),配合采用磁放大器、电机扩大机、闸流管等控制器件,可获得优良的调速性能,如有较宽的调速范围(十比一至数十比一)、较小的转速变化率和调速平滑等。特别是当电动机减速时,可以通过发电机非常容易地将电动机轴上的飞轮惯量反馈给电网,这样,一方面可得到平滑的制动特性,另一方面又可减少能量的损耗,提高效率。但发电机—电动机调速系统的主要缺点是需要增加两台与调速电动机相当的旋转电机和一些辅助励磁设备,因而体积设备较多、体积大、费用高、效率低、安装需要地基、运行有噪声、维修困难等。第三,自出现汞弧变流器后,利用汞弧变流器代替上述发电机—电动机系统,使调速性能指标又进一步提高。特别是它的系统快速响应性是发电机—电动机系统不能比拟的。但是汞弧变流器仍存在一些缺点:维修还是不太方便,特别是水银蒸汽对维护人员会造成一定的危害等。第四,1957年,世界上出现了第一只晶闸管,与其它变流元件相比,晶闸管具有许多独特的优越性,因而晶闸管直流调速系统立即显示出强大的生命力。由于它具有体积小、响应快、工作可靠、寿命长、维修简便等一系列优点,采用晶闸管供电,不仅使直流调速系统经济指标上和可靠性有所提高,而且在技术性能上也显示出很大的优越性。晶闸管变流装置的放大倍数在10000以上,比机组(放大倍数10)高1000倍,比汞弧变流器(1000)高10倍;在快速响应性上,机组是秒级,而晶闸管变流装置为毫秒级。因此,目前在直流调速系统中,除某些特大容量的设备而且供电电路容量较小的情况下,仍有采用机组供电、晶闸管励磁系统以外,几乎绝大部分都已改用晶闸管相控整流供电了。
随着微电子技术的发展,微机功能的不断提高以及电力电子、计算机控制技术的发展,电气传动领域出现了以微机为核心的数字控制系统。计算机的发展可
以使复杂的控制规律较方便的实现,以计算机为核心的数字控制技术成为自控领
域的主流,也给直流电气传动的发展注入了新的活力,使电气传动进入了更新的发展阶段。
第2章 课程设计的方案
2.1 概述
本次设计主要是综合应用所学知识,设计直流电机转速控制系统设计,并在实践的基本技能方面进行一次系统的训练。能够较全面地巩固和应用“微型计算机控制技术”课程中所学的基本理论和基本方法,并初步掌握小型控制系统设计的基本方法。
2.2 系统组成总体结构
图2.2是基于单片机的转速控制系统的基本组成方框。主要由测速发电机,电机,矩阵键盘,LCD(12864),单片机(89C51)组成。测速发电机输出电压的大小反映机械转速的高低,并将该模拟量入如A/D转换器,转换成数字信号给单片机。单片机89C51是该系统的核心部分,一方面负责计算电机的转速,另一方面将计算得到的转速与设定转速相比较,经过计算处理,得到相应的控制信号,并用该信号传入D/A转换器,再传入晶闸管调压器控制控制电压从而控制电机转速。通过键盘可以设定工作模式(通过输入设定转速,单片机自动控制电机转速,使其接近设定值)设定转速。由单片机检测哪一个按键按下,实现设定值的修改,并通过LCD实时显示设定值以及测得转速。
电机
测速发电机
单片机
D/A转换器
LCD
A/D转换器
键盘
晶闸管
图2.2系统框图
第3章 硬件设计
3.1 控制器
采用AT89 C51作为系统控制的方案。AT89C51单片机算术运算功能强,软件编程灵活、自由度大,可用软件编程实现各种算法和逻辑控制。相对于FPGA来说,它的芯片引脚少,在硬件很容易实现。并且它还具有功耗低、体积小、技术成熟和成本低等优点,在各个领域中应用广泛。
3.2 测速发电机
采用ZYS型直流测速发电机,直流测速发电机在结构上与普通小微型直流发电机相同,通常是两极电机,分为他励式和永磁式两种。
他励式测速发电机的磁极由铁心和励磁绕组构成,在励磁绕组中通入直流电流便可以建立极性恒定的磁场。它的励磁绕组电阻会因电机工作温度的变化而变化,使励磁电流及其生成的磁通随之变化,产生线性误差。
永磁式测速发电机的磁极由永久磁铁构成,不需励磁电源。磁极的热稳定性较好,磁通随电机工作温度的变化而变化的程度很小,但易受机械振动的影响而引发不同程度的退磁。
3.3 A/D转换和D/A转换器
该模块A/D转换选用ADC0809是M美国国家半导体公司生产的CMOS工艺8通道,8位逐次逼近式A/D转换器。其内部有一个8通道多路开关,它可以根据地址码锁存译码后的信号,只选通8路模拟输入信号中的一个进行A/D转换。是目前国内应用最广泛的8位通用A/D芯片。
DAC0832是8分辨率的D/A转换集成芯片。与微处理器完全兼容。这个DA芯片以其价格低廉、接口简单、转换控制容易等优点,在单片机应用系统中得到广泛的应用。D/A转换器由8位输入锁存器、8位DAC寄存器、8位D/A转换电路及转换控制电路构成。
3.4 晶闸管整流控压
本设计采用三相全控桥式整流电路,由一组共阴极接法的三相半波可控整流电路和一组共阳极接法的三相半波可控整流电路串联而成。如图3.4所示。
如图3.4 三相桥式全控整流电路
三相全控桥式整流电路要求用双窄脉冲触发,即用两个间隔60°的窄脉冲去触发晶闸管。产生双脉冲的方法有两种, 一种是每个触发电路在每个周期内只产生一个脉冲, 脉冲输出电路同时触发两个桥臂的晶闸管,这叫外双脉冲触发; 另一种是每个触发电路在一个周期内连续发出两个相隔60°的窄脉冲, 脉冲输出电路只触发一个晶闸管,这称为内双脉冲触发。 内双脉冲触发是目前应用最多的一种触发方式。
本设计采用KC04与KC41C组合的触发电路如图3.4.1所示触发电路。
3.4.1 KC04与KC41C组成的全控桥触发电路
3.5 键盘模块
本次设计中采用的4*4的非编码键盘。矩阵式非编码键盘的电路原理图如图3.4所示。当没有键按下时,行线和列线之间是不相连。若第N行第M列的键被按下,那么第N行与第M列的线就被接通。如果在行线上加上信号,根据列线的状态,便可得知是否有键按下。如果在行线上逐行加上一个扫描信号(本实验中用的低电平),就可以判断按键的位置。常用的按键识别有两种方法:一种是传统的行扫描法;另一种是速度较快的线反转法。本实验中采用的是线反转法进行识键。
键盘在单片机系统中是一个很重要的部件。为了输入数据、查询和控制系统的工作状态,都要用到键盘,键盘是人工干预计算机的主要手段。
键盘可分为编码和非编码键盘两种。编码键盘采用硬件线线路来实现键盘编码,每按下一个键,键盘能自动生成按键代码,键数较多,而且还具有去抖动功能。这种键盘使用方便,但硬件较复杂,PC机所用的键盘就属于这种。非编码键盘仅提供按键开关工作状态,其他工作由软件完成,这种键盘键数较少,硬件简单,一般在单片机应用系统中广泛使用。
3.6 显示器
液晶显示模块(LCD12864)由于其具有功耗低、无电磁辐射、寿命长、价格低、接口方便等一系列显著优点,被广泛应用与各种仪表仪器、测量显示装置、计算机显示终端等方面。12864汉字图形点阵液晶显示模块,可显示汉字及图形,内置8192个中文汉字(16X16点阵)、128个字符(8X16点阵)及64X256点阵显示RAM(GDRAM)。
主要技术参数和显示特性:
电源:VDD 3.3V~+5V(内置升压电路,无需负压);
显示内容:128列× 64行
显示颜色:黄绿
显示角度:6:00钟直视
LCD类型:STN
与MCU接口:8位或4位并行/3位串行
配置LED背光
多种软件功能:光标显示、画面移位、自定义字符、睡眠模式等
3.7 整体结构原理图
整体原理图如图3.7所示:
3.7 整体原理图
第4章 软件设计
4.1 主流程设计
在一个完整的系统中,只有硬件部分是不能完成相应设计任务的,所以在该系统中软件部分是非常重要的,按照要求和系统运行过程设计出主程序流程如图4.1所示。
是
开始
定时器初始化
键盘选择工作模式
是否启动电机
显示信息
刷新显示
进行键盘扫描
按键功能判断
更新控制并清除标志位
是
图4.1 主流程图
4.2 按键功能部分
该部分首要任务是判定到底是哪个按键按下,然后实现对应功能。如果是11号键按下,则工作模式设定为自动模式,可以通过0~9的数字键来更改设定速度,由单片机通过PID算法来控制电机转速接近设定值。如果是12号键按下,则工作模式设定为手动模式,可以通过0~9的数字键来直接控制电机转速。
4.3 PID控制部分
如图4.3给出了数字PID增量控制算法的流程图,利用增量控制算法也可得出位置控制算法,即,这便是位置型控制算式的递推算法,其流程和增量型算法类似,稍加修改即可。
离线计算q0,q1,q2
求e(k)=r(k)-y(k)
e(k-2)=e(k-1) e(k-1)=e(k)
将输给D/A
将A/D结果赋给y(k)
计算控制增量
采样时刻到否
A/D
D/A
被控对象
是
否
图4.3 PID控制算法流程图
4.4 参数确认
TI =0.1 T2=0.06 得
通常取,
通常取,
=
根据上式确认,。
=0.58s
= 0.159s
求得数字PID调节器控制参数
据上式确认数字PID调节器控制参数。
4.5 LCD显示部分
其工作流程为先向LCD发送控制命令,再传送待显数据,最后刷新屏幕。其流程图如图4.5所示。
入口
发送命令
延时
发送数据
延时
显示
返回
图4.5 LCD显示函数流程图
第5章 实验试验结果
通过实验室试验,输入已经确定的Kp=1.4,T1=0.096,Td=0.15得到如图5.1所示。
图5.1 实验图像
超调量=297/2000=14% 小于20%符合设计要求。
第6章 课程设计总结
这次课程设计结束,感谢辽宁工业大学给我这个锻炼的机会,感谢王老师给的指导。
刚开始做设计的时候觉得无从下手,后来通过老师的指导慢慢的进入了状态,看书查找资料,在实验室做实验,过程中出现了很多的问题,经过老师和同学的帮助终于克服了。
参考文献
[1] 赵新民.智能仪器设计基础.哈尔滨:哈尔滨工业大学出版社,2009:42-56
[2] 程德福.智能仪器.北京:机械工业出版社,2009.9:101-130
[3] 张毅刚.单片机原理及接口技术[M] .哈尔滨:哈尔滨工业大学出版社,2007:55-66
[4] 胡文金.单片机应用技术实训教程.重庆:重庆大学出版社,2005:5-21
[5] 梁森.自动检测技术及应用. 北京:机械工业出版社,2009:32-33
部分程序
PID算法程序
#include <C8051F020.H>
#include <string.h>
#include <math.h>
//void PIDInit(PID *PP);
/*定义结构体和公用体*/
#define N 8
typedef struct PID{
unsigned int setpoint; /*设定值*/
unsigned int proportion; /*比例系数*/
unsigned int integral; /*积分系数*/
unsigned int derivative; /*微分系数 */
unsigned int lasterror; /*前一拍误差*/
unsigned int preerror; /*前两拍误差*/
}PID;
union stu{
unsigned int value;
unsigned char num[2];
}laser;
union dat{
unsigned char dd[2];
unsigned int number;
}collect;
/*函数声明部分*/
unsigned int PIDcal(PID *pp,int thiserror);
void PIDInit(PID *PP);
void PortInit(void);
unsigned int get_ad(void);
unsigned int filter_valve(void);
void Delayms(void);
/*主函数部分*/
void main(void)
{
PID vPID; /*定义结构体变量名*/
unsigned int verror;
unsigned int Error;
unsigned int tempi;
unsigned char LASERH,LASERL; /*误差的高低字节变量*/
WDTCN=0xde;
WDTCN=0xad;
//portinit();
PIDInit(&vPID);
vPID.proportion=10; /*设置PID比例系数为10*/
vPID.integral=10; /*设定PID积分系数 为10*/
vPID.derivative=10; /*设定PID微分系数为10*/
vPID.setpoint=50; /*根据实际情况设定*/
IE= 0x80;
while(1)
{
verror=filter_valve(); /*得到AD的滤波输出值 */
Error=vPID.setpoint-verror; /*得到误差值*/
tempi=PIDcal(&vPID,Error); /*调用PID算法函数 得到误差增量*/
laser.value+=tempi;
LASERH=laser.num[0]; /*value与num[2]为共同体,变量名为laser*/
LASERL=laser.num[1]; /*存放高低字节*/
}
}
/*PID算法函数,返回误差增量*/
unsigned int PIDcal(PID *pp,int thisError){
unsigned int pError,dError,iError;
unsigned int templ;
pError=thisError-pp->lasterror;
iError=thisError;
dError=thisError-2*(pp->lasterror)+pp->preerror;
templ=pp->proportion*pError+pp->integral*iError+pp->derivative*dError; /*增量计算*/
pp->preerror=pp->lasterror; /*存放误差用于下次运算*/
pp->lasterror=thisError;
return ((int)(templ>>8));
}
/*测量值*/
/*float measure(void) 已知A B 角为锐角
{ /* COSA=1/7 SIN(A+B)=14分之5倍根号3 */
/*long float value; /*求COSB*/
/*float A,B;
A=acos(1/7);
B=asin((5/14)*sqrt(3))-A;
if((0<A<pi/2)&&(0<B<pi/2)) return cos(B);
} */
/*得到ADC转换值*/
unsigned int get_ad(void)
{
while(AD0INT==0);
{
AD0INT=0;
collect.dd[1]=ADC0H;
collect.dd[0]=ADC0L;
return (collect.number);
}
}
void Timer3_ISR(void) interrupt 14
{
TMR3CN=0x7f;
//AMUX0SL=0x00;
AD0BUSY=1;
}
void Timer3_Init(unsigned char Highcounts,unsigned char Lowcounts)
{
TMR3CN=0x01; /*禁止定时器3;清TF3,采用SYSCLK为时基*/
TMR3RLH=-Highcounts; /*初始化重装载值*/
TMR3RLL=-Lowcounts;
TMR3L=0xff; /*设置为立即重装在*/
TMR3H=0xff;
EIE2|= 0x01; /*允许定时3中断*/
TMR3CN|=0x06; /*启动定时器3*/
}
void ADCInit(void)
{
ADC0CF=0x00; /*选择ADC0的转换始终为系统时钟,增益为1*/
ADC0CN=0xc0; /*允许ADC0准备转换,定义低功耗跟踪方式,置AD0BUSY位为1启动ADC,寄存器数据右对齐*/
AMX0CF=0x01; /*选择AIN0和AIN!为通道0差分输入的正负端*/
}
/*PID初始化*/
void PIDInit(PID *PP)
{
memset(PP,0,sizeof(PID));
}
/*数字算术滤波子程序*/
unsigned int filter_valve(void)
{
unsigned char i,j,temp;
unsigned char count;
unsigned int valve_buf[N];
unsigned int sum=0;
for(count=0;count<N;count++)
{
valve_buf[count]=get_ad();
Delayms();
}
for(j=0;j<N-1;j++)
{ for(i=0;i<N-j;i++)
{
if(valve_buf[i]>valve_buf[i+1])
{
temp=valve_buf[i];
valve_buf[i]=valve_buf[i+1];
valve_buf[i+1]=temp;
}
}
}
for(count=1;count<N-1;count++)
{
sum+=valve_buf[count];
return (unsigned int)(sum/(N-2));
}
}
/*延时子程序*/
void Delayms(void)
{
unsigned int ms;
unsigned char i;
while(ms--)
{
for(i=0;i<120;i++);
}
}
展开阅读全文