1、则增量式控制算法为 :其中Kp为控制器比例系数,Ki为积分时间常数。 由于系统采用了比例积分调节器 (简称 PI调节器),使系统在扰动的作用下,通过 PI调节器的调节作用使电动机的转速达到静态无差,从而实现了静态无差。无静差调速系统中,比例积分调节器的比例部分使动态响应比较快(无滞后),积分部分使系统消除静差。第二章 硬件设计与分析在对直流电机调速系统有个清楚的认识后,对本系统进行硬件设计。整个系统以89C52单片机为核心,包括主回路,驱动电路,测速电路,按键显示电路。2.1 系统硬件组成图21为该系统硬件电路设计框图。根据本系统要求通过软件编程定义键盘各键的功能及显示控制。有关驱动及主回路控
2、制电路见下几节。整个系统控制过程为:键盘输入控制信号、参数及速度给定值,单片机经过速度闭环、 运算,控制P口(自行定义)输出脉冲的占空比,从而控制电机的转速,并经显示电路显示出来。图21 系统硬件框图2.2 驱动控制电路驱动控制电路见图23。将单片机软件产生的PWM信号经并联使用的施密特反相器,对IGBT进行驱动。图22 驱动控制电路2.3 主回路控制电路主电路控制电路见图22。220交流电压经过桥式整流电路的整流,再经过电容滤波,经过IGBT元件的功率放大,加到直流电机的两端控制电机。图23 主电路控制电路2.4测速电路测速电路见图24。图24 测速电路2.5 显示及按键电路显示电路见图2-
3、5。选用共阴8段数码管,采用MAX7219驱动。MAX7219是一种高集成化的串行输入/输出的共阴极LED显示驱动器。每片可驱动8位7段加小数点的共阴极数码管,可以数片级联,而与微处理器的连接只需3根线。MAX7219内部设有扫描电路,除了更新显示数据时从单片机接收数据外,平时独立工作,极大地节省了MCU有限的运行时间和程序资源。MAX7219芯片上包括BCD译码器、多位扫描电路、段驱动器、位驱动器和用于存放每个数据位的88静态RAM以及数个工作寄存器。通过指令设置这些工作寄存器,可以使MAX7219进入不同的工作状态。MAX7219的详细资料请参考其他书籍,这里不再赘述。图2-5 MAX72
4、19驱动显示电路按键电路见图26。 52单片机的P口在悬空时默认是高电平,每个按钮通过一个上拉电阻接到5V电源,按下按钮,则P口变成低电平,这样就可以通过P口的状态来反映按钮的按下情况。按键通过并联电容C进行防抖动,无需通过软件部分实现。 图26第三章 软件设计与分析软件设计是本系统的难点也是重点,最终直流电机控制系统的好坏,很大程度上是由软件程序的优良决定的。通过硬件的设计部分可知,软件程序主要包括:按键程序,显示程序,PWM产生程序,测速程序以及PI调节程序。在编写程序的过程中,运用工程化思想,从总体出发,由易到难,这样才能高质高效的完成软件设计的任务。采用C语言而不是汇编语言,因为C语言
5、方便使用,而且移植性好,更容易入手,有利于各个功能部分的实现。3.1 按键功能按键的判断是通过检测P口的高低电平来实现的,有键按下,相应的P口就为低电平。值得注意的是,按键程序必须防止误操作,也就是要加入防抖动功能。我们采用的是串联电容接地实现防抖动功能,无需软件实现。按键程序流程图见图31。图31 按键程序流程图3.2 显示功能LED灯可以由单片机的P口经过放大后直接驱动点亮,但是这样做不仅硬件设计繁琐,而且也增加了软件设计的负担,这里采用专用芯片MAX7219驱动LED灯,可以很方便的完成显示功能。软件部分除了对MAX7219初始化功能需要编程外,重点是LED灯怎样和按键配合准确地显示。本
6、系统要实现按键和显示配合的功能如下:按下增加(减少)键,LED显示09相应的增加(减少);按下选择键,可以循环控制不同位置的LED灯;按下确认键,LED显示设定的数值。而且要求没有按键时,待按键对应的LED灯闪烁变化,确认键按下后,LED不闪烁。设定好的数值还要反馈到单片机中进行相应的运算控制以调节系统,测速电路测得的转速也应该通过显示功能电路显示出来,而且同时在一边另外的LED灯中显示设定转速,以和实际转速进行对比。显示程序流程图见图32。图32 显示程序流程图3.3 PWM波产生和电机测速功能 在脉冲作用下,当电机通电时,速度增加;电机断电时,速度逐渐减少。只要按一定规律改变通、断电的时间
7、,即可让电机转速得到控制。PWM波产生的思想是,固定PWM的周期为PWMT,t时间内输出高电平,则剩下PWMT-t时间就输出低电平。通过控制定时器T1,从而可以实现从8051的任意输出口输出不同占空比的脉冲波形。由于PWM信号软件实现的核心是单片机内部的定时器,而不同单片机的定时器具有不同的特点,即使是同一台单片机由于选用的晶振不同,选择的定时器工作方式不同,其定时器的定时初值与定时时间的关系也不同。因此,首先必须明确定时器的定时初值与定时时间的关系。如果单片机的时钟频率为f,定时器/计数器为N位,则定时器初值与定时时间的关系为:式中,Tw 定时器定时初值;N 一个机器周期的时钟数。N随着机型
8、的不同而不同。在应用中,应根据具体的机型给出相应的值。这样,我们可以通过设定不同的定时初值Tw,从而改变占空比D,进而达到控制电机转速的目的。此次实验采用12MHz晶振,计数频率为1MHz,即每微秒计数器加一,设置PMW脉冲周期固定为PWMT=10000,即0.01s。 在实际的直流电机调速系统中,电机的测速由测速电机完成,本次实验系统,由电机自带的霍尔元件完成测速,电机每转一圈,霍尔元件就送出一个脉冲,我们设计的程序是将测速部分嵌套在PWM函数里,这样就节省了一个定时器资源。PWM脉冲周期为0.01s,一个周期定时器T1中断2次,设置定时器每中断200次,即每1s对电机进行一次测速,测速完毕
9、后计数器T0归零,重新对霍尔脉冲计数。PWM和测速程序流程图见图33。图33 PWM和测速程序流程图3.5 PI调节功能 本系统功率、电压环PI算法均采用积分分离增量式位置输出算法。程序框图如图35所示。图3-5PI算法程序流程图图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#include /*-*/#define uchar unsigned ch
10、ar #define uint unsigned intsbit dis_DIN=P00; /*显示串行数据输入端*/sbit dis_LOAD=P01; /*显示数据锁存端*/sbit dis_CLK=P02; /*显示时钟输入端*/#define NoOp 0x00 /*空操作*/#define Digit0 0x01 /*数码管1*/#define Digit1 0x02 /*数码管2*/#define Digit2 0x03 /*数码管3*/#define Digit3 0x04 /*数码管4*/#define DecodeMode 0x09 /*译码模式*/#define Inten
11、sity 0x0a /*亮度*/#define ScanLimit 0x0b /*扫描界限*/#define ShutDown 0x0c /*掉电模式*/#define DisplayTest 0x0f /*显示测试*/#define ShutdownMode 0x00 /*掉电方式工作*/#define NormalOperation 0x01 /*正常操作方式*/#define DecodeDigit 0xff /*译码位数设置*/#define IntensityGrade 0x0a /*显示亮度级别设置*/#define ScanDigit 0x07 /*扫描位数设置*/#define
12、 TestMode 0x01 /*显示测试方式*/#define TextEnd 0x00 /*显示测试结束,正常工作*/unsigned int data DisBuffer4=0,0,0,0; /*显示缓存区*/uchar Digit4=Digit0,Digit1,Digit2,Digit3; /*数码管缓存区*/unsigned char code dispaly_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,0x
13、67,0x3e,0xff,0x5f; /*A,B,C,D,E,F,P,U,全亮,全灭*/*- 延时t毫秒子程序-*/void delay(uint t) uint i; while(t-) /*对于12MHz时钟,约延时1ms*/ for(i=0;i125;i+) /*- 向MAX7219写入字节(8位)-*/void SendChar (unsigned char ch) unsigned char i,temp; _nop_(); for (i=0;8; temp=ch&0x80; ch=ch1; if(temp) dis_DIN=1; dis_CLK=0; dis_CLK=1; else
14、 dis_DIN=0; 向MAX7219写入字(16位)-*/void WriteWord (unsigned char addr,unsigned char num) dis_LOAD=0; SendChar (addr); SendChar (num); dis_LOAD=1; 显示数值void Display (void) WriteWord (Digit0,DisBuffer0); WriteWord (Digit1,DisBuffer1); WriteWord (Digit2,DisBuffer2); WriteWord (Digit3,DisBuffer3); MAX7219初始化
15、void InitDis (void) WriteWord (ScanLimit,ScanDigit); /*设置扫描界限*/ WriteWord (DecodeMode,DecodeDigit); /*设置译码模式*/ WriteWord (Intensity,IntensityGrade); /*设置亮度*/ WriteWord (ShutDown,NormalOperation); /*设置电源工作模式*/ 系统上电初始化void InitMain (void) IE=0x00; /*设置中断允许寄存器*/ IP=0x00; /*设置中断优先级管理寄存器*/ TH0=0xd8; /*设定
16、时器初值,10ms*/ TL0=0xf0; TMOD=0x01; /*T1 定时器模式2,波特率发生器,T0 定时器模式1*/ TCON=0x11; /*设置定时器控制寄存器,INT0设置为边沿触发方式*/ PSW=0x00;主函数main.c#include MAX7219.Hsbit ADD=P10; /*增加键*/sbit DEC=P11; /*减少键*/sbit OPT=P12; /*选择键*/sbit ENS=P13; /*确定键*/sbit T0CLK=P34; /*脉冲计数引脚*/sbit CLK=P17; /*PWM脉冲*/#define uchar unsigned char
17、#define PWMT 10000 float Set=0; /设定转速float t=0; /控制转速float t1=0;unsigned long int x=0; /中断次数float speed=0; /检测转速float ek=0; /e(k)float ek1=0; /e(k-1)float Kp=0; /比例系数float Ki=0.5; /积分系数uint key() /检测按键 uint key_state=ADD&DEC&OPT&ENS; if(key_state) return 0; /如果没有键被按下,返回0 else if(ADD=0) return 1; /如果
18、增加键被按下,返回1 else if(DEC=0) return 2; /如果减少键被按下,返回2 else if(OPT=0) return 3; /如果选择键被按下,返回3 else return 4; /如果确定键被按下,返回4void timer1(void) interrupt 3 /中断服务,返回值函数名interrupt n ,其中n对应中断源的编号,其值从0开始,以80C51单片机为例,编号从04,分别对应外中断0、定时器0中断、外中断1、定时器1中断和串行口中断。 CLK=!CLK; t=PWMT-t; /使脉冲周期固定为PWMT if(CLK=1) t=t1; x+; if
19、(x%200=0) speed=(TH0*256+TL0)*60; /每隔1秒检测一次转速 ek1=ek; ek=Set-speed; t=t+Kp*(ek-ek1)+Ki*ek; /PI调节 if(tPWMT) t=PWMT; t1=t; TH0=0; TL0=0; /重置计数器 CLK=1; TH1=-(int)t/256; TL1=-(int)t%256;void main() unsigned int i, j, k; /i表示数码管数组的下标,t表示设定的转速 InitMain (); InitDis (); WriteWord (DisplayTest,TestMode); Wri
20、teWord (DisplayTest,TextEnd); /初始化 for(j=0;j4;j+) WriteWord (Digitj,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 (Digiti,0x5
21、f); delay(200); WriteWord (Digiti,DisBufferi); loop: k=key(); /检测按键 if(k=0) goto loop; /若无键按下,则继续检测 else if(k=1) /如果增加键被按下,返回值为1 DisBufferi=(DisBufferi+1)%10; /当前数组元素加一 /显示当前数组元素 for(;ADD=0;) /数码管闪烁直到有键按下 WriteWord (Digiti,0x5f); else if(k=2) /如果减少键被按下,返回值为2 if(DisBufferi=0) DisBufferi+=10; DisBufferi=DisBufferi-1; /当前数组元素减一,以10为周期循环DEC=0; goto loop; else if(k=3) /如果选择键被按下,返回值为3 i=(i+1)%
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1