51系列单片机直流电机闭环调速实验.docx
- 文档编号:23693981
- 上传时间:2023-05-20
- 格式:DOCX
- 页数:22
- 大小:293.30KB
51系列单片机直流电机闭环调速实验.docx
《51系列单片机直流电机闭环调速实验.docx》由会员分享,可在线阅读,更多相关《51系列单片机直流电机闭环调速实验.docx(22页珍藏版)》请在冰豆网上搜索。
51系列单片机直流电机闭环调速实验
指导教师评定成绩:
审定成绩:
自动化学院
综合实验报告
综合实验
(1):
51系列单片机直流电机闭环调速实验
——基于Protuse仿真实验平台实现
专业:
电气工程与自动化
班级:
姓名:
学号:
时间:
2013.10---2013.12
一、设计要求
1.设计硬件电路:
(1)直流电机采用编码器测速
(2)直流电机速度给定采用电位器进行模拟电压给定,0——5V
(3)AD转采用12位转换
(4)显示采用8位LED,或者LCD1602显示
(5)键盘4X4,PID等参数通过键盘设置。
2.软件
(1)控制算法:
数字PID,参数在线修改。
(2)显示窗口:
显示速度的设置值SV、速度的实际值PV。
(3)实际速度值,速度峰值、峰值时间等通过串口上传到上位机(选做)
二、实验内容
直流电机PWM控制系统的主要功能包括:
直流电机的加速、减速以及电机的正转和反转,并且可以调整电机的转速,还可以方便的读出电机转速的大小,能够很方便的实现电机的智能控制。
其间,还包括直流电机的直接清零、启动(置数)、暂停、连续功能。
该直流电机系统由以下电路模块组成:
振荡器和时钟电路:
这部分电路主要由AT89C52、些电容、晶振组成。
设计输入部分:
这一模块主要是利用带中断的独立式键盘来实现。
设计控制部分:
主要由AT89C52单片机的外部中断扩展电路组成。
设计液晶显示部分由LCD1602液晶显示模块组成。
直流电机PWM控制实现部分:
主要由一些二极管、电机和L298直流电机驱动模块组成。
1.主控电路
主控型号:
AT89C52
图2-1单片机最小系统
2.电机驱动电路
电机的驱动芯片选用L298N作为驱动芯片,工作稳定电机驱动信号由单片机提供,信号经过光耦隔离后,通过L298N的输出脚与两个电机相连,L298N内部包含4通道逻辑驱动电路,可以方便的驱动两个直流电机,或一个两相步进电机。
L298N可接受标准TTL逻辑电平信号VSS,VSS可接4.5~7V电压。
4脚VS接电源电压,VS电压范围VIH为+2.5~46V。
输出电流可达2.5A,可驱动电感性负载。
L298N的OUT1,OUT2和OUT3,OUT4之间可分别接电动机,该4个端口用来控制电机的转向,L298的另外两个使能端是用来通过调节占空比控制电机转速。
图2-2电机驱动电路
3.键盘输入电路
采用键盘4X4,进PID等参数通过键盘设置
图2-3输入电路
4.AD采集电路
型号:
TLC2543,为12位AD
图2-4AD采集电路
5.显示电路
采用LCD1602液晶进行信息显示
图2-5LCD1602显示电路
三、PID算法
将偏差的比例(Proportion)、积分(Integral)和微分(Differential)通过线性组合构成控制量,用这一控制量对被控对象进行控制,这样的控制器称PID控制器。
PID控制分为模拟PID控制和数字PID控制。
而单片机PID控制属于数字PID控制,数字式PID控制算法可以分为位置式PID和增量式PID控制算法。
经典算法如下:
floatMaxValue=100;//上限
floatMinValue=0;//下限
/******************PID参数定义*******************/
structPIDsPID;//PIDControlStructure
structPID*sptr=&sPID;//PID地址指针
/*******************PID初始化********************/
voidPID_Init()
{
sptr->SetPoint=100;
sptr->Output=0;//输出值
sptr->LastError=0;//Error[-1]
sptr->PrevError=0;//Error[-2]
sptr->SumError=0;
sptr->Proportion=0.5;//比例常数ProportionalConst
sptr->Integral=0;//积分常数IntegralConst
sptr->Derivative=0;//微分常数DerivativeConst
}
/*****************PID位置式*******************/
floatLocPIDCalc(floatNextPoint)
{
floatiError,dError;
iError=sptr->SetPoint-NextPoint;//偏差
sptr->SumError+=iError;//积分
dError=iError-sptr->LastError;//微分
sptr->LastError=iError;
sptr->Output=sptr->Proportion*iError//比例项
+sptr->Integral*sptr->SumError//积分项
+sptr->Derivative*dError;//微分项
if(sptr->Output>MaxValue)sptr->Output=MaxValue;//上限控制
if(sptr->Output
printf("PIDOUT=%f\r\n\r\n",sptr->Output);
returnsptr->Output;
}
/******************PID增量式*******************/
floatIncPIDCalc(floatNextPoint)
{
floatiError;
iError=sptr->SetPoint-NextPoint;
sptr->Output=sptr->Proportion*iError//E[0]
-sptr->Integral*sptr->LastError//E[-1]
+sptr->Derivative*sptr->PrevError;//E[-2]
sptr->PrevError=sptr->LastError;
sptr->LastError=iError;
if(sptr->Output>MaxValue)sptr->Output=MaxValue;//上限控制
if(sptr->Output
printf("PIDOUT=%f\r\n\r\n",sptr->Output);
return(sptr->Output);
}
四、整体电路
图4-1整体电路
五、结论
本课题的目的在于利用单片机实现PID算法产生PWM脉冲来控制电机转速。
归纳起来主要做了如下几方面的工作:
1、PID算法与PWM控制技术有机的结合;2、设计了电机调速电路;3、利用C语言进行程序设计,并通过仿真(源程序见附录)。
根据上面论述结合测试数据可以看出本次设计基本完成了设计任务和要求。
通过此次设计,掌握了数字PID算法的使用及编程方法,学习了如何进行系统设计及相关技巧,为今后的工作和学习奠定了坚实的基础。
六、控制程序代码
1.main.c
#include
#include"delay.h"
#include"1602.h"
#include"PID.h"
#include"timer.h"
#include"keyboard.h"
#include
/*------------------------------------------------
主程序
------------------------------------------------*/
main()
{
unsignedchartemp[7];//定义显示区域临时存储数组
unsignedcharkey;//按键
LCD_Init();//初始化液晶
DelayMs(20);//延时有助于稳定
LCD_Clear();//清屏
init();
while
(1)//主循环
{
sprintf(temp,"%5.1f",(float)speed);//float是强制转换符号,用于将结果转换成浮点型,%5.0f表示浮点输出,共5位数,小数点后0位
LCD_Write_String(0,0,temp);
key=KeyPro();
}
}
2.timer.c
#include
#include"timer.h"
#include"1602.h"
#include"PID.h"
#include
unsignedintinit_count;//中断次数
unsignedintcount,count1;//定时溢出次数
unsignedintspeed0,speed;//速度
unsignedlongtime;//脉冲周期
charspwm=10;//pwm值
/*************定时器初始化*************/
voidinit_clock()
{
TMOD=0x21;//设定时器0为工作方式1,定时器1为工作方式2(自动重装初值)
TH0=0x3c;//设定50ms一次中断
TL0=0xb0;
TH1=0x9c;//设定100us一次中断
TL1=0x9c;
EA=1;//开总中断
ET0=1;//开定时器0中断
TR0=1;//启动定时器0
//TR0=0;//关闭定时器0
ET1=1;//开定时器1中断
TR1=1;//启动定时器1
}
/************外部中断初始化************/
voidinit_int()
{
EA=1;//开总中断
EX0=1;//开外部中断0
IT0=1;//启动下降沿触发有效
}
/**************总初始化***************/
voidinit()
{
init_int();
init_clock();
}
/************中断服务程序*************/
voidinto()interrupt0
{
init_count++;
}
voidT0_time()interrupt1
{
TH0=0x3c;//重装初值
TL0=0xb0;
count++;
if(count>=20)//50ms*20=1s
{
EX0=0;
TR0=0;
led=~led;
speed=init_count;//电机转速
spwm=pidcontrol(speed);
count=0;
init_count=0;
EX0=1;
TR0=1;
}
}
voidT1_time()interrupt3
{
count1++;
if(count1>=100)count1=0;//计时100us*100=10ms=100Hz
if(count1 elsepwm=0; } 3.1602.c /*----------------------------------------------- 名称: LCD1602 引脚定义如下: 1-VSS2-VDD3-V04-RS5-R/W6-E7-14DB0-DB715-BLA16-BLK ------------------------------------------------*/ #include"1602.h" #include"delay.h" sbitRS=P2^0;//定义端口 sbitRW=P2^1; sbitEN=P2^2; #defineRS_CLRRS=0 #defineRS_SETRS=1 #defineRW_CLRRW=0 #defineRW_SETRW=1 #defineEN_CLREN=0 #defineEN_SETEN=1 #defineDataPortP0 /*------------------------------------------------ 判忙函数 ------------------------------------------------*/ /* bitLCD_Check_Busy(void) { DataPort=0xFF; RS_CLR; RW_SET; EN_CLR; _nop_(); EN_SET; return(bit)(DataPort&0x80); } */ /*------------------------------------------------ 写入命令函数 ------------------------------------------------*/ voidLCD_Write_Com(unsignedcharcom) { //while(LCD_Check_Busy());//忙则等待 RS_CLR; RW_CLR; EN_SET; DataPort=com; _nop_(); EN_CLR; } /*------------------------------------------------ 写入数据函数 ------------------------------------------------*/ voidLCD_Write_Data(unsignedcharData) { //while(LCD_Check_Busy());//忙则等待 RS_SET; RW_CLR; EN_SET; DataPort=Data; _nop_(); EN_CLR; } /*------------------------------------------------ 清屏函数 ------------------------------------------------*/ voidLCD_Clear(void) { LCD_Write_Com(0x01); DelayMs(5); } /*------------------------------------------------ 写入字符串函数 ------------------------------------------------*/ voidLCD_Write_String(unsignedcharx,unsignedchary,unsignedchar*s) { if(y==0) { LCD_Write_Com(0x80+x);//表示第一行 } else { LCD_Write_Com(0xC0+x);//表示第二行 } while(*s) { LCD_Write_Data(*s); s++; } } /*------------------------------------------------ 写入字符函数 ------------------------------------------------*/ voidLCD_Write_Char(unsignedcharx,unsignedchary,unsignedcharData) { if(y==0) { LCD_Write_Com(0x80+x); } else { LCD_Write_Com(0xC0+x); } LCD_Write_Data(Data); } /*------------------------------------------------ 初始化函数 ------------------------------------------------*/ voidLCD_Init(void) { LCD_Write_Com(0x38);/*显示模式设置*/ DelayMs(5); LCD_Write_Com(0x38); DelayMs(5); LCD_Write_Com(0x38); DelayMs(5); LCD_Write_Com(0x38); LCD_Write_Com(0x08);/*显示关闭*/ LCD_Write_Com(0x01);/*显示清屏*/ LCD_Write_Com(0x06);/*显示光标移动设置*/ DelayMs(5); LCD_Write_Com(0x0C);/*显示开及光标设置*/ } 4.ad.c /************************************ TLC2543驱动程序 *************************************/ #include #include #include /************************************** 2543控制引脚定义 *************************************/ sbitD_OUT=P2^3;/*2543输出*/ sbitD_IN=P2^4;/*2543输入*/ sbit_CS=P2^5;/*2543片选*/ sbitCLOCK=P2^6;/*2543时钟*/ /************************************** 名称: delay 功能: 延时模块 输入参数: n要延时的周期数 输出参数: 无 *************************************/ voiddelay(ucharn) { uchari; for(i=0;i { _nop_(); } } /************************************** 名称: read2543 功能: TLC2543驱动模块 输入参数: port通道号 输出参数: ad转换值 *************************************/ uintread2543(ucharport) { uintad=0,i; CLOCK=0; _CS=0; port<<=4; for(i=0;i<12;i++) { if(D_OUT)ad|=0x01; D_IN=(bit)(port&0x80); CLOCK=1; delay(3); CLOCK=0; delay(3); port<<=1; ad<<=1; } _CS=1; ad>>=1; return(ad); } 5.pid.c #include"PID.h" floatmaxvalue=100,minvalue=0;//输出范围控制 floatsetpoint=100,e,e1,e2;//pid偏差 floatuk,uk1,duk;//pid输出值 floatKp=5.0,Ki=0.1,Kd=0.3;//pid控制系数 /******************PID算法*******************/ floatpidcontrol(floatpoint) { e=setpoint-point; duk=(Kp*(e-e1)+Ki*e+Kd*(e-2*e1+e2)); uk=uk1+duk; uk1=uk; e2=e1; e1=e; if(uk>maxvalue)uk=maxvalue; elseif(uk returnuk; } 6.keyboard.c /*----------------------------------------------- 名称: 矩阵键盘 ------------------------------------------------*/ #include #include"keyboard.h" #include"delay.h" #defineKeyPortP1 /*------------------------------------------------ 按键扫描函数,返回扫描键值 ------------------------------------------------*/ unsignedcharKeyScan(void)//键盘扫描函数,使用行列反转扫描法 { unsignedcharcord_h,cord_l;//行列值中间变量 KeyPort=0x0f;//行线输出全为0 cord_h=KeyPort&0x0f;//读入列线值 if(cord_h! =0x0f)//先检测有无按键按下 { DelayMs(10);//去抖 if((KeyPort&0x0f)! =0x0f) { cord_h=KeyPort&0x0f;//读入列线值 KeyPor
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 51 系列 单片机 直流电机 闭环 调速 实验