自 动 化 工 程 训 练Word文档下载推荐.docx
《自 动 化 工 程 训 练Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《自 动 化 工 程 训 练Word文档下载推荐.docx(20页珍藏版)》请在冰豆网上搜索。
则增量式控制算法为:
其中Kp为控制器比例系数,Ki为积分时间常数。
由于系统采用了比例积分调节器(简称PI调节器),使系统在扰动的作用下,通过PI调节器的调节作用使电动机的转速达到静态无差,从而实现了静态无差。
无静差调速系统中,比例积分调节器的比例部分使动态响应比较快(无滞后),积分部分使系统消除静差。
第二章硬件设计与分析
在对直流电机调速系统有个清楚的认识后,对本系统进行硬件设计。
整个系统以89C52单片机为核心,包括主回路,驱动电路,测速电路,按键显示电路。
2.1系统硬件组成
图2-1为该系统硬件电路设计框图。
根据本系统要求通过软件编程定义键盘各键的功能及显示控制。
有关驱动及主回路控制电路见下几节。
整个系统控制过程为:
键盘输入控制信号、参数及速度给定值,单片机经过速度闭环、运算,控制P口(自行定义)输出脉冲的占空比,从而控制电机的转速,并经显示电路显示出来。
图2-1系统硬件框图
2.2驱动控制电路
驱动控制电路见图2-3。
将单片机软件产生的PWM信号经并联使用的施密特反相器,对IGBT进行驱动。
图2-2驱动控制电路
2.3主回路控制电路
主电路控制电路见图2-2。
220交流电压经过桥式整流电路的整流,再经过电容滤波,经过IGBT元件的功率放大,加到直流电机的两端控制电机。
图2-3主电路控制电路
2.4测速电路
测速电路见图2-4。
图2-4测速电路
2.5显示及按键电路
显示电路见图2-5。
选用共阴8段数码管,采用MAX7219驱动。
MAX7219是一种高集成化的串行输入/输出的共阴极LED显示驱动器。
每片可驱动8位7段加小数点的共阴极数码管,可以数片级联,而与微处理器的连接只需3根线。
MAX7219内部设有扫描电路,除了更新显示数据时从单片机接收数据外,平时独立工作,极大地节省了MCU有限的运行时间和程序资源。
MAX7219芯片上包括BCD译码器、多位扫描电路、段驱动器、位驱动器和用于存放每个数据位的8×
8静态RAM以及数个工作寄存器。
通过指令设置这些工作寄存器,可以使MAX7219进入不同的工作状态。
MAX7219的详细资料请参考其他书籍,这里不再赘述。
图2-5MAX7219驱动显示电路
按键电路见图2-6。
52单片机的P口在悬空时默认是高电平,每个按钮通过一个上拉电阻接到+5V电源,按下按钮,则P口变成低电平,这样就可以通过P口的状态来反映按钮的按下情况。
按键通过并联电容C进行防抖动,无需通过软件部分实现。
图2-6
第三章软件设计与分析
软件设计是本系统的难点也是重点,最终直流电机控制系统的好坏,很大程度上是由软件程序的优良决定的。
通过硬件的设计部分可知,软件程序主要包括:
按键程序,显示程序,PWM产生程序,测速程序以及PI调节程序。
在编写程序的过程中,运用工程化思想,从总体出发,由易到难,这样才能高质高效的完成软件设计的任务。
采用C语言而不是汇编语言,因为C语言方便使用,而且移植性好,更容易入手,有利于各个功能部分的实现。
3.1按键功能
按键的判断是通过检测P口的高低电平来实现的,有键按下,相应的P口就为低电平。
值得注意的是,按键程序必须防止误操作,也就是要加入防抖动功能。
我们采用的是串联电容接地实现防抖动功能,无需软件实现。
按键程序流程图见图3-1。
图3-1按键程序流程图
3.2显示功能
LED灯可以由单片机的P口经过放大后直接驱动点亮,但是这样做不仅硬件设计繁琐,而且也增加了软件设计的负担,这里采用专用芯片MAX7219驱动LED灯,可以很方便的完成显示功能。
软件部分除了对MAX7219初始化功能需要编程外,重点是LED灯怎样和按键配合准确地显示。
本系统要实现按键和显示配合的功能如下:
按下增加(减少)键,LED显示0~9相应的增加(减少);
按下选择键,可以循环控制不同位置的LED灯;
按下确认键,LED显示设定的数值。
而且要求没有按键时,待按键对应的LED灯闪烁变化,确认键按下后,LED不闪烁。
设定好的数值还要反馈到单片机中进行相应的运算控制以调节系统,测速电路测得的转速也应该通过显示功能电路显示出来,而且同时在一边另外的LED灯中显示设定转速,以和实际转速进行对比。
显示程序流程图见图3-2。
图3-2显示程序流程图
3.3PWM波产生和电机测速功能
在脉冲作用下,当电机通电时,速度增加;
电机断电时,速度逐渐减少。
只要按一定规律改变通、断电的时间,即可让电机转速得到控制。
PWM波产生的思想是,固定PWM的周期为PWMT,t时间内输出高电平,则剩下PWMT-t时间就输出低电平。
通过控制定时器T1,从而可以实现从8051的任意输出口输出不同占空比的脉冲波形。
由于PWM信号软件实现的核心是单片机内部的定时器,而不同单片机的定时器具有不同的特点,即使是同一台单片机由于选用的晶振不同,选择的定时器工作方式不同,其定时器的定时初值与定时时间的关系也不同。
因此,首先必须明确定时器的定时初值与定时时间的关系。
如果单片机的时钟频率为f,定时器/计数器为N位,则定时器初值与定时时间的关系为:
式中,Tw—定时器定时初值;
N—一个机器周期的时钟数。
N随着机型的不同而不同。
在应用中,应根据具体的机型给出相应的值。
这样,我们可以通过设定不同的定时初值Tw,从而改变占空比D,进而达到控制电机转速的目的。
此次实验采用12MHz晶振,计数频率为1MHz,即每微秒计数器加一,设置PMW脉冲周期固定为PWMT=10000,即0.01s。
在实际的直流电机调速系统中,电机的测速由测速电机完成,本次实验系统,由电机自带的霍尔元件完成测速,电机每转一圈,霍尔元件就送出一个脉冲,我们设计的程序是将测速部分嵌套在PWM函数里,这样就节省了一个定时器资源。
PWM脉冲周期为0.01s,一个周期定时器T1中断2次,设置定时器每中断200次,即每1s对电机进行一次测速,测速完毕后计数器T0归零,重新对霍尔脉冲计数。
PWM和测速程序流程图见图3-3。
图3-3PWM和测速程序流程图
3.5PI调节功能
本系统功率、电压环PI算法均采用积分分离增量式位置输出算法。
程序框图如图3-5所示。
图3-5 PI算法程序流程图
图3-6中,Ki为积分系数;
Kp为比例系数;
U(k)为第k次电压输出值;
U(k-1)为第(k-1)次电压输出值;
U′(k)为第k次与第(k-1)次电压输出值之差;
e(k)为给定与反馈值之差;
e′(k)为第k次与第(k-1)偏差之差。
附录二软件原程序
自定义头文件max7219.h
#include<
reg51.h>
#include<
intrins.h>
/*--------------------------------------------------*/
#defineucharunsignedchar
#defineuintunsignedint
sbitdis_DIN=P0^0;
/*显示串行数据输入端*/
sbitdis_LOAD=P0^1;
/*显示数据锁存端*/
sbitdis_CLK=P0^2;
/*显示时钟输入端*/
#defineNoOp0x00/*空操作*/
#defineDigit00x01/*数码管1*/
#defineDigit10x02/*数码管2*/
#defineDigit20x03/*数码管3*/
#defineDigit30x04/*数码管4*/
#defineDecodeMode0x09/*译码模式*/
#defineIntensity0x0a/*亮度*/
#defineScanLimit0x0b/*扫描界限*/
#defineShutDown0x0c/*掉电模式*/
#defineDisplayTest0x0f/*显示测试*/
#defineShutdownMode0x00/*掉电方式工作*/
#defineNormalOperation0x01/*正常操作方式*/
#defineDecodeDigit0xff/*译码位数设置*/
#defineIntensityGrade0x0a/*显示亮度级别设置*/
#defineScanDigit0x07/*扫描位数设置*/
#defineTestMode0x01/*显示测试方式*/
#defineTextEnd0x00/*显示测试结束,正常工作*/
unsignedintdataDisBuffer[4]={0,0,0,0};
/*显示缓存区*/
ucharDigit[4]={Digit0,Digit1,Digit2,Digit3};
/*数码管缓存区*/
unsignedcharcodedispaly_list[]=
{
0x7e,0x30,0x6d,0x79,0x33,0x5b,0x5f,0x70,0x7f,0x7b,/*0,1,2,3,4,5,6,7,8,9*/
0x77,0x1f,0x4e,0x3d,0x4f,0x47,0x67,0x3e,0xff,0x5f};
/*A,B,C,D,E,F,P,U,全
亮,全灭*/
/*--------------------------------------------------------
延时t毫秒子程序
---------------------------------------------------------*/
voiddelay(uintt)
{
uinti;
while(t--)
/*对于12MHz时钟,约延时1ms*/
for(i=0;
i<
125;
i++)
{}
}
/*-------------------------------------------------
向MAX7219写入字节(8位)
--------------------------------------------------*/
voidSendChar(unsignedcharch)
unsignedchari,temp;
_nop_();
for(i=0;
8;
temp=ch&
0x80;
ch=ch<
<
1;
if(temp)
dis_DIN=1;
dis_CLK=0;
dis_CLK=1;
else
dis_DIN=0;
向MAX7219写入字(16位)
-------------------------------------------------*/
voidWriteWord(unsignedcharaddr,unsignedcharnum)
dis_LOAD=0;
SendChar(addr);
SendChar(num);
dis_LOAD=1;
显示数值
voidDisplay(void)
WriteWord(Digit0,DisBuffer[0]);
WriteWord(Digit1,DisBuffer[1]);
WriteWord(Digit2,DisBuffer[2]);
WriteWord(Digit3,DisBuffer[3]);
MAX7219初始化
voidInitDis(void)
WriteWord(ScanLimit,ScanDigit);
/*设置扫描界限*/
WriteWord(DecodeMode,DecodeDigit);
/*设置译码模式*/
WriteWord(Intensity,IntensityGrade);
/*设置亮度*/
WriteWord(ShutDown,NormalOperation);
/*设置电源工作模式*/
系统上电初始化
voidInitMain(void)
IE=0x00;
/*设置中断允许寄存器*/
IP=0x00;
/*设置中断优先级管理寄存器*/
TH0=0xd8;
/*设定时器初值,10ms*/
TL0=0xf0;
TMOD=0x01;
/*T1定时器模式2,波特率发生器,T0定时器模式1*/
TCON=0x11;
/*设置定时器控制寄存器,INT0设置为边沿触发方式*/
PSW=0x00;
主函数main.c
#include"
MAX7219.H"
sbitADD=P1^0;
/*增加键*/
sbitDEC=P1^1;
/*减少键*/
sbitOPT=P1^2;
/*选择键*/
sbitENS=P1^3;
/*确定键*/
sbitT0CLK=P3^4;
/*脉冲计数引脚*/
sbitCLK=P1^7;
/*PWM脉冲*/
#defineucharunsignedchar
#definePWMT10000
floatSet=0;
//设定转速
floatt=0;
//控制转速
floatt1=0;
unsignedlongintx=0;
//中断次数
floatspeed=0;
//检测转速
floatek=0;
//e(k)
floatek1=0;
//e(k-1)
floatKp=0;
//比例系数
floatKi=0.5;
//积分系数
uintkey()//检测按键
{
uintkey_state=ADD&
&
DEC&
OPT&
ENS;
if(key_state)return0;
//如果没有键被按下,返回0
elseif(ADD==0)return1;
//如果增加键被按下,返回1
elseif(DEC==0)return2;
//如果减少键被按下,返回2
elseif(OPT==0)return3;
//如果选择键被按下,返回3
elsereturn4;
//如果确定键被按下,返回4
}
voidtimer1(void)interrupt3//中断服务,返回值 函数名 interruptn,其中n对应中断源的编号,其值从0开始,以80C51单片机为例,编号从0~4,分别对应外中断0、定时器0中断、外中断1、定时器1中断和串行口中断。
CLK=!
CLK;
t=PWMT-t;
//使脉冲周期固定为PWMT
if(CLK==1)
t=t1;
x++;
if(x%200==0)
{
speed=(TH0*256+TL0)*60;
//每隔1秒检测一次转速
ek1=ek;
ek=Set-speed;
t=t+Kp*(ek-ek1)+Ki*ek;
//PI调节
if(t<
0)
t=0;
if(t>
PWMT)
t=PWMT;
t1=t;
TH0=0;
TL0=0;
//重置计数器
CLK=1;
}
TH1=-(int)t/256;
TL1=-(int)t%256;
voidmain()
unsignedinti,j,k;
//i表示数码管数组的下标,t表示设定的转速
InitMain();
InitDis();
WriteWord(DisplayTest,TestMode);
WriteWord(DisplayTest,TextEnd);
//初始化
for(j=0;
j<
4;
j++)
WriteWord(Digit[j],0);
//刚加电时,显示0000
CLK=0;
//T1定时t秒
TH0=0;
//T0从0开始计数
TL0=0;
TMOD=0x15;
//T1定时模式1,T0计数模式1
EA=0;
ET1=1;
ET0=1;
TR1=1;
TR0=1;
while
(1)
for(j=0;
OPT==0;
)//当选择键按下时开始设置
{
for(;
){delay(10);
i=0;
for(;
ADD&
ENS==1;
)//0号数码管闪烁直到有键按下
{
WriteWord(Digit[i],0x5f);
delay(200);
WriteWord(Digit[i],DisBuffer[i]);
}
loop:
k=key();
//检测按键
if(k==0)
{
gotoloop;
//若无键按下,则继续检测
}
elseif(k==1)//如果增加键被按下,返回值为1
DisBuffer[i]=(DisBuffer[i]+1)%10;
//当前数组元素加一
//显示当前数组元素
for(;
ADD==0;
)//数码管闪烁直到有键按下
{
WriteWord(Digit[i],0x5f);
}
elseif(k==2)//如果减少键被按下,返回值为2
{
if(DisBuffer[i]==0)
DisBuffer[i]+=10;
DisBuffer[i]=DisBuffer[i]-1;
//当前数组元素减一,以10为周期循环
DEC==0;
gotoloop;
elseif(k==3)//如果选择键被按下,返回值为3
i=(i+1)%