51系列单片机直流电机闭环调速实验.docx

上传人:b****7 文档编号:23693981 上传时间:2023-05-20 格式:DOCX 页数:22 大小:293.30KB
下载 相关 举报
51系列单片机直流电机闭环调速实验.docx_第1页
第1页 / 共22页
51系列单片机直流电机闭环调速实验.docx_第2页
第2页 / 共22页
51系列单片机直流电机闭环调速实验.docx_第3页
第3页 / 共22页
51系列单片机直流电机闭环调速实验.docx_第4页
第4页 / 共22页
51系列单片机直流电机闭环调速实验.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

51系列单片机直流电机闭环调速实验.docx

《51系列单片机直流电机闭环调速实验.docx》由会员分享,可在线阅读,更多相关《51系列单片机直流电机闭环调速实验.docx(22页珍藏版)》请在冰豆网上搜索。

51系列单片机直流电机闭环调速实验.docx

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->OutputOutput=MinValue;//下限控制

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->OutputOutput=MinValue;//下限控制

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模板 > 其它模板

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

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