指导教师评定成绩:
审定成绩:
重庆邮电大学
自动化学院
计算机控制技术课程设计报告设计题目:步进电动机调速控制
单位(二级学院):自动化学院
学生姓名:林参
专业:自动化
班级:0810903
学号:2009212466
指导教师:陈勇
设计时间:2012 年 6 月
目录
摘要 (1)
设计题目 (2)
一、平台 (2)
二、设计目的: (2)
三、设计要求: (2)
设计内容 (3)
一、计算机控制系统的总体规划与设计思路: (3)
二、硬件综合设计 (4)
1. 总体原理电路图: (4)
2. 实物图: (4)
三、软件综合设计 (11)
1. 设计流程图: (11)
2. PID两种基本算法:位置算法和增量算法,采用变频调速 (12)
3. 实现以上要求的控制算法(已调试正确): (13)
设计总结 (21)
参考文献 (22)
摘要
步进电动机是将电脉冲信号转变为角位移的开环控制元件。通过单片机AT89C52控制的脉冲信号的频率和脉冲数控制电机的转速、停止的位置,而不受负载的影响,即给电机加一个脉冲信号,电机则转过一个步距角。
采用对射式光电传感器H92B4为步进电机的测速原件,它利用码盘对光速的遮挡,由同步回路选通电路,从而检测码盘有无遮挡。光电式旋转编码器是转速或转角的检测元件,旋转编码器与电机相连,当电机转动时,带动增量式码盘旋转,便发出转速或转角信号。
L297步进电机专用控制器,芯片内的PWM斩波器电路可开关模式下调节步进电机绕组中的电机绕组中的电流,用于计算机控制的两相双极和四相单相步进电机,能够用于控制此步进电机,并与L298双全桥步进电机专用芯片等共同组成驱动电路。
控制算法上,利用增量式PID算法,从测试传感器采样的信号经PID控制和所测试相结合消除减少误差,编出满足要求的程序。
由以上几个主要部分共同构成步进电机闭环控制系统,驱动电路驱动电机,测速提供为反馈,AT89C52控制步进电机的正反转、和转速增减,实现对步进电机的控制,并由显示器显示出正反转方向和转速。
关键词:步进电动机PID AT89C52 L297 L298 H92B4
设计题目
步进电动机调速控制
一、平台
1、二相四线制步进电动机;
2、以单片机作为控制器。
二、设计目的:
1、设计步进电机控制电路;
2、设计步进电机调速控制电路,要求采用变频调速;
3、采用PID 两种基本算法:位置算法和增量算法,并要求知道这两种算法的特点;
(1)位置算法:
)
,()]
1()([)()()(0
P D D I
P
I K
j D I P K T
T K T T K K k e k e K j e K k e K k u =
=--++=∑=
(2)增量算法:
)]
2()1(2)([)()]1()([)
1()()(-+--++--=--=?k e k e k e K k e K k e k e K k u k u k u D I P
4、步进电动机旋转误差小于1%;
5、实现正反转;
6、速度检测与显示及控制。
三、设计要求:
1、整个课程设计的各个环节都要求学生自己动手。
2、提供相应的算法分析与计算。
3、自己选择计算机控制设备,构建一个简单的计算机控制系统。
4、对课程设计进行总结,撰写课程设计报告。
5、课程设计时间1.5周。
设计内容
一、计算机控制系统的总体规划与设计思路:
此步进电机调速计算机控制系统主要由以下4部分组成
1、单片机AT89C52的控制电路
2、L297和L298组成驱动电路
3、对射式光传感器为测速元件测速(用的是T法测速)组成的反馈回路
4、二相四线制步进电机
由以上4部分组成步进电机调速计算机控制闭环控制系统。在A T89C52中载入增量式PID控制算法的程序,通过对按键的操作,控制步进电机的转速(加速、减速、正反转),并在显示器上显示出转速。最终实现完整的二相四线步进电机调速的计算机控制系统。
设计基本框图如下:
二、硬件综合设计
1.总体原理电路图:
2.实物图:
1、控制电路AT89C52
实体图:
AT89C52是一个低电压,高性能CMOS的 8位单片机,片内含8k bytes的可反复擦写的FLASH只读程序存储器和256 bytes的随机存取数据存储器(RAM)采用工业标准的C51内核,在内部功能及管脚排布上与通用的8xc52 相同,其主要用于会聚调整时的功能控制。功能包括对会聚主IC 内部寄存器、数据RAM 及外部接口等功能部件的初始化,会聚调整控制,会聚测试图控制,红外遥控信号IR的接收解码及与主板CPU通信等。主要管脚有:XTAL1(19 脚)和XTAL2
(18 脚)为振荡器输入输出端口,外接12MHz 晶振。RST/Vpd(9 脚)为复位输入端口,外接电阻电容组成的复位电路。VCC(40 脚)和VSS(20 脚)为供电端口,分别接+5V电源的正负端。P0~P3 为可编程通用I/O 脚,其功能用途由软件定义,在本设计中,P0 端口(32~39 脚)被定义为N1 功能控制端口,分别与N1的相应功能管脚相连接,13 脚定义为IR输入端,10 脚和11脚定义为I2C总线控制端口,分别连接N1的SDAS(18脚)和SCLS(19脚)端口,12 脚、27 脚及28 脚定义为握手信号功能端口,连接主板CPU 的相应功能端,用于当前制式的检测及会聚调整状态进入的控制功能。主要工作特性是:片内程序存储器内含8KB的Flash程序存储器,可擦写寿命为1000次;
片内数据存储器内含256字节的RAM;
具有32根可编程I/O口线;
具有3个可编程定时器;
中断系统是具有8个中断源、6个中断矢量、2个级优先权的中断结构;
串行口是具有一个全双工的可编程串行通信口;
具有一个数据指针DPTR;
低功耗工作模式有空闲模式和掉电模式;
具有可编程的3级程序锁定位;
AT89C52工作电源电压为5(1+0.2)V,且典型值为5V;
AT89C52最高工作频率为24MHz
2、驱动电路L297和L298
实体图:
L297是步进电机专用控制器,它能产生4相控制信号,可用于计算机控制的两相双极和四相单相步进电机,能够用单四拍、双四拍、四相八拍方式控制步进电机。芯片内的PWM斩波器电路可开关模式下调节步进电机绕组中的电机绕组中的电流。该集成电路采用了SGS公司的模拟/数字兼容的I2L技术,使用5V 的电源电压,全部信号的连接都与TFL/CMOS或集电极开路的晶体管兼容。L297的芯片引脚特别紧凑,采用双列直插20脚塑封封装,其引脚见图1,内部方框见图2。
内部电路图
[2]
在图2所示的L297的内部方框图中。变换器是一个重要组成部分。变换器由一个三倍计算器加某些组合逻辑组成,产生一个基本的八格雷码(顺序如图3所示)。由变换器产生4个输出信号送给后面的输出逻辑部分,输出逻辑提供禁
止和斩波器功能所需的相序。为了获得电动机良好的速度和转矩特性,相序信号
是通过2个PWM斩波器控制电动波器包含有一个比较器、一个触发器和一个外部检测电阻,如图4所示,晶片内部的通用振荡器提供斩波频率脉冲。每个斩波器的触发器由振荡器的脉冲调节,当负载电流提高时检测电阻上的电压相对提高,当电压达到Uref时(Uref是根据峰值负载电流而定的),将触发器重置,切断输出,直至第二个振荡脉冲到来、此线路的输出(即触发器Q输出)是一恒定速率的PWM信号,L297的CONTROL端的输入决定斩波器对相位线A,B,C,D或抑制线INH1和INH2起作用。CONTROL为高电平时,对A,B,C,D有抑制作用;为低电平时,则对抑制线INH1和INH2有抑制作用,从而可对电动机和转矩进行控制。
L298内部包含4通道逻辑驱动电路。可以方便的驱动两个直流电机,或一个两相步进电机。L298N芯片可以驱动两个二相电机,也可以驱动一个四相电机,
输出电压最高可达50V,可以直接通过电源来
调节输出电压;可以直接用单片机的IO口提
供信号;而且电路简单,使用比较方便。
L298可接受标准TTL逻辑电平信号
VSS,VSS可接4.5~7 V电压。4脚VS接
电源电压,VS电压范围VIH为+2.5~46 V。
输出电流可达2.5 A,可驱动电感性负载。1
脚和15脚下管的发射极分别单独引出以便接
入电流采样电阻,形成电流传感信号。L298
可驱动2个电动机,OUT1,OUT2和OUT3,
OUT4之间可分别接电动机,本实验装置我们选用驱动一台电动机。5,7,10,12脚接输入控制电平,控制电机的正反转。EnA,EnB接控制使能端,控制电机的停转。表1是L298功能逻辑图。
In3,In4的逻辑图与表1相同。由表1
可知EnA为低电平时,输入电平对电机控
制起作用,当EnA为高电平,输入电平为
一高一低,电机正或反转。同为低电平电
机停止,同为高电平电机刹停。
3、步进电机及对射式光电传感器H92B4
步进电动是一步一步转动的,故叫步进电动机。步进电机是数字控制电机,它将脉冲信号转变成角位移,即给一个脉冲信号,步进电机就转动一个角度,因此非常适合于单片机控制。因此步进电动机是一种把脉冲变为角度位移(或直线位移)的执行。随着数字控制系统的发展,步进电动机的应用将逐渐扩大。
H92B4是有高发射功率的砷化镓红外发射管和高灵敏度的光敏管组成。她是利用被检测物对光束的遮挡,由同步回路选通电路,从而检测物体有无。特点:易安装、高可靠性:响应速度快,光缝0.8mm;槽宽4mm,脚距8.8mmm。
T法测速:
记录编码器两个相邻输出脉冲的间的高频脉冲个数M2,f0为高频脉冲频率,
电机转速
r/min
ZM
f 60ZT 60n 2
0t
==
T 法测速的分辨率:
)
1(6060)
1(602
20
2
02
0-=
-
-=
M
ZM f ZM
f M
Z f Q 或Zn
f Zn
Q -=
02
60
T法测速误差率:
%
1001
1
%10060
60 )1(60%2
2
02
02
max ?-=
?-=
M
ZM
f ZM
f M
Z f δ
T 法测速适用于低速段。
三、软件综合设计
1.设计流程图:
总体流程图
保护现场
禁止测速
开启定时器0产生高频脉冲并计数
允许测速?恢复现场
中断返回
关定时器0,关外部中断允许
计算转速并清零高频脉冲计数值
是
否
测速流程图
2. PID 两种基本算法:位置算法和增量算法,采用变频调速
(1)位置算法:
)
,()]
1()([)()()(0
P D D I
P
I K
j D I P K T
T K T T K K k e k e K j e K k e K k u =
=--++=∑=
(2)增量算法:
)]
2()1(2)([)()]1()([)
1()()(-+--++--=--=?k e k e k e K k e K k e k e K k u k u k u D I P
3.实现以上要求的控制算法(已调试正确):
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define F 6 //表示光电码盘一圈的齿数
#define T 40 //采样周期10ms,250us为单位
#define PID_K 2
#define PID_I 0.1
#define PID_D 0.1
#define ST_cishu 50 //更新显示频率设为0.5s,10ms为单位
sbit clk=P1^0; //脉冲
sbit cw=P1^1; //转向
sbit full=P1^2; //半步、全步
sbit reset=P1^3;
sbit duanen=P2^6; //段选锁存
sbit weien=P2^7; //位选锁存
sbit fuhao=P2^2; //正负符号位
sbit dirKey = P3^4; //设置位移
sbit plusKey = P3^5;
sbit subKey = P3^6;
sbit revKey = P3^7; //反转
int Uk_1 = 0;
int Uk = 0;
uchar posKey = 0; //屏幕显示位置标志
int speed[3] = {0, 0 ,0}; //存速度差值
int Si,n=0,m=0; //n为转速,m为T法高速脉冲个数,Si 为m记数允许标志位
uchar time_n1=500;
uchar time_n2;
int speedSet,speed_set; //定时器1首先就输出一个电平变化,再根据PID输出设置z=speed_set
int speed_n=0; //用于显示的测试的速度
int outallow=1; //输出允许,第一次设置完生效,开始输出
int ST_allow; //速度测试允许位
int ST_counter=0; //计数变量,用于计显示更新频率
int fankui=0;
void display(int);
void delay(int);
void LED(int,int);
void xiaoying(void);
void readKey();
void initial();
void pid();
void pid_f_to_time_n1();
void ST_get();
/****************************初始化***************************/
void initial()
{
IE=0x80; //开总中断
TCON=0x01;//IT0=1时外部中断0为下跳沿触发
TMOD=0x21;//定时器0工作方式1,定时器1工作方式2,自动重载 TH0=0xec; //定时5ms,初值为60536,产生高速脉冲
TL0=0x78;
TH1=0x06; //定时250us,输出脉冲精度
TL1=0x06;
Si=0;
time_n2=1;
clk = 1;
}
/**************************显示函数****************************/
void delay(int i)
{
int x,y;
for(x=i;x>0;x--)
{for(y=1;y<333;y++);}
}
void xiaoying()
{
weien=1;
P0=0xff;
weien=0;
}
void LED(int shu,int wei)
{
uchar code DSY_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; //最后为负号
uchar code DSY_WEI[]={0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
P0=DSY_CODE[shu];
duanen=0;
weien=1;
P0=DSY_WEI[wei];
weien=0;
delay(2);
}
void display(int a) //a 为测得转速{
int qian;
int bai;
int shi;
int ge;
if (a<0)
{
LED(10,4);
xiaoying();
(int)qian=-a/1000;
(int)bai=-a%1000/100;
(int)shi=-a%100/10;
(int)ge=-a%10;
}
else
{
(int)qian=a/1000;
(int)bai=a%1000/100;
(int)shi=a%100/10;
(int)ge=a%10;
}
LED(qian,3);
xiaoying();
LED(bai,2);
xiaoying();
xiaoying();
LED(ge,0);
xiaoying();
}
/******************************PID************************* ***/
void pid()
{
Uk = PID_K * (speed[2]-speed[1]) + PID_I * speed[2] + PID_D *(speed[2]2*speed[1]+speed[0])+Uk_1; //增量式算法
Uk_1 = Uk;
if(Uk>150) //越界处理
{
Uk=Uk_1;
}
}
void pid_f_to_time_n1()
{
if(time_n1>4) //频率最高不能超过1500Hz,设定最高为1000Hz 250us*4=1ms
{
time_n1 = 600 / Uk; // 步距角为 1.8 估T=1/f=0.3*n. T=250us*2*time_n1(us) Uk~f
}
else {time_n1=6;}
}
/***********************速度差值计算***************************/
void delta_n()
{
speed[0] = speed[1];
speed[1] = speed[2];
speed[2] = speed_set-n;
}
/***************************速度检测**************************/
void ST_time() interrupt 0 //外部中断0
{
if (Si==0) //Si为测试速度而设,Si=0,则记第一次,
Si=1,则应关闭TR0
{
TR0=1;
Si=1; //关闭标志,表明测量一个周期内波形完成 }
else
{
TR0=0;
IE=IE&0xfc; //关定时中断0和外部中断0
Si=0;
(int)n=60000/(m*F*5);//计算转速F为放大系数,表示转一圈输出多少脉冲
if (!fuhao)
{
n=-n;
}
m=0;
}
}
void ST_count() interrupt 1 //定时中断0,产生高速脉冲,10ms 一次
{
m++;
if(m>10000) //若转速低至10s一个信号,则认为转速为0,防止m越界
{n=0;}
TH0=0xec;
TL0=0x78;
}
void ST_get() //获取速度函数,供外部调用
{
IE=IE|0x03; //开定时器0和外部中断0 定时器IE 设置位,EA, , ,ES,ET1,EX1,ET0,EX0
}
/**************************速度输出****************************/
void SO_time() interrupt 3 //定时中断1,用于定时输出脉冲
{
time_n2--; //250us一次
if (!time_n2)
{
time_n2=time_n1; //上个脉冲完后再取新设置的值
clk=~clk;
}
fankui++;
if (fankui==33)
{
clkf=~clkf;
fankui=0;
}
ST_allow++; //定时采样允许,采样周期40*250us=10ms
if (ST_allow==T)
{
ST_allow=0;
ST_get(); //开中断,不会影响时间
}
}
/**********************键盘设置函数****************************/
void readKey()
{
int temp = 0;
if(dirKey == 0)
{
delay(30);
while(!dirKey); //放开生效,不影响中断
posKey = posKey + 1;
if(posKey >= 4)
{
posKey = 0;
speed_set=speedSet; //设置完四个数,使设置生效
if(outallow) //初始为1
{
ET1=1; //定时1中断允许,开始输出脉冲
TR1=1; //输出允许
outallow=0;
}
}
}
//显示
if(posKey) //在设置时才能按