基于单片机的直流电机转速PID控制系统设计.docx

上传人:b****4 文档编号:12142463 上传时间:2023-04-17 格式:DOCX 页数:45 大小:466.63KB
下载 相关 举报
基于单片机的直流电机转速PID控制系统设计.docx_第1页
第1页 / 共45页
基于单片机的直流电机转速PID控制系统设计.docx_第2页
第2页 / 共45页
基于单片机的直流电机转速PID控制系统设计.docx_第3页
第3页 / 共45页
基于单片机的直流电机转速PID控制系统设计.docx_第4页
第4页 / 共45页
基于单片机的直流电机转速PID控制系统设计.docx_第5页
第5页 / 共45页
点击查看更多>>
下载资源
资源描述

基于单片机的直流电机转速PID控制系统设计.docx

《基于单片机的直流电机转速PID控制系统设计.docx》由会员分享,可在线阅读,更多相关《基于单片机的直流电机转速PID控制系统设计.docx(45页珍藏版)》请在冰豆网上搜索。

基于单片机的直流电机转速PID控制系统设计.docx

基于单片机的直流电机转速PID控制系统设计

直流电机转速PID控制系统设计

 

学院:

专业班级:

姓名:

学号:

指导老师:

 

单片机原理课程设计任务书

班级:

自动化07姓名:

指导教师:

曹利钢2010年6月7日

设计题目:

基于单片机的直流电机转速PID控制系统设计

设计任务和要求

1.直流电机型号自选

2.对直流电机转速实时显示

3.对转速实现恒值控制

4.转速控制范围:

10%

~90%

,其中

为电机额定转速

5.稳态精度达:

±5r/min。

围aosu

设计成果

设计说明书一份

电路图一份

参考资料

1.胡汉才.单片机原理及接口技术(第2版)[M].北京:

机械工业出版社,2004

2.陈光东,赵性初.单片机微型计算机原理与接口技术(第2版)[M].武汉:

华中科技大学出版社,1999

教研室主任签字:

年月日

第六章课程设计体会………………………………………………39

第七章参考文献……………………………………………………39

 

第一章直流电机工作原理

1.1工作原理

本设计中的电子钟的核心是AT89C51。

硬件电路主要由六部分构成:

PID控制电路、复位电路、键盘电路、显示电路、串行通信电路以及温度检测电路。

PID控制电路是电子钟硬件电路的核心,没有PID控制电路,直流电机无法正常稳定运行。

本系统电路采用的晶振11.0592MHz,一号单片机定时器采用的是定时器0工作在方式2定时,用于实现一定时间的计时,定时时间为10ms。

复位电路可使单片机回复到初始状态。

键盘可实现对直流电机转速的设定及启动的操作。

温度检测是通过DS18B20芯片实现,在温度显示中还要注意数的转换。

在该设计中还用到定时器1工作在方式2用来产生9600的波特率,用在两片单片机之间串行传送数据。

1、外部中断INT1

当电机转一圈时向外部中断进行一次中断计数,从而实现电机转速的测量。

2、一号单片机转速显示

当电机转动时,显示部分可以把电机的设定转速或者是通过通信由温度计算的转速显示出来,同时在右侧部分显示电机当下的转速。

二号单片机的温度显示与之类似。

3、温度测量

温度测量有专门的芯片DS18B20。

DS18B20可编程温度传感器有3个管脚。

GND为接地线,DQ为数据输入输出接口,通过一个较弱的上拉电阻与单片机相连。

VDD为电源接口,既可由数据线提供电源,又可由外部提供电源,范围3.O~5.5V。

当DSI8B20接收到温度转换命令后,开始启动转换。

转换完成后的温度值就以16位带符号扩展的二进制补码形式存储在高速暂存存储器的0,1字节。

单片机可通过单线接口读到该数据,读取时低位在前,高位在后,数据格式以0.0625℃/LSB形式表示。

4、按键选择

一号单片机的键盘采用4×4的按键方式检测按键。

P0、P1口不断扫描按键的行和列从而计算出所选择的数值,进而执行相关的程序。

二号单片机原理类似。

5、直流电机驱动部分

一号单片机根据端口采集到的电机的转速,经过PID计算,通过另一端口发送PWM波,从而使电机改变转速。

1.2、直流电机PID控制原理方框图

图2.2电路连接图

第二章硬件设计与实现

2.1硬件设计

直流电机PID控制电路的核心是两块89C51,用两块89C51作控制是为了电机控制和温度检测互不干扰,其中一块控制电机,另一块实现温度检测。

2.1.1按键电路设计

根据功能需要,本控制电路需要设置一下功能键:

按键设定转速。

在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式,如图1所示。

在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。

这样,一个端口(如P1口)就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,比如再多加一条线就可以构成20键的键盘,而直接用端口线则只能多出一键(9键)。

由此可见,在需要的键数比较多时,采用矩阵法来做键盘是合理的。

矩阵式结构的键盘显然比直接法要复杂一些,识别也要复杂一些,下图中,列线通过电阻接正电源,并将行线所接的单片机的I/O口作为输出端,而列线所接的I/O口则作为输入。

这样,当按键没有按下时,所有的输入端都是高电平,代表无键按下。

行线输出是低电平,一旦有键按下,则输入线就会被拉低,这样,通过读入输入线的状态就可得知是否有键按下了。

图2.1按键电路

参见表2.1。

按键

键名

功能

属性

0~9

设定

设定转速值

自动复位

确定

确定

确定设定值

自动复位

清除

清除

去除设定值

自动复位

运行

运行

开始运行

自动复位

表2.1按键功能表

按键操作说明如下:

0~9键:

通过此按键设定要求电机转速的设定值。

设定过程中数值依次左移,实现百十个位的设定。

确定键:

该键为自动复位键,当设定完成后按确定键就可以使设定值赋给相应变量。

清除键:

清除已经设定的转速值。

运行键:

设定值完毕则可以点此键进行相应的运行。

2.1.2复位电路

复位是单片机的初始化操作,以便使CPU和系统中其他部件都处于一个确定的初始状态,并从这个状态开始工作。

除了进入系统的正常初始化之外,当单片机系统在运行出错或操作错误使系统处于思索状态时,也可按复位键重新启动。

复位后,PC内容初始化为0000H,使单片机从0000H单元开始执行程序。

89C51单片机复位信号的输入端是RST引脚,高电平有效。

RST端的外部复位电路有两种操作方式:

上电自动复位和按键手

动复位。

按键手动复位有电平方式和脉冲方式两种。

本设计用的是按键电平复位时相当于RST端接高电平。

如图2.2所示。

需要注意的是单片机连接了8255A,复位电路也需与8255A的RESET相连。

电路为上电复位电路,它是利用电容充电来实现的。

在接电瞬间,RESET端的电位与VCC相同,随着充电电流的减少,RESET的电位逐渐下降。

只要保证RESET为高电平的时间大于两个机器周期,便能正常复位。

该电路除具有上电复位功能外,若要复位,只需按RESET键,此时电源VCC经电阻R1、R2分压,在RESET端产生一个复位高电平。

2.1.3显示电路

本设计中使用LED数码管显示电机的设定和实际转速以及温度值。

电路设计如下:

 

图2.3转速的显示电路

温度的显示电路在另一个单片机中完成,图相似。

2.1.4温度检测

系统设置了一路温度检测在该系统中,图4.6是一路温度硬件图。

图2.4DS18B20测温原理框图

图2.5温度检测的硬件图

2.1.5串行通讯

该系统用到两片单片机,因此单片机还需要连接串行接口,电路略。

2.1.6晶振电路设计

在AT89S51芯片内部有一个高增益反相放大器,其输入端为芯片引脚XTAL1,输出端为引脚XTAL2。

而在芯片内部,XTAL1和XTAL2之间跨接晶体振荡器和微调电容,从而构成一个稳定的自激振荡器。

时钟电路产生的振荡脉冲经过触发器进行二分频之后,才成为单片机的时钟脉冲信号。

其电路如图2.7。

图2.7晶振电路

2.1.7电机驱动电路

通过端口采集电机转速进而输出PWM波完成电机控制。

PWM(PulseWidthModulation)控制技术就是对脉冲的宽度进行调制的技术,即通过对一系列脉冲的宽度进行调制,来等效的获得所需要的波形(含形状和幅值);面积等效原理是PWM技术的重要基础理论;一种典型的PWM控制波形SPWM:

脉冲的宽度按正弦规律变化而和正弦波等效的PWM波形称为SPWM波。

图2.7电机驱动电路

2.1.8报警电路

当温度过高或者过低时,报警电路会自动报警。

图2.8报警电路

2.2系统面板图

时间控制模块面板图如图2.8,温度测量模块面板图如图2.9。

图2.9直流电机控制模块面板图

图2.10温度测量模块面板图

第三章流程设计

3.1软件设计流程图

3.1.1主程序流程图

电机调试程序流程:

温度测量程序流程:

3.1.2速度显示子程序流程图

图5.2速度显示子程序流程图

3.1.3温度采集程序流程图

3.3温度采集程序流程图3.4报警子程序流程图

3.1.4串行通信接受与发送流程图

第四章程序说明

4.1直流电机部分程序

#include

#defineuintunsignedint

#defineucharunsignedchar

sbitp34=P3^4;

sbitp26=P2^6;

sbitp36=P3^6;

ucharcodetable[]={0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f};

ucharcodechose[]={0x01,0x02,0x04,0x08,0x10,0x20};

uintshu[6]={1,2,3,4,5,6};

ucharq=0,i=0,m=0,n=0;

uintcount,miaoshu,sv,k=0,k2=0,sv1,sv2;//定义计数值,实际温度值,设定的温度值

ucharsec,tcnt,flag,flag1;

intrk,yk,uk,uk_1=0,ek,ek_1=0,ek_2=0;//PID计算参数

signedcharT=20,Kp=30,Td=8,Ti=100,q0,q1,q2;//PID参数其值经反复调试得来

uchardatabuf[4]={0,1,1,1};//字型显示中间变量

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

延时子程序用来产生1ms的延时,用于在程序中的等待

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

//延时1ms子程序

voiddelay(ucharz)

{

ucharx,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

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

显示子程序用来在数码管中显示电机的设定转速或计算转速以及实际转速

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

//显示子程序

voiddisplay(uinta,uintb)

{

chari;

shu[0]=a/100;

shu[1]=a%100/10;

shu[2]=a%10;

shu[3]=b/100;

shu[4]=b%100/10;

shu[5]=b%10;

for(i=0;i<6;i++)

{

P2=chose[i];

P0=table[shu[i]];

delay(5);

}

}

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

定时器中断子程序用来产生0.1秒的中断,以此来测量电机的转速

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

//定时器中断0子程序

voidt0(void)interrupt1using0//定时T0中断服务函数

{

tcnt++;//每过250usttcnt加一

if(tcnt==40)//计满40次(1/100秒)时

{

tcnt=0;//重新再计

sec++;

if(sec==10)//定时0.1秒,在从零开始计时

{

sec=0;

TH0=0x06;//对TH0TL0赋值

TL0=0x06;

miaoshu=count;

count=0;

}

}

}

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

用来记录中断数,从而得到转速

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

voidsdf(void)interrupt2using0//外部中断服务函数

{

count=count+1;

}

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

接收来自另一个单片机的中断并放入一个数组中以便在显示函数中方便调用此数据,其中加了

容错程序,通过一个特殊字符’11’,来区别哪一个是三位数的百位,十位,个位。

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

voidjieshou()//接收子程序

{ucharg;

if(RI==1)

{g=SBUF;

if(g==11)

m=0;

buf[m]=g;

m++;

if(m==4)

m=0;

RI=0;//REN=1;

}

}

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

检测按键值计算对应的数值

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

//左移一位

voidyishu(ucharnum)

{

ucharbai,shi,ge;

bai=sv1%100/10;

shi=sv1%10;

ge=num;

sv1=bai*100+shi*10+ge;

k2=sv1;//xinjia

}

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

检测对应的按键

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

//按键子程序

voidkey()

{

uchari,temp,lie,hang,shu;

for(i=0;i<4;i++)//求出按键值

{

P1=~chose[i];

temp=P1;

temp=temp&0xf0;

if(temp!

=0xf0)

{

hang=i;

if(temp==0xe0)

lie=1;

elseif(temp==0xd0)

lie=2;

elseif(temp==0xb0)

lie=3;

elseif(temp==0x70)

lie=4;

break;

}

}

shu=hang*4+lie;//数为对应的按键

switch(shu)

{

case1:

if(!

flag)yishu(0);break;

case2:

if(!

flag)yishu

(1);break;

case3:

if(!

flag)yishu

(2);break;

case4:

if(!

flag)yishu(3);break;

case5:

if(!

flag)yishu(4);break;

case6:

if(!

flag)yishu(5);break;

case7:

if(!

flag)yishu(6);break;

case8:

if(!

flag)yishu(7);break;

case9:

if(!

flag)yishu(8);break;

case10:

if(!

flag)yishu(9);break;

case11:

flag++;/*flag1++*/;break;

case12:

sv1=0;miaoshu=0;flag=0;flag1=0;break;

case13:

flag1++;break;

default:

break;

}

while(temp!

=0xf0)//放键检测

{

temp=P1;

temp=temp&0xf0;

for(i=0;i<10;i++)

display(sv1,miaoshu);

}

}

//按键检测程序

voidkeyscan()

{

uchartemp;

P1=0xf0;

temp=P1;

temp=temp&0xf0;

if(temp!

=0xf0)

{

delay(5);//消除抖动

P1=0xf0;

temp=P1;

temp=temp&0xf0;

if(temp!

=0xf0)

key();

}

}

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

进行pid的计算,用来在后面的程序中进行电机的闭环控制

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

voidpid(void)//PID计算输出量

{sv2=100*buf[1]+10*buf[2]+buf[3];

if(p26==0)//低电平时正常显示设定值

sv=sv1;

if(p26==1)//高电平时显示通信值

//{if(n==1)

sv=sv2;

//if(n==0)

//sv=k;

//}

ek=sv-miaoshu;

uk=uk_1+q0*ek+q1*ek_1+q2*ek_2;

ek_2=ek_1;

ek_1=ek;

uk_1=uk;

if(uk>501)

uk=501;//限定输出上限

if(uk<1)

uk=1;//限定输出下限

}

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

主函数:

初始化定时器、进行顺序的子程序执行

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

main()

{

q0=Kp*(1+T/Ti+Td/T);//先算出PID的计算参数

q1=-Kp*(1+2*Td/T);

q2=Kp*Td/T;

p34=0;

EX0=1;

IT1=1;

IP=0X00;

TMOD=0x22;//定时器T0工作在方式2自动重装方式,计数器T1工作在方式2自动重装方式

TH0=0x06;//对TH0TL0赋值

TL0=0x06;

TH1=0XFC;

TL1=0XFC;

TR0=1;//开始定时

ET0=1;//允许T0产生中断

TR1=1;

ET1=0;

EA=1;

EX1=1;

EA=1;

//ES=1;

sec=0;

SCON=0x50;//MODER1,REN=1;

PCON=0x00;

miaoshu=0;tcnt=0;count=0;sv=0;

flag=0;

while

(1)

{

keyscan();

jieshou();//xinjia

if(flag==2)

p34=0;

if(flag1==1)

{

//uinti;

pid();

if(ek>100)

{

p34=1;

}

elseif(ek>=0)

{

p34=1;

delay(uk/10);

display(sv,miaoshu);

p34=0;

delay(50-uk/10);

}

//elseif(ek<0)

//p34=0;

}

if(p26==0)

display(sv1,miaoshu);

else

display(sv2,miaoshu);

}

}

4.2温度检测部分程序

#include

#include

#defineucharunsignedchar

#defineuintunsignedint

sbitDATA=P1^1;//DS18B20接入口

ucharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//共阴极字型码

inttemp,temp2;//温度值

intss;//中间的一个变量

intdd;

intj,i0=0,k;

ucharsec,tcnt,flag0,flag1,sec2;

uchardatab;//定时器中断次数

uchardatabuf[4]={0,0,0,0};//字型显示中间变量

uchardatabuf2[4]={11,0,0,0};

intalarmH=500;//默认报警值

intalarmL=-10;

//定义开关的接入口

sbitk1=P2^5;//+

sbitk2=P2^6;//-

sbitk3=P2^7;//确认

sbitk4=P2^4;

sbitbell=P1^0;

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

当前位置:首页 > 工程科技 > 能源化工

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

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