直流电机控制器的设计.docx

上传人:b****8 文档编号:30576373 上传时间:2023-08-16 格式:DOCX 页数:22 大小:96.25KB
下载 相关 举报
直流电机控制器的设计.docx_第1页
第1页 / 共22页
直流电机控制器的设计.docx_第2页
第2页 / 共22页
直流电机控制器的设计.docx_第3页
第3页 / 共22页
直流电机控制器的设计.docx_第4页
第4页 / 共22页
直流电机控制器的设计.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

直流电机控制器的设计.docx

《直流电机控制器的设计.docx》由会员分享,可在线阅读,更多相关《直流电机控制器的设计.docx(22页珍藏版)》请在冰豆网上搜索。

直流电机控制器的设计.docx

直流电机控制器的设计

 

直流电机控制器

(华侨大学信息学院08自动化)

 

摘要目前见到的许多关于直流电机的测速与控制类文献中,虽然能实现直流电机的无级调速,但还存在一些问题,如无法与计算机直接接口,许多较为复杂的控制算法无法在不增加硬件成本的情况下实现,控制器的人机界面不理想。

总的来讲,控制器的智能化程度不高,可移植性差。

虽然采用PWM芯片来实现电机无级调速的方案成本较低,但当控制器针对不同的应用场合增加多种附加功能时,其灵活性不够,而且反而增加硬件的成本。

还有一些使用PLC控制器或高档处理器芯片(如DSP器件)的文献,它们虽然具有较高的控制性能,但由于这些高档处理器价格过高,需要更多的外围器件,因此也不具备在通常情况下大规模使用的条件。

从发展趋势上看,总体的研究方向是提出质量更高的算法和调速方案,以及在考虑成本要求的前提下选择适合这种算法的核心控制器。

本设计采用MCU(AT89S52),完成了小型直流电机转速的采集、计算、显示、键盘设定,采用直流电机的PWM调速,实现了对电机转速的测量和控制,解决了通常低采样周期时系统的超调以及积分饱和问题。

关键词单片机;转速;调速;显示

 

一、设计任务与要求

1、设计任务

设计并制作一个直流电机控制器,控制电机的转速、转向和转速显示(用数码管动态显示)。

2、技术指标

a.基本要求

(1)具有转速显示功能(在同一CPU上,并留有测试点)。

(2)具有转向控制功能。

(3)可任意定义并控制转速。

(4)转速范围在60~600转/分钟之间连续可调。

(5)可显示任一时刻的占空比。

(6)任何时候控制信号无明显跳变。

b.发挥部分

(1)转速范围扩展至30~800转/分钟之间连续可调。

(2)可按步进.30转调整转速。

(3)用键盘输入任意占空比控制电机(大于60转/分),该状态下仍可按步进.10转调整转速。

3、题目评析

本题的重点是实现转速的可调可控;难点在于电机的驱动以及控制的算法;由于电机的广泛应用,实现电机的调速控制,实用价值很大。

二、方案比较与论证

根据设计任务,需要设计一个直流电机控制系统。

该系统采用脉宽调速,使电机速度等于设定值,并且实时显示电机的转速值。

通过对设计功能分解,设计方案论证可以分为:

速度测量方案论证,电机驱动方案论证,键盘显示方案论证,PWM软件实现方案论证。

1、转速测量方案论证

方案一:

使用红外对射管测速。

硬件简单,只要使用两个电阻,一个红外对管,即可完成要求。

方案二:

使用红外反射管测速。

硬件需要电压比较器,使得硬件电路板比较繁琐。

2、电机驱动方案论证

方案一:

采用专用小型直流电机驱动芯片。

这个方案的优点是驱动电路简单,几乎不添加其它外围元件就可以实现稳定的控制,使得驱动电路功耗相对较小,而且目前市场上此类芯片种类齐全,价格也比较便宜。

方案二:

采用继电器对电动机的开或关进行控制,通过开关的切换对电机的速度进行调整。

这个方案的优点是电路较为简单,缺点是继电器的响应时间慢、机械结构易损坏、寿命较短、可靠性不高。

方案三:

采用由达林顿管组成的H型PWM电路。

用单片机控制达林顿管使之工作在占空比可调的开关状态,精确调整电动机转速。

这种电路由于工作在管子的饱和截止模式下,效率非常高;H型电路保证了可以简单地实现转速和方向的控制;电子开关的速度很快,稳定性也极佳,是一种广泛采用的PWM调速技术。

本次设计不得使用专用模块,所以本设计采用方案三。

3、键盘显示方案论证

方案一:

采用4×4键盘,可直接输入设定值。

显示部分使用8位数码管,优点是显示数据充分,缺点是功耗大,动态显示耗时长。

方案二:

使用4个按键,进行逐位设置,操作繁琐。

显示部分是使用LCD,优点是功耗低,软件编程简单,不符合题目要求。

根据设计要求,本设计采用方案一。

4、PWM软件实现方案论证

脉宽调制的方式有三种:

定频调宽、定宽调频和调宽调频。

本设计采用了定频调宽方式,采用这种方式的优点是电动机在运转时比较稳定,并且在采用单片机产生PWM脉冲的软件实现上比较方便。

对于实现方式则有两种方案。

方案一:

采用定时器做为脉宽控制的定时方式,这一方式产生的脉冲宽度极其精确,误差只在几个us。

方案二:

采用软件延时方式,这一方式在精度上不及方案一,特别是在引入中断后,将有一定的误差。

但是基于不占用定时器资源,且对于直流电机,采用软件延时所产生的定时误差在允许范围。

因此选择方案一。

三、硬件部分总体框图:

系统原理框图如图所示,是一个带键盘输入和数码管动态显示测量控制系统。

主体思想是通过系统设定信息计算输出控制信息。

 

图1整机框图

4、各模块的分析、计算与硬件电路设计

1、速度测量电路的设计

1.1转速/频率转换电路的设计

理论上,是先将转速转化为某一种电量来测量,如电压,电流等。

设计中将转速测量转化为电脉冲频率的测量。

基于这一思想,在电机转轮剪成锯齿型,,总共有八个齿,这样,每转一圈,三级管(红外接收头)透光导通八次,OUT端变化十六次,即完成了转速/频率的转换。

1.2电机驱动电路的设计

 

图2电机驱动原理图

1.4LED数码管显示电路的设计

 

图3LED数码管显示电路

1.54×4矩阵键盘的设计

矩阵键盘又称为行列式键盘,它是用4条I/O线作为行线,4条I/O线作为列线组成的键盘。

在行线和列线的每一个交叉点上,设置一个按键。

这样键盘中按键的个数是4×4个。

这种行列式键盘结构能够有效地提高单片机系统中I/O口的利用率。

图为矩阵键盘电路图,行线接P1.4-P1.7,列线接P1.0-P1.3。

图4矩阵键盘电路

图5按键排列

键盘程序设计的任务是赋予各按键相应的功能,完成速度设定值的输入和向控制器的发送。

0~9作为占空比数字键输出;

A:

正转命令;B:

反转命令;C:

占空比输入命令键;D:

步进0.3rpm键;

E:

步进0.1rpm键;F:

stop键

5、

程序流程框图

 

 

五、结束语

本设计完成了设计的基本要求和扩展要求,由于所使用的直流电机的启动速度在200转/分左右,所以电机的转速测量控制范围为30~800转/分。

另外,参数的确定需要反复的实验观测,所以本系统的各参数设置不一定都是较理想的选择,但系统稳定时控制精度可达1转/分。

根据实际需要,若要进一步提高系统控制的反映速度、精确度和稳定度还需要设计更稳定和精确的转速测量电路以及设置更准确的参数。

附录1主要元器件清单

类型

型号

数量

MCU

AT89S52

1

晶振

12MHz

1

电解电容

10UF

4

光耦

2

电感

100UH

2

瓷片电容

104

4

22PF

2

三极管

772

2

882

2

8050

4

9012

2

电阻

10K

20

芯片

74LS245

2

数码管

共阳

8

二极管

1N4007

2

排阻

10K

4

开关

微动

17

自锁

1

红外对管

1

发光二极管

3

排针

若干

导线

若干

附录2程序清单

#include

#defineucharunsignedchar

#defineuintunsignedint

ucharcodekey_code[]=

{0xee,0xed,0xeb,0xe7,0xde,0xdd,0xdb,0xd7,

0xbe,0xbd,0xbb,0xb7,0x7e,0x7d,0x7b,0x77};

ucharcodedispcode[]=

{0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,

0x6F,0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,

0xFF,0xEF,0x63,0x5c,0x00,0x40,0x01,0x08};

//定义共阴极字型码0123456789-0.1.2.3....20口,21口,22消隐,23-,24上-,25下-

sbitZZ=P3^0;//控制端

sbitFZ=P3^1;//控制端

sbitCE=P3^2;//测速

sbitHW=P3^3;//控制端

voidinit_sys(void);

voidfanzh();

voidzhenzh();

voidstop();

voidset_z();

voidset_s3();

voidset_s1();

ucharZKB1,ZKB2,pwm1,pwm2,Key,ZKB,biao,biao1,hui,MM;

uintsudu=0,count,zhong,hui1;

/***********************************************

延时子函数

***********************************************/

voiddelayms(uintms)

{

uchart;

while(ms--)

{

for(t=0;t<100;t++);

}

}

/***********************************************

显示子函数

***********************************************/

voiddisplay(uchari,uintj)

{

P2=0xfe;

P0=dispcode[i/10];

delayms(3);

P0=0x00;

P2=0xfd;

P0=dispcode[i%10];

delayms(3);

P0=0x00;

P2=0xfb;

P0=biao1;

delayms(3);

P0=0x00;

P2=0xf7;

P0=biao;

delayms(3);

P0=0x00;

P2=0xef;

P0=dispcode[j/1000];

delayms(3);

P0=0x00;

P2=0xdf;

P0=dispcode[j%1000/100];

delayms(3);

P0=0x00;

P2=0xbf;

P0=dispcode[j%1000%100/10+10];

delayms(3);

P0=0x00;

P2=0x7f;

P0=dispcode[j%1000%100%10];

delayms(3);

}

/***********************************************键盘扫描子函数

***********************************************/

ucharkeyscan()

{

ucharscan1,scan2,keycode,j;

P1=0xf0;

scan1=P1;

if((scan1&0xf0)!

=0xf0)//判键是否按下

{

display(ZKB,sudu);//延时30ms

display(ZKB,sudu);

scan1=P1;

if((scan1&0xf0)!

=0xf0)//二次判键是否按下

{

P1=0x0f;

scan2=P1;

keycode=scan1|scan2;//组合成键编码

for(j=0;j<=15;j++)

{

if(keycode==key_code[j])//查表得键值

{

Key=j;

return(Key);

}

}

}

}

elseP1=0xff;

return(16);

}

/***********************************************

判键是否按下子函数

***********************************************/

voidkeydown()

{

P1=0xf0;

if((P1&0xf0)!

=0xf0)

{

keyscan();}

}

/***********************************************

按键功能

**********************************************/

voidKeyfic(ucharkey)

{

switch(key)

{

case0x0a:

zhenzh();break;

case0x0b:

fanzh();break;

case0x0c:

set_z();break;

case0x0d:

set_s3();break;

case0x0e:

set_s1();break;

case0x0f:

stop();break;

default:

break;

}

}

/***********************************************

按键功能

***********************************************/

ucharshuchu(uchari)

{

if(Key<10)

{

hui=i%10*10+Key;

Key=16;

return(hui);

}

}

voidset_z()

{

Key=16;

while(Key!

=0x0c)

{

biao1=dispcode[23];

display(ZKB,sudu);

ZKB=shuchu(ZKB);

keydown();

if(Key==0x0a)

zhenzh();

if(Key==0x0b)

fanzh();

}

biao1=dispcode[22];

Key=16;

}

voidzhenzh()

{

biao=dispcode[20];

ZKB2=ZKB/2+50;

ZKB1=100-ZKB2;

}

voidfanzh()

{

biao=dispcode[21];

ZKB1=ZKB/2+50;

ZKB2=100-ZKB1;

}

voidstop()

{

ZKB1=50;

ZKB2=100-ZKB1;

biao=dispcode[22];

ZKB=0;

}

voidset_s3()

{

uintsudu1;

sudu1=sudu;

while(Key!

=0x0f)

{

Key=16;

biao1=dispcode[24];

display(ZKB,sudu1);

keydown();

display(ZKB,sudu1);

keydown();

display(ZKB,sudu1);

keydown();

if(Key==0x0d)

sudu1+=3;

if(sudu1>sudu)

{

display(ZKB,sudu1);

ZKB++;

if(ZKB>=99)ZKB=0;

ZKB2=ZKB/2+50;

ZKB1=100-ZKB2;

}

else

{

display(ZKB,sudu1);

ZKB--;

if(ZKB<=0)ZKB=99;

ZKB2=ZKB/2+50;

ZKB1=100-ZKB2;

}

if(HW==0)

{

while(HW==0)

{

EA=0;

ZZ=0;

FZ=0;

}

EA=1;

}

}

biao1=dispcode[22];

}

voidset_s1()

{

uintsudu2;

sudu2=sudu;

while(Key!

=0x0f)

{

Key=16;

biao1=dispcode[25];

display(ZKB,sudu2);

keydown();

display(ZKB,sudu2);

keydown();

display(ZKB,sudu2);

keydown();

if(Key==0x0E)

sudu2++;

if(sudu2>sudu)

{

display(ZKB,sudu2);

ZKB++;

if(ZKB>=99)ZKB=0;

ZKB2=ZKB/2+50;

ZKB1=100-ZKB2;

}

else

{

display(ZKB,sudu2);

ZKB--;

if(ZKB<=0)ZKB=99;

ZKB2=ZKB/2+50;

ZKB1=100-ZKB2;

}

if(HW==0)

{

while(HW==0)

{

EA=0;

ZZ=0;

FZ=0;

}

EA=1;

}

}

biao1=dispcode[22];

}

/***************************************

主程序

*****************************************/

voidmain(void)

{

init_sys();

ZKB1=50;

ZKB2=50;

CE=1;

while

(1)

{

display(ZKB,sudu);

keydown();

Keyfic(Key);

if(HW==0)

{

while(HW==0)

{

EA=0;

ZZ=0;

FZ=0;

}

EA=1;

}

}

}

/***********************************************

初始化,包括定时器初始化和变量初始化

***********************************************/

voidinit_sys(void)

{

/***************************************

定时器初始化

****************************************/

TMOD=0X01;

TH0=0XFF;

TL0=0X9B;

TR0=1;

ET0=1;

EA=1;

}

/***********************************************

中断函数

***********************************************/

voidtimer0(void)interrupt1using2

{

staticucharclick=0;

staticuintcount=0;

TH0=0XFF;

TL0=0X9B;

++click;

if(click>=100)click=0;

if(click<=ZKB1)

ZZ=0;

else

ZZ=1;

if(click<=ZKB2)

FZ=0;

else

FZ=1;

count++;

if(MM==~CE)

{

MM=CE;

zhong++;

}

if(count>=5000)

{

count=0;

sudu=zhong*2/16*60;

zhong=0;

}

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1