《直流电机PID控制-(重要).doc》由会员分享,可在线阅读,更多相关《直流电机PID控制-(重要).doc(15页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、精品文档,仅供学习与交流,如有侵权请联系网站删除重庆科技学院课程设计报告院(系):_电子信息工程学院_ 专业班级: 测控普07 学生姓名: 程家林 学 号: 2007440762 设计地点(单位)_ 实验楼I512_ _ _ _设计题目:_基于单片机的转速控制系统_ _完成日期: 2010 年 7 月 2 日 指导教师评语: _ _ _ 成绩(五级记分制):_ _ 指导教师(签字):_ _ 【精品文档】第 9 页目录1.设计题目12.设计内容13.方案总体设计与论证14.硬件电路设计24.1最小系统设计24.2传感器模块24.3负载模块34.4键盘模块44.5显示模块45.软件设计55.1主函
2、数部分55.2中断部分65.3 显示刷新部分65.4 按键扫描部分75.5 按键功能实现部分85.6更新输出控制信号部分95.7PID控制部分105.8LCD显示部分115.9延时部分116.系统调试127.结 束 语128.参考文献12附录一系统硬件原理图13附录二源程序代码14摘要本文章介绍了由51单片机以及直流电机、三极管驱动电路、矩阵键盘、LCD和红外传感器构成的转速闭环控制系统。其中红外传感器负责对电机转速进行测量,并将测量的结果反馈给控制中心,并由控制中心将之与设定值进行比较得到偏差,再由偏差产生直接控制作用去消除偏差。文章不但介绍了基于单片机的转速控制系统的软件设计,还涉及了硬件
3、设计方法。文中介绍系统不但可以实现手动控制,还有无人值守,自动调速功能。关键词直流电机 闭环控制 单片机 矩阵键盘 LCD重庆科技学院课程设计任务书设计题目:基于单片机的转速控制系统设计学生姓名程家林课程名称智能义器义表设计与调试专业班级测控普07地 点实验楼I512起止时间2010.6.21至2010.7.2设计内容及要求要求设计的转速控制系统完成以下功能:1.基本功能按键设定并显示转速,实时显示实际转速按键控制电机起停、正反转PWM转速闭环控制。2. 扩展功能 实现与PC机的通讯:将转速的设定值和实测值发送到PC机显示,PC机可以设定速度,发送到单片机设计参数1.转速调节范围:1500转/
4、分-3000转/分2.测速误差10%进度要求1. 布置任务、方案设计,硬件设计(1天)2. 画电路图(1天)3. 软件设计,画流程图(1天)4. 程序设计和调试(6天)5. 设计验收、撰写报告(1天)详见进度安排表参考资料1.程德福.智能义器. 机械工业出版社. 2009.92.胡文金.单片机系统实训教程.重庆:重庆大学出版社,20053.林金阳.基于MC51单片机的直流电机PWM调速系统.长春工程学院学报(自然科学版)2009年第10卷第3期其它说明.本表应在每次实施前一周由负责教师填写二份,院系审批后交院系办备案,一份由负责教师留用。.若填写内容较多可另纸附后。3.一题多名学生共用的,在设
5、计内容、参数、要求等方面应有所区别。教研室主任: 指导教师:钟秉翔、张义辉基于单片机的转速控制系统设计1.设计题目基于单片机的转速控制系统设计2.设计内容设计的转速控制系统完成以下功能:a) 基本功能按键设定并显示转速,实时显示实际转速按键控制电机起停、正反转PWM转速闭环控制。b) 扩展功能实现与PC机的通讯:将转速的设定值和实测值发送到PC机显示,PC机可以设定速度,发送到单片机3.方案总体设计与论证图1是基于单片机的转速控制系统的基本组成方框。主要由测速传感器(红外对管),电机及驱动电路,矩阵键盘,LCD(12864),单片机(80C51)组成。测速传感器是把电机转速转换成相应的脉冲量的
6、器件,并将该脉冲送给单片机计数。测速传感器输出脉冲的频率随电机转速的快慢变化而变化。单片机8051是该系统的核心部分,一方面负责计算电机的转速,另一方面将计算得到的转速与设定转速相比较,经过计算处理,得到相应的控制信号(PWM),并用该信号控制电机转速。通过键盘可以设定手动工作模式(通过操作人员修改输出方波占空比实现)或者自动工作模式(由操作人员输入设定转速,单片机自动控制电机转速,使其接近设定值),输入输出方波占空比以及设定转速。由单片机检测哪一个按键按下,实现占空比或者设定值的修改,并通过LCD实时显示设定值以及测得转速。图1系统框图由上图可知系统硬件基本上由传感器模块,负载模块,键盘模块
7、,显示模块组成。而软件设计是紧紧围绕系统的硬件结构展开的,软件主要是配合控制硬件完成预期的设计要求,软件的基本模块也是针对上述硬件结构进行相应操作的。下面具体阐述系统各功能模块的设计。4.硬件电路设计4.1最小系统设计本次设计中的最小系统模块中包括CPU、复位电路和晶振,其最小系统原理图如图4.1所示。图4.1最小系统原理图4.2传感器模块本次设计中测速传感器选用红外对管,其有一个红外发射管一个红外接收管。发射管和接收管位于同一平面,当其发射出的红外遇到风扇的叶片时,红外接收管接收到反射回来的信号,输出一个脉冲,该脉冲作用于单片机的P32引脚,在单片机的外部中断0中进行计数。其硬件图如图4.2
8、所示。图4.2红外对管测速传感器硬件原理图4.3负载模块该模块主要由一个直流电机和一个电机驱动组成,该驱动为三极管驱动,由单片机的P13引脚输出控制。该模块中的二极管D1在电机断电后起释放电机能量的作用。该电机的控制算法为PID控制算法,控制系统为闭环控制系统。该负载模块的硬件原理图如图4.3所示。图4.3负载模块硬件原理图4.4键盘模块本次设计中采用的4*4的非编码键盘。矩阵式非编码键盘的电路原理图如图4.4所示。当没有键按下时,行线和列线之间是不相连。若第N行第M列的键被按下,那么第N行与第M列的线就被接通。如果在行线上加上信号,根据列线的状态,便可得知是否有键按下。如果在行线上逐行加上一
9、个扫描信号(本实验中用的低电平),就可以判断按键的位置。常用的按键识别有两种方法:一种是传统的行扫描法;另一种是速度较快的线反转法。本实验中采用的是线反转法进行识键。图4.4键盘模块硬件原理图4.5显示模块本设计采用ST7920控制器的LCD液晶显示器,其具有低电压,字迹清晰、能够显示汉字和字符等特点,且编程方便,易于查看、修改。本实验中主要用到了VSS、VDD、RS、RW、CS引脚。ST7920液晶显示器与MCU接口电路原理图如图4.5所示。图4.5显示模块硬件原理图5.软件设计5.1主函数部分该函数首先初始化定时器0和外部中断0,然后判断启动键是否按下,如果按下则控制LCD显示数据,如果启
10、动键没有按下,则继续等待。程序执行过程中,主要通过循环扫描各标志位,如果设定速度、工作模式或者电机实时转速有所改动,就刷新LCD显示。如果按键扫描标志位允许进行按键扫描即进行按键扫描。如果有按键按下就进行相应的按键指定功能实现。主函数流程图如图5.1所示。图5.1主函数流程图5.2中断部分本次设计中主要用到了定时器0和外部中断0。中断部分的流程图如图5.2所示。定时器主要用于控制PWM输出以及控制按键扫描函数的启动,采样周期,控制周期等和时间密切相关的函数。外部中断主要用于数脉冲输入的个数。由定时器控制取值并清零的时间。在一定的时间内采集到和电机转速相关的脉冲数,就可以计算出电机的转速。a)定
11、时器0中断流程图 b)外部中断流程图 图5.2中断流程图5.3显示刷新部分该函数主要通过判断测得转速是否允许更新,来更新测得转速。判断设定速度、占空比、是否发生变化,如果有变化则更新,如无变化则不更新。其流程图如图5.3所示。图5.3显示函数流程图刷新5.4按键扫描部分主函数通过判断一个按键扫描标志位来判断是否进行按键扫描。该标志位在定时器0中进行更改,当定时时间达到100ms,该标志位被置一。主函数在检测到该标志位为一时调用按键扫描函数,进行按键扫描。在执行按键扫描后,该标志位被清零。按键扫描函数流程图如图5.4所示。图5.4按键扫描函数流程图5.5按键功能实现部分该函数被主函数调用,以实现
12、其功能。该函数首要任务是判定到底是哪个按键按下,然后实现对应功能。如果是11号键按下,则工作模式设定为自动模式,可以通过09的数字键来更改设定速度,由单片机通过PID算法来控制电机转速接近设定值。如果是12号键按下,则工作模式设定为手动模式,可以通过09的数字键来更改占空比直接控制电机转速。其流程图如图5.5所示。图5.5按键功能实现函数流程图5.6更新输出控制信号部分如果控制时间到,定时器置一控制标志位。当主函数检测到该标志位为一,将调用更新输出控制信号函数,并清零标志位。该函数一经调用便要判断工作模式为自动模式还是手动模式。如果工作模式为手动模式,便计算之前输入占空比,并判断是否在规定的范
13、围内。如果不在规定范围内,则强制转化为最大输出或最小输出。如果工作模式为自动模式,则判断设定值和测得值的差值是否大于设定死区。如果差值在死区范围内,则输出上次控制量;如果差值超出了死区范围,则调用PID算法,计算输出控制量并判断控制量是否在允许范围内。如果不在,则输出最值,如果在该范围内,则直接输出计算得到的控制量。其流程图如图5.6所示。图5.6更新输出控制信号函数5.7PID控制部分当控制时间到后,定时器置一控制标志位,由更新输出控制信号调用该函数。如果设定值和测得值的差值大于死区值,更新输出控制信号函数便调用该函数来改变输出控制量。如果差值在死区范围内,则不调用,保持上次输出控制信号不变
14、。该PID控制算法为增量型PID控制算法,增量型PID算法有计算量减小,计算速度快等优点。该算法用到的参数为经验参数,是通过大量的实验数据不停地修改得到。其流程图如图5.7所示。图5.7PID控制算法流程图5.8LCD显示部分该函数主要为各显示函数调用。其工作流程为先向LCD发送控制命令,再传送待显数据,最后刷新屏幕。其流程图如图5.8所示。图5.8LCD显示函数流程图5.9延时部分该函数主要被LCD显示函数调用。该函数所延时为不确定时间值。因为该函数的延时是通过一个空的for循环实现的。其流程图如图5.9所示。图5.9延时函数流程图6.系统调试在该系统的构想之初有不少困惑。主要是在定时器个数
15、的选择以及关于PID算法。最后还是决定用1个定时器。在调试过程中遇到了不少小小的麻烦。比如在按键调试的时候,就遇到了按键没反应的问题,后来修改程序后,按键有反应了,但新的问题又出来了。主要是按键不好使,要么按下没反应,要么按下太久,系统把一次按键动作当成了几次。后来在按键扫描函数中加入了等待按键弹起的语句,解决了按键的灵敏问题。在调制PWM波形的时候发现电机的转速并不随输出的控制信号的改变而变化。用示波器观察输出波形,发现输出波形并不规则。理论上应该是输出一个一定占空比的方波啊。经过一段时间的测试,发现信号输出引脚给出了高低电平,但示波器检测出来的信号看上去并不像给了高低电平啊,就像一个脉冲干
16、扰。突然来个尖脉冲,然后很快衰减。后来缩短定时器的中断时候后,该问题得到解决,输出波形正常。输出波形正常后再测试电机转速,电机转速仍然不正常。后来才发现原来是实验箱的问题。实验箱中用于测量电机转速的霍尔传感器和电机的供电电源是一个,这就意味着当输出控制信号让电机停止转动的同时霍尔传感器也停止工作了。后来用红外对管传感器对转速进行测试,问题得到解决。在编写PID算法的时候,发现占空比变化剧烈,要么是0,要么就是100,总是在两个极值上变化。修改PID参数后问题没有得到很好解决,后来才发是因为现变量的类型给定义错了。修改后,问题得到解决。在PID的调试过程中还遇到不少小问题,在此就不一一累述了。在
17、编写完了后,发现程序并没按预定的程式那样运行,后来才发现是定时器中代码太长的原因。后来只在定时器中保留PWM波形调制部分将一些按键扫描之类的函数都拿到主函数中,在定时器中设立标志位。在主函数中通过判断标志位来选择调用子函数,该问题得到了解决。7.结束语这次课程设计结束在即,在此感谢重庆科技学院给我们提供了一个锻炼的机会,给我们提供场所和设备。感谢钟秉翔老师和张义辉老师不辞辛苦给我们提供解决问题的思路和方向。在此次课程设计中我也得到了很好的锻炼,不单在硬件软件方面的能力,而且在独立思考,解决问题,探索解决问题的方向方面的能力得到了提高。8.参考文献1 赵新民.智能仪器设计基础.哈尔滨:哈尔滨工业
18、大学出版社,20092 程德福.智能仪器.北京:机械工业出版社,2009.93 张毅刚.单片机原理及接口技术M .哈尔滨:哈尔滨工业大学出版社,2007.4 胡文金.单片机应用技术实训教程.重庆:重庆大学出版社,20055 梁森.自动检测技术及应用. 北京:机械工业出版社,2009附录一系统硬件原理图附录二源程序代码/*主函数*/#includereg51.h#includedisplay.h#includekeyscan.h#include pid.h#define THC0 0xfc/1ms#define TLC0 0x17unsignedcharreflag=0,pwmflag=0,se
19、tflag=0,autoflag=1,ctrlflag=0,scanflag=1;unsignedcharrekey=0,setnum8= ,51,53,48,48,r,/,m,zkb3=48,49,48,;unsignedcharreceived8= ,48,48,48,48,r,/,m,g=0,s=0,b=5,q=3,zg=0,zs=0,zb=1;unsignedcharm=0,n=0,mode=0;unsignedintsetval=0;intpwm=40; intsspeed=3500,accept,speed4;unsignedintnumber=0;sbitpwmout=P13;
20、voiddisplay();voidkey_func();voidpwm_ctrl();voidmain()TMOD=0x11;/定时器0初始化 TH0=THC0; TL0=TLC0; TR0=1; ET0=1;EX0=1;/外部中断0初始化IT0=1;EA=1; /开启总中断InitLCD(); while(1)rekey=keyscan();if(rekey=16)break;DispHanzi(0,0,8,电机实时控制系统);/第1行0列显示汉字DispHanzi(1,0,4,设定转速);DispHanzi(2,0,4,测得转速);DispHanzi(3,0,3,占空比);DispZim
21、u(1,4,8,setnum);DispZimu(2,4,8,received);DispZimu(3,4,3,zkb);while(1)if(mode=1)DispHanzi(3,6,2,手动);autoflag=0;elseDispHanzi(3,6,2,自动);autoflag=1;display();if(scanflag=1)rekey=keyscan();scanflag=0;key_func();if(ctrlflag=1)pwm_ctrl();ctrlflag=0;voidcount()interrupt 0number+; voidtimer0()interrupt1stat
22、icunsignedintscan=0,contrl=0,out=0,a=0;TH0=THC0; TL0=TLC0;out+;scan+;contrl+;if(outpwm&out100)scan=0;scanflag=1;if(contrl1000)contrl=0;reflag=1;a+;if(a=5)ctrlflag=1;a=0;voiddisplay()if(reflag=1) accept=number*15; received1=accept/1000+0x30; received2=accept%1000/100+0x30; received3=accept%100/10+0x3
23、0; received4=accept%10+0x30; reflag=0; DispZimu(2,4,8,received); number=0; if(pwmflag=1|autoflag=1) zkb0=pwm/100+0x30; zkb1=pwm/10%10+0x30; zkb2=pwm%10+0x30; pwmflag=0; DispZimu(3,4,3,zkb); if(setflag=1)sspeed=q*1000+b*100+s*10+g;DispZimu(1,4,8,setnum);setflag=0;voidkey_func() if(rekey!=0)if(rekey=1
24、1)mode=0;if(rekey=12)mode=1;if(rekey=1&rekey=10)if(mode=0)if(n3)n+;elsen=0;switch(n)case1:setnum1=rekey+0x2f;q=rekey-1;break;case2:setnum2=rekey+0x2f;b=rekey-1;break;case3:setnum3=rekey+0x2f;s=rekey-1;break;case0:setnum4=rekey+0x2f;g=rekey-1;break;setflag=1;if(mode=1)if(m2)m+;elsem=0; switch(m) case
25、1:zkb0=rekey+0x2f;zb=rekey-1;break; case2:zkb1=rekey+0x2f;zs=rekey-1;break; case0:zkb2=rekey+0x2f;zg=rekey-1;break; pwmflag=1;voidpwm_ctrl()if(autoflag=1)if(accept-sspeed)=100)pwm=pid(sspeed,accept);if(pwm100)pwm=100;if(pwm100)pwm=100;if(pwm0) pwm=0;pwmflag=1;/*显示函数*/*头文件*/#ifndef_DISPLAY_H_#define_
26、DISPLAY_H_#includereg51.h#includedelay.hvoid send_command(unsigned char command_data); /发送命令void send_data(unsigned char command_data); /发送数据void InitLCD(void); /液晶初始化void DispHanzi(unsigned char x,unsigned char y,unsigned char how,unsigned char *stri);/汉字显示void DispZimu(unsigned char x,unsigned cha
27、r y,unsigned char how,unsigned char *stri);/字母数字都可以显示sbitCS = P10; /液晶接口 sbit SID = P11; sbit SCLK = P12; #endif/*C文件*/#includedisplay.hvoid InitLCD(void) /液晶初始化send_command(0x30); /功能设置:一次送8位数据,基本指令集 send_command(0x06); /点设定:显示字符/光标从左到右移位,DDRAM地址加1 send_command(0x0c); /显示设定:开显示,显示光标,当前显示位反白闪动 send_
28、command(0x04); /显示设定:开显示,显示光标,当前显示位反白闪动 send_command(0x01); /清DDRAM send_command(0x02); /DDRAM地址归位 send_command(0x80); /把显示地址设为0X80,即为第一行的首位void send_command(unsigned char command_data) /发送命令unsigned char i; unsigned char i_data,temp_data1,temp_data2; i_data=0xf8; /操作命令,可以查看资料delay(10); CS=1; SCLK=0
29、; for(i=0;i8;i+) SID=(bit)(i_data&0x80); SCLK=0; SCLK=1; i_data=i_data1; i_data=command_data; i_data&=0xf0; for(i=0;i8;i+) SID=(bit)(i_data&0x80); SCLK=0; SCLK=1; i_data=i_data=4; temp_data2=4; i_data=temp_data1|temp_data2; i_data&=0xf0; for(i=0;i8;i+) SID=(bit)(i_data&0x80); SCLK=0; SCLK=1; i_data=
30、i_data1; CS=0; void send_data(unsigned char command_data) /发送数据unsigned char i; unsigned char i_data,temp_data1,temp_data2;i_data=0xfa; /操作命令,可以查看资料delay(10); CS=1; for(i=0;i8;i+) SID=(bit)(i_data&0x80); SCLK=0; SCLK=1; i_data=i_data1; i_data=command_data; i_data&=0xf0; for(i=0;i8;i+) SID=(bit)(i_da
31、ta&0x80); SCLK=0; SCLK=1; i_data=i_data=4; temp_data2=4; i_data=temp_data1|temp_data2; i_data&=0xf0; for(i=0;i8;i+) SID=(bit)(i_data&0x80); SCLK=0; SCLK=1; i_data=i_data1; CS=0; /*x,y为起始座标 x(0=x=3),y(0=y=7),x为行座标,y为列座标; how为要显示汉字的个数; str是要显示汉字的地址 */void DispHanzi(unsigned char x,unsigned char y,unsi
32、gned char how,unsigned char *stri)/汉字显示unsigned char hi=0; if(x=0) send_command(0x80+y); /else if(x=1) send_command(0x90+y);else if(x=2) send_command(0x88+y);else if(x=3) send_command(0x98+y);for(hi=0;hihow;hi+)send_data(*(stri+hi*2);send_data(*(stri+hi*2+1);void DispZimu(unsigned char x,unsigned ch
33、ar y,unsigned char how,unsigned char *stri)/字母数字都可以显示unsigned char hi=0;/字母显示if(x=0) send_command(0x80+y);else if(x=1) send_command(0x90+y);else if(x=2) send_command(0x88+y);else if(x=3) send_command(0x98+y);for(hi=0;hi0;x-)for(i=0;i100;i+);/*按键扫描函数*/*头文件*/#ifndef_KEYSCAN_H_#define_KEYSCAN_H_#includ
34、ereg51.hunsignedcharkeyscan(void);#endif/*C文件*/#includekeyscan.hunsignedcharkeyscan() unsignedchari,data1,data2;unsignedintx,keynum;P2=0x0f;data1=P2&0x0f;if(data1=0x0f)i=0;returni;for(x=0;x1000;x+); /消抖P2=0x0f;data1=P2&0x0f; /p2gaibianif(data1=0x0f)i=0;returni;P2=0xf0|data1;data2=P2&0xf0;data1=data1
35、|data2;switch(data1)case0xe7:keynum=1; while(P2=0xe7);break;case0xeb:keynum=2; while(P2=0xeb);break;case0xed:keynum=3; while(P2=0xed);break;case0xee:keynum=4; while(P2=0xee);break;case0xd7:keynum=5; while(P2=0xd7);break;case0xdb:keynum=6; while(P2=0xdb);break;case0xdd:keynum=7; while(P2=0xdd);break;
36、case0xde:keynum=8; while(P2=0xde);break;case0xb7:keynum=9; while(P2=0xb7);break;case0xbb:keynum=10;while(P2=0xbb);break;case0xbd:keynum=11;while(P2=0xbd);break;case0xbe:keynum=12;while(P2=0xbe);break;case0x77:keynum=13;while(P2=0x77);break;case0x7b:keynum=14;while(P2=0x7b);break;case0x7d:keynum=15;w
37、hile(P2=0x7d);break;case0x7e:keynum=16;while(P2=0x7e);break;returnkeynum;/*PID控制算法*/*头文件*/#ifndef_PID_H_#define_PID_H_#includereg51.hintpid(intsetpoint,intachieved) ;sbitled=P00;#endif/*C文件*/#include pid.hintpid(intsetpoint,intachieved) floatp=5,i=1,d=0.5;staticfloateun=0.0,en=0.0,en1=0.0,en2=0.0;staticintoutput=0,output1=50;en=setpoint-achieved;eun=p*en-i*(en-en1)+d*(en1-en2);eun=eun/500;output=output1+(int)eun;output1=output;en2=en1;en1=en; returnoutput;