基于51单片机的闭环控制 附带源程序文档格式.docx

上传人:b****5 文档编号:20448635 上传时间:2023-01-23 格式:DOCX 页数:18 大小:326.69KB
下载 相关 举报
基于51单片机的闭环控制 附带源程序文档格式.docx_第1页
第1页 / 共18页
基于51单片机的闭环控制 附带源程序文档格式.docx_第2页
第2页 / 共18页
基于51单片机的闭环控制 附带源程序文档格式.docx_第3页
第3页 / 共18页
基于51单片机的闭环控制 附带源程序文档格式.docx_第4页
第4页 / 共18页
基于51单片机的闭环控制 附带源程序文档格式.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

基于51单片机的闭环控制 附带源程序文档格式.docx

《基于51单片机的闭环控制 附带源程序文档格式.docx》由会员分享,可在线阅读,更多相关《基于51单片机的闭环控制 附带源程序文档格式.docx(18页珍藏版)》请在冰豆网上搜索。

基于51单片机的闭环控制 附带源程序文档格式.docx

而软件部分,是对硬件端口所体现的信号,加以采集、分析、处理,最终实现控制器所要实现的各项功能,达到控制器自动对电机速度的有效控制。

但是此设计中电机只需要正转,所以相对来说简单点。

3硬件设计

8051单片机简介

AT89C52是一个低电压,高性能CMOS8位单片机,片内含8kbytes的可反复擦写的Flash只读程序存储器和256bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元,AT89C52单片机在电子行业中有着广泛的应用。

AT89C52有40个引脚,32个外部双向输入/输出(I/O)端口,同时内含2个外中断口,3个16位可编程定时计数器,2个全双工串行通信口,2个读写口线,AT89C52可以按照常规方法进行编程,也可以在线编程。

其将通用的微处理器和Flash存储器结合在一起,特别是可反复擦写的Flash存储器可有效地降低开发成本。

部分功能如下:

(1)8kB可反复擦写(大于1000次)FlashROM;

(2)32个双向I/O口;

(3)256x8bit内部RAM;

(4)3个16位可编程定时/计数器中断;

(5)时钟频率0-24MHz;

(6)2个串行中断,可编程UART串行通道;

(7)2个外部中断源,共8个中断源;

(8)2个读写中断口线,3级加密位;

直流电机

设计中采用直流电机,自带高精度的磁编码器,性能介绍如图一所示,

接线说明如图二所示:

性能介绍图一

 

接线图二

L298N

恒压恒流桥式2A驱动芯片L298N,简称H桥。

L298是SGS公司的产品,比较常见的是15脚Multiwatt封装的L298N,内部同样包含4通道逻辑驱动电路。

可以方便的驱动两个直流电机,或一个两相步进电机。

L298N芯片可以驱动两个二相电机,也可以驱动一个四相电机,输出电压最高可达50V,可以直接通过电源来调节输出电压;

可以直接用单片机的IO口提供信号;

而且电路简单,使用比较方便。

L298N可接受标准TTL逻辑电平信号VSS,VSS可接4.5~7V电压。

4脚VS接电源电压,VS电压范围VIH为+2.5~46V。

输出电流可达2.5A,可驱动电感性负载。

1脚和15脚下管的发射极分别单独引出以便接入电流采样电阻,形成电流传感信号。

L298可驱动2个电动机,OUT1,OUT2和OUT3,OUT4之间可分别接电动机,本实验装置我们选用驱动一台电动机。

5,7,10,12脚接输入控制电平,控制电机的正反转。

EnA,EnB接控制使能端,控制电机的停转。

L298芯片驱动电路图如下:

图1L298芯片驱动电路图

系统总体电路

图中控制器模块为系统的核心部件,电位器和显示器是用来实现人机交换功能,其中通过键盘将需要设置的参数和状态输入到单片机中,并且通过控制器显示到显示器上。

在运行过程中控制器产生PWM脉冲送到电机驱动电路中,经过放大后控制直流电机转速,同时利用速度检测模块将当前转速反馈到控制器中,控制器经过数字PID运算后改变PWM脉冲的占空比,实现电机转速实时控制的目的。

PWM脉冲

图1系统方案框图

4软件设计

PID算法

PI调节器是电力拖动自动控制中最常用的的一种,在微机数字控制系统中,当采样频率足够高时,可以先按模拟系统的设计方法设计,然后再离散化,得到数字控制器的算法。

PI调节器的传递函数如式所示:

()

若输入误差函数为e(t),输出函数为u(t),则e(t)和u(t)的关系时域表达式可写成:

()

式子中

为比例系数,

为比例系数。

将式转化为差分方程,得到数字PI调节器的表达式,其第k拍输出为:

式中

为采样周期。

增量式算法只需要当前的和上一拍的偏差即可计算出输出值。

增量式PI调节器算法为:

()

在控制系统中,常需要对调节器的输出实施限幅。

在数字控制算法中,要对u限幅,只需要在程序中设置限幅值。

不考虑限幅时,位置式和增量式两种算法完全等同,考虑限幅时,则两者略有差异。

增量式PI调节器算法只需要输出限幅,而位置式算法必须同时设置积分限幅和输出限幅。

若没有积分限幅,积分项可能很大,将产生较大的退饱和超调。

算法模块如下:

inte=0,e1=0,e2=0;

floatuk=0,uk1=,duk=;

//PID输出值

floatkp=5,ki=,kd=;

//PID控制系数

上面是初始化部分

voidPIDControl()//PID偏差计算

{

e=temp-num;

//变量temp是AD采集过来的值,num是通过M法测出点值

duk=(kp*(e-e1)+ki*e+kd*(e-2e1+e2))

uk=uk1+duk;

out=(int)uk;

if(out>

250)

{

out=100;

}

elseif(out<

0)

out=0;

uk1=uk;

e2=e1;

e1=e;

value=out;

//value最后送给PWM。

}

这部分是子程序

M法测速

在一定时间Tc内测取旋转编码器输出脉冲个数M1,用以计算这段时间内的转速,称作M法测速。

把M1除以Tc就可以得到旋转编码器输出脉冲的频率f1=M1/Tc,所以又称频率法。

电机每转一圈共产生Z个脉冲(Z=倍频系数*编码器光栅数),把f1除以Z就得到在单位时间内电机的转速。

在习惯上,时间Tc以s为单位,而转速是以r/min为单位,则电动机的转速为:

n=60M1/ZTc()

由于Z和Tc都是常数,因此转速n与计数值M1成正比,故此测速方法称M法测速。

具体程序部分用外部中断计数和定时器来完成,程序如下:

voidexter0()interrupt0//外部中断脉冲计数

{//M法测速度(外部中断0和定时器0用在M法测速上)

Inlpuse++;

voidtimer0()interrupt1

{

TH0=0x3c;

//重装初值

TL0=0xb0;

time++;

if(time>

=20)//1s钟读取一次转速(2*60ms)

{EX0=0;

TR0=0;

num=Inlpuse;

//计算转速

Inlpuse=0;

PIDControl();

//100ms控制一次

Inlpuse=0;

EX0=1;

TR0=1;

}

参数设定

在程序中修改PID调节算法中的比例系列、积分系数和微分系数可以得到不同特性的转速曲线。

参数改变,转速响应的超调量和调整时间发生变化。

系统的稳定性和快速性是一对矛盾,因此我们必须选择一个合适的PI参数。

在调试过程中,当令kp=5、ki=、kd=时系统的快速性和稳定性达到最佳状态。

电位器的AD采集模块

AD采集模块利用是我是直接调用了开发板里面的程序,这个模块可以也可以自己制作。

我用的XPT2046是一款4线制电阻式触摸屏控制器,内含12位分辨率125KHz转换速率逐步逼近型A/D转换器。

此芯片支持从到的低电压I/O接口。

XPT2046能通过执行两次A/D转换查出被按屏幕位置,除此之外,还可以测量加在触摸屏上的压力。

主要特性如下:

(1)工作电压范围为到

(2)支持的数字I/O口

(3)内建参考电压

(4)内建结温测量功能

(5)触摸压力测量,具有自动省电功能

(6)采用3线制SPI通信接口

程序见最后的程序清单。

5课题总结

从课题选定开始,先是看了一遍课本以及网上找了对应的论文,然后看了老师发的试验资料以及各个元器件的原理和用法,最后把硬件焊接起来,然后想如何测测速,如何给定,如何用PID进行控制,最后如何通过PID去控制PWM的占空比。

在调试的过程中遇到一个很简单和致命的问题,就是我用的开发板和L298N开始的时候没有共接地导致调速一直失败,最后通过用示波器观测PWM输出的波形发现了问题,当真正的实现调速的时候感觉很好,终于通过自己的努力完成了一项有点技术含量的事情。

继续加油。

全部程序如下:

对于程序,每个读者的I/0口或者用的ad采集方式不一样,程序可能不同,但是解决闭环问题的核心是读取给定值用AD转换,读取测速值用外部中断和定时器中段,PWM输出也用一个定时器。

#include"

"

//--定义使用的IO--//

#defineGPIO_DIGP0

sbitPWM=P1^0;

//PID偏

intout=0;

sbitIN2=P1^1;

//--定义一个全局变量--//

unsignedintvalue,timer1;

uintnum;

uintInlpuse=0,num=0;

//脉冲计数单元

uinttemp,count,temp1;

unsignedinttime=0;

sbitzhongduan=P3^2;

sbitLSA=P2^2;

sbitLSB=P2^3;

sbitLSC=P2^4;

//--定义全局变量--//

unsignedcharcodeDIG_CODE[17]={

0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码

ucharDisplayData[8];

//用来存放要显示的8位数的值

voidDigDisplay(void);

voidPIDControl()//PID偏差计算

out=0;

voidSetSpeed(void)

temp1=Read_AD_Data(0x94);

//AIN0电位器(100us采集一次

temp=2*temp1>

>

5;

//temp的变化范围在0-250之间

voidDigDisplay(void)

unsignedchari;

unsignedintj;

DisplayData[7]=DIG_CODE[num%10000/1000];

DisplayData[6]=DIG_CODE[num%1000/100];

DisplayData[5]=DIG_CODE[num%100/10];

DisplayData[4]=DIG_CODE[num%10/1];

DisplayData[3]=DIG_CODE[temp%10000/1000];

DisplayData[2]=DIG_CODE[temp%1000/100];

DisplayData[1]=DIG_CODE[temp%100/10];

DisplayData[0]=DIG_CODE[temp%10/1];

for(i=0;

i<

8;

i++)

switch(i)//位选,选择点亮的数码管,

{

case(0):

LSA=0;

LSB=0;

LSC=0;

break;

//显示第0位

case

(1):

LSA=1;

//显示第1位

case

(2):

LSB=1;

//显示第2位

case(3):

//显示第3位

case(4):

LSC=1;

//显示第4位

case(5):

//显示第5位

case(6):

//显示第6位

case(7):

//显示第7位

}

GPIO_DIG=DisplayData[i];

//发送段码

j=50;

//扫描间隔时间设定

while(j--);

GPIO_DIG=0x00;

//消隐

{//M法测速度(外部中断0和定时器0用在M法测速上)

voidT1_time()interrupt3

count1++;

if(count1>

=100)count1=0;

//计时100us*100=10ms=100Hz

if(count1<

value)pwm=1;

//占空比

elsepwm=0;

voidSystemInit()

{

TMOD=0x21;

//设定时器0为工作方式1,定时器1为工作方式2(自动重装初值)

//设定50ms一次中断

TH1=0x9c;

//设定100us一次中断

TL1=0x9c;

EA=1;

//开总中断

ET0=1;

//开定时器0中断

ET1=1;

//开定时器1中断

//开外部中断0

IT0=1;

//启动下降沿触发有效

TR1=1;

//启动定时器1

TR0=1;

//启动定时器0

voidmain()

SystemInit();

while

(1)

DigDisplay();

AD采集模块:

(这一部分程序只是AD采集模块,用的芯片是XPT2046,用spi通信方式,最后改变电位器可以改变temp的值,这部分程序读者可以自己解决,)

#ifndef__XPT2046_H_

#define__XPT2046_H_

//---包含头文件---//

#include<

//---重定义关键词---//

#ifndefuchar

#defineucharunsignedchar

#endif

#ifndefuint

#defineuintunsignedint

#ifndefulong

#defineulongunsignedlong

//---定义使用的IO口---//

sbitDOUT=P3^7;

//输出

sbitCLK=P3^6;

//时钟

sbitDIN=P3^4;

//输入

sbitCS=P3^5;

//片选

uintRead_AD_Data(ucharcmd);

uintSPI_Read(void);

voidSPI_Write(uchardat);

/****

*函数名:

TSPI_Start

*输入:

*输出:

*功能:

初始化触摸SPI

****/

voidSPI_Start(void)

CLK=0;

CS=1;

DIN=1;

CLK=1;

CS=0;

SPI_Write

dat:

写入数据

使用SPI写入数据

voidSPI_Write(uchardat)

uchari;

i<

i++)

DIN=dat>

7;

//放置最高位

dat<

<

=1;

CLK=0;

//上升沿放置数据

CLK=1;

SPI_Read

读取到的数据

使用SPI读取数据

uintSPI_Read(void)

uinti,dat=0;

12;

i++)//接收12位数据

dat|=DOUT;

returndat;

Read_AD_Data

cmd:

读取的X或者Y

endValue:

最终信号处理后返回的值

读取触摸数据

uintRead_AD_Data(ucharcmd)

uintAD_Value;

SPI_Write(cmd);

for(i=6;

i>

0;

i--);

//延时等待转换结果

//发送一个时钟周期,清除BUSY

_nop_();

AD_Value=SPI_Read();

returnAD_Value;

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

当前位置:首页 > 工程科技 > 电力水利

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

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