xxda 学
自动化学院综合实验报告
题 目: 直流电机闭环调速系统
学生姓名:
学 号: xx 同组人员: xx 指导教师: xx
直流电机闭环调速系统实验报告
一、实验名称:直流电机闭环调速
基本情况:
1. 学生姓名:xx
2. 学 号:x
3. 班 级:0830902班
4. 实验项目组长:xx
5. 同组其他成员:
6. 具体分工:
7. 本人在项目组的作用描述:
本次综合实验的目的是在于实现直流电机的闭环调速,我在本次实验的主要负责的是软
件程序设计,也就是应用C 语言进行编程,PID 控制主要是要通过比例项、积分项、微分项
三项的控制来实现调速功能。编写了计时器T0产生PWM 波、通过改变占空比实现;用T1
记录脉冲来确定转速;在键盘输入上改变转速的额定值,观察实际转速,显示最终的实际数
值。最终确定了调解中的各项系数:Kp = 0.4,Ki = 0.02, Kd = 0.02 。
二、实验内容(实验原理介绍) :
2.1 实验内容
1) 基于51单片机PWM 输出控制直流电机转速;
2) 可以实时显示电机转速,同时显示设定值以及给定值
3) 可以通过按键设定直流电机转速,即实现加减速(转/秒,r/s);
4) 可以调节P 、I 、D 参数,通过PID 调速使电机转速逐渐稳定;
2.2 实验原理
2.2.1系统框图
2.2.2实验原理
该系统是基于51单片机最小系统的控制系统,由51单片机产生PWM ,由驱
动芯片L298N 驱动电机转动,再由红外对射传感器产生脉冲输入单片机,单片机
经过PID 算法调节占空比实现对电机速度的控制和调节。
PWM 控制的基本原理:
在采样控制理论中有一个重要的结论:冲量相等而形状不同的窄脉冲加在具
有惯性的环节上时,其效果基本相同。冲量指窄脉冲的面积。这里所说的效果基
本相同,是指环节的输出响应波形基本相同。低频段非常接近,仅在高频段略有
差异。
由于PWM 调速系统的开关频率较高,仅靠电枢电感的滤波作用就可获得平稳
的直流电流,低速特性好、稳速精度高、调速范围宽。同样,由于开关频率高,
快速响应特性好, 动态抗干扰能力强,可以获得很宽的频带;开关器件只工作在
开关状态,因此主电路损耗小、装置效率高;直流电源采用不可控整流时,电网
功率因数比相控整流器高。
数字PID 算法
1、PID 控制系统组成
2、 PID 调节器的微分方程和传递函数
PID调节器是一种线性调节器,它将给定值r(t)与实际输出值c(t)的偏差
的比例(P)、积分(I)、微分(D)通过线性组合构成控制量,对控制对象进行控制。
PID 调节器的微分方程:
⎡1u (t ) =K P ⎢e (t ) +T I ⎣
式中 e (t ) ⎰t 0e (t ) dt +T D de (t ) ⎤⎥ dt ⎦=r (t ) -c (t )
⎡⎤U (S ) 1=K P ⎢1++T D S ⎥ E (S ) T I S ⎣⎦
PID调节器的传输函数:D (S ) = 3模拟PID 控制规律的离散化
4、数字PID 控制器的差分方程
⎧⎫T D T n [e (n ) -e (n -1) ]⎬+u 0u (n ) =K P ⎨e (n ) +e (i ) +∑T I i =0T ⎩⎭
=u P (n ) +u I (n ) +u D (n ) +u 0
式中 u P (n ) =K P e (n ) 比例项 T u (n ) =K I P T I
u D (n ) =K P ∑e (i ) 积分项 i =0n T D [e (n ) -e (n -1) ] 微分项 T
5、 PID调节器各校正环节的作用
(1)比例环节:即时成比例地反应控制系统的偏差信号e(t),偏差一旦产
生,调节器立即产生控制作用以减小偏差。
(2)积分环节:主要用于消除静差,提高系统的无差度。积分作用的强弱取
决于积分时间常数TI ,TI 越大,积分作用越弱,反之则越强。
(3)微分环节:能反应偏差信号的变化趋势(变化速率) ,并能在偏差信号的
值变得太大之前,在系统中引入一个有效的早期修正信号,从而加快系统的动作
速度,减小调节时间。
三、实验结果分析(含程序、数据记录、控制算法及分析和实验总结等):
3.1 程序流程图
3.2源程序
/*计时器T0用于产生PWM 脉冲,同时T1
/************************************用于计数器模式,记录脉冲的个数,确定转
******************************/ 速*/
/* 函数声明 #include */
/************************************#include //标准输入输出
******************************/ #include//移位头函数
#include // void PWMOut();
#define uchar unsigned char /************************************
#define uint unsigned int ******************************/
#define Data P0//数据端口 /* 微秒延时函数 #define THCon 0xfc */
/************************************#define TLCon 0x66 //初值 1ms
******************************/
sbit P1_0 = P1^0; void DelayUs(unsigned char us)//delay us
sbit P1_1 = P1^1; {
unsigned char uscnt; sbit RS = P2^4; //Pin4 改 P2^5
sbit RW = P2^5; //Pin5 P2^6 uscnt=us>>1; /*12MHz频率*/
sbit E = P2^6; //Pin6 P2^7 while(--uscnt);
} sbit key1 = P3^0; //键盘改
sbit key2 = P3^1; /************************************
******************************/
char data TimeNum[]=" "; /* 毫秒函数声明 char data Test1[]=" "; */
char ge,shi,bai,ge1,shi1,bai1; // /************************************
sbit test = P1^3; ******************************/
void DelayMs(unsigned char ms) sbit PWM_C = P1^2 ; //pwm控制端
P3^3 {
while(--ms) int e = 0, e1 = 0, e2 = 0; //pid偏差
{ float uk = 0, uk1 = 0.0, duk = 0.0; //pid输
DelayUs(250); 出值
float Kp = 0.4,Ki = 0.02, Kd = 0.02 ; DelayUs(250);
DelayUs(250); //pid控制系数
int out; DelayUs(250);
uint SpeedSet = 16; }
uint cnt = 0; }
/************************************uint num = 0; //脉冲计数 Impluse =
0, ******************************/
uint PWM_Time = 50; //脉冲/* 写入命令函数
*/ 宽度
/************************************
******************************/ p=pos+0xb0; //是第二行则命令代void WriteCommand(unsigned char c) 码高4位为0xc
{ else
DelayMs(5);//操作前短暂延时,保证信 p=pos+0x80; //是第二行则命令代号稳定 码高4位为0x8
E=0; WriteCommand (p);//写命令
RS=0; WriteData (c); //写数据
RW=0; }
_nop_(); /************************************ E=1; ******************************/ Data=c; /* 写入字符串函数 E=0; */
} /************************************/******************************************************************/
******************************/ void ShowString (unsigned char line,char
*ptr) /* 写入数据函数
*/ {
/************************************ unsigned char l,i;
******************************/ l=line
void WriteData(unsigned char c) for (i=0;i
{ ShowChar (l++,*(ptr+i));//循环显示16 DelayMs(5); //操作前短暂延时,保证个字符
} 信号稳定
E=0; /************************************ RS=1; ******************************/ RW=0; /* 初始化函数 _nop_(); */
E=1; /************************************ Data=c; ******************************/ E=0; void init()
RS=0; {
} TMOD = 0x51;
/************************************ TH0 = THCon;
******************************/ TL0 = TLCon;
TH1 = 0; /* 写入字节函数
*/ TL1 = 0;
/************************************ //EA = 1;
******************************/ ET0 = 1;
void ShowChar(unsigned char pos,unsigned TR0 = 1;//开始计时器0
char c)
{ ET1 = 1;
unsigned char p; TR1 = 1;//开始计数器1
if (pos>=0x10)
{
EA = 1; ge = numa%10;
e = 0; shi = numa/10%10;
e1 = 0; bai = numa/100%10;
e2 = 0; }
} void AnalysisCu(char numa)
void InitLcd() {
{ ge1 = numa%10;
DelayMs(15); shi1 = numa/10%10;
WriteCommand(0x38); //display mode bai1 = numa/100%10;
WriteCommand(0x38); //display mode }
WriteCommand(0x38); //display mode
WriteCommand(0x06); //显示光标移动void PIDControl()
位置 {
WriteCommand(0x0c); //显示开及光标 e = SpeedSet*4 - num;
设置 duk = ( Kp*(e-e1) + Ki*e WriteCommand(0x01); //显示清屏 Kd*(e-2*e1+e2)); //kp*(error1-error2) ki*error1 + kd*(error1-2*error2+error3) DelayMs(15); uk = uk1 + duk;
sprintf(Test1,"set speed:"); //打印输出 out = (int)uk;//
第一行信息 if(out > 100)
ShowString(0,Test1); {
out = 100;
sprintf(TimeNum,"current:");//打印输 }
出第二行信息 else if(out
ShowString(1,TimeNum); {
} out = 0;
}
void keyscan() uk1 = uk;
{ e2 = e1;
if(!key1) e1 = e;
{ //按下相应的按键,数码管显 PWM_Time = out; // out
示相应的码值 }
DelayMs(5); void Delay(uchar k)
if(!key1) {
{ uint i = 0,j = 0;
SpeedSet++; for(i = k;i > 0;i--)
// P1_0=~P1_0; {
// num++; for(j = 50; j > 0; j--);
} }
} }
} void PWMOut()
void AnalysisData(char numa) {
+ +
if(cnt
{ AnalysisData(SpeedSet);
PWM_C = 1; WriteCommand(0x80+0x0c); }
else WriteData(0x30+bai); { WriteData(0x30+shi); PWM_C = 0; WriteData(0x30+ge); if(cnt >= 100) DelayMs(200);
{
cnt = 0; AnalysisCu(num/4); } WriteCommand(0x80+0x49); } WriteData(0x30+bai1); WriteData(0x30+shi1); WriteData(0x30+ge1); } DelayMs(200);
PWMOut();
}
/************************************
******************************/ }
/************************************/* 主函数
*/ ******************************/ /************************************
******************************/ void exter0() interrupt 0 using 1
void main(void) {
// Impluse++;
{ // P1_0 = ~P1_0;
init(); }
void timer0() interrupt 1 InitLcd(); //初始化LCD
{ DelayMs(15); //延时保证信号稳
// static unsigned char Bit = 0; 定
P1_0 = 1; static unsigned int time = 0;
TH0 = THCon; //sprintf(Test1," set speed:" ); //打印输
TL0 = TLCon; 出第一行信息
//ShowString(0,Test1); cnt++; //pid脉冲周期
//
//sprintf(TimeNum,"current:");//打印输 time++; //转速测量周期
出第二行信息
//ShowString(1,TimeNum);
PWMOut();
if(time >= 100)
while(1) {
{ time = 0;
num = (TH1*256+TL1);//4个脉冲,转一圈 Impluse/4
P1_1 = ~P1_1;
TH1 = 0;
TL1 = 0;
//Impluse = 0;
PIDControl();
}
}
3.3硬件原理图
3.4实验心得
本次综合实验是在课外时间完成,复习了很多东西,自动控制原理,程序编写等,在PID 的控制中,根据组长的分配任务,前期了解了一些程序编写中应该设计的控制量,基本上还是基于单片机上的程序,难度有点大,很多东西需要尹辉的帮助。
在实验中也遇到了一些问题,Kp 、Ki 、Kd 的数值上的选取、计算等,以及闭环反馈的相关调节。实际上编程难度对自己来说比较大,一是一段时间没有进行这方面的操作,二是自己编程比较薄弱。
最终通过大三时期的比例、微分、积分各个实验的程序和当时的实验资料,基本编出实现调速功能的程序,这次综合实验最大的好处就是为毕业设计做了一些好的复习。
10
xxda 学
自动化学院综合实验报告
题 目: 直流电机闭环调速系统
学生姓名:
学 号: xx 同组人员: xx 指导教师: xx
直流电机闭环调速系统实验报告
一、实验名称:直流电机闭环调速
基本情况:
1. 学生姓名:xx
2. 学 号:x
3. 班 级:0830902班
4. 实验项目组长:xx
5. 同组其他成员:
6. 具体分工:
7. 本人在项目组的作用描述:
本次综合实验的目的是在于实现直流电机的闭环调速,我在本次实验的主要负责的是软
件程序设计,也就是应用C 语言进行编程,PID 控制主要是要通过比例项、积分项、微分项
三项的控制来实现调速功能。编写了计时器T0产生PWM 波、通过改变占空比实现;用T1
记录脉冲来确定转速;在键盘输入上改变转速的额定值,观察实际转速,显示最终的实际数
值。最终确定了调解中的各项系数:Kp = 0.4,Ki = 0.02, Kd = 0.02 。
二、实验内容(实验原理介绍) :
2.1 实验内容
1) 基于51单片机PWM 输出控制直流电机转速;
2) 可以实时显示电机转速,同时显示设定值以及给定值
3) 可以通过按键设定直流电机转速,即实现加减速(转/秒,r/s);
4) 可以调节P 、I 、D 参数,通过PID 调速使电机转速逐渐稳定;
2.2 实验原理
2.2.1系统框图
2.2.2实验原理
该系统是基于51单片机最小系统的控制系统,由51单片机产生PWM ,由驱
动芯片L298N 驱动电机转动,再由红外对射传感器产生脉冲输入单片机,单片机
经过PID 算法调节占空比实现对电机速度的控制和调节。
PWM 控制的基本原理:
在采样控制理论中有一个重要的结论:冲量相等而形状不同的窄脉冲加在具
有惯性的环节上时,其效果基本相同。冲量指窄脉冲的面积。这里所说的效果基
本相同,是指环节的输出响应波形基本相同。低频段非常接近,仅在高频段略有
差异。
由于PWM 调速系统的开关频率较高,仅靠电枢电感的滤波作用就可获得平稳
的直流电流,低速特性好、稳速精度高、调速范围宽。同样,由于开关频率高,
快速响应特性好, 动态抗干扰能力强,可以获得很宽的频带;开关器件只工作在
开关状态,因此主电路损耗小、装置效率高;直流电源采用不可控整流时,电网
功率因数比相控整流器高。
数字PID 算法
1、PID 控制系统组成
2、 PID 调节器的微分方程和传递函数
PID调节器是一种线性调节器,它将给定值r(t)与实际输出值c(t)的偏差
的比例(P)、积分(I)、微分(D)通过线性组合构成控制量,对控制对象进行控制。
PID 调节器的微分方程:
⎡1u (t ) =K P ⎢e (t ) +T I ⎣
式中 e (t ) ⎰t 0e (t ) dt +T D de (t ) ⎤⎥ dt ⎦=r (t ) -c (t )
⎡⎤U (S ) 1=K P ⎢1++T D S ⎥ E (S ) T I S ⎣⎦
PID调节器的传输函数:D (S ) = 3模拟PID 控制规律的离散化
4、数字PID 控制器的差分方程
⎧⎫T D T n [e (n ) -e (n -1) ]⎬+u 0u (n ) =K P ⎨e (n ) +e (i ) +∑T I i =0T ⎩⎭
=u P (n ) +u I (n ) +u D (n ) +u 0
式中 u P (n ) =K P e (n ) 比例项 T u (n ) =K I P T I
u D (n ) =K P ∑e (i ) 积分项 i =0n T D [e (n ) -e (n -1) ] 微分项 T
5、 PID调节器各校正环节的作用
(1)比例环节:即时成比例地反应控制系统的偏差信号e(t),偏差一旦产
生,调节器立即产生控制作用以减小偏差。
(2)积分环节:主要用于消除静差,提高系统的无差度。积分作用的强弱取
决于积分时间常数TI ,TI 越大,积分作用越弱,反之则越强。
(3)微分环节:能反应偏差信号的变化趋势(变化速率) ,并能在偏差信号的
值变得太大之前,在系统中引入一个有效的早期修正信号,从而加快系统的动作
速度,减小调节时间。
三、实验结果分析(含程序、数据记录、控制算法及分析和实验总结等):
3.1 程序流程图
3.2源程序
/*计时器T0用于产生PWM 脉冲,同时T1
/************************************用于计数器模式,记录脉冲的个数,确定转
******************************/ 速*/
/* 函数声明 #include */
/************************************#include //标准输入输出
******************************/ #include//移位头函数
#include // void PWMOut();
#define uchar unsigned char /************************************
#define uint unsigned int ******************************/
#define Data P0//数据端口 /* 微秒延时函数 #define THCon 0xfc */
/************************************#define TLCon 0x66 //初值 1ms
******************************/
sbit P1_0 = P1^0; void DelayUs(unsigned char us)//delay us
sbit P1_1 = P1^1; {
unsigned char uscnt; sbit RS = P2^4; //Pin4 改 P2^5
sbit RW = P2^5; //Pin5 P2^6 uscnt=us>>1; /*12MHz频率*/
sbit E = P2^6; //Pin6 P2^7 while(--uscnt);
} sbit key1 = P3^0; //键盘改
sbit key2 = P3^1; /************************************
******************************/
char data TimeNum[]=" "; /* 毫秒函数声明 char data Test1[]=" "; */
char ge,shi,bai,ge1,shi1,bai1; // /************************************
sbit test = P1^3; ******************************/
void DelayMs(unsigned char ms) sbit PWM_C = P1^2 ; //pwm控制端
P3^3 {
while(--ms) int e = 0, e1 = 0, e2 = 0; //pid偏差
{ float uk = 0, uk1 = 0.0, duk = 0.0; //pid输
DelayUs(250); 出值
float Kp = 0.4,Ki = 0.02, Kd = 0.02 ; DelayUs(250);
DelayUs(250); //pid控制系数
int out; DelayUs(250);
uint SpeedSet = 16; }
uint cnt = 0; }
/************************************uint num = 0; //脉冲计数 Impluse =
0, ******************************/
uint PWM_Time = 50; //脉冲/* 写入命令函数
*/ 宽度
/************************************
******************************/ p=pos+0xb0; //是第二行则命令代void WriteCommand(unsigned char c) 码高4位为0xc
{ else
DelayMs(5);//操作前短暂延时,保证信 p=pos+0x80; //是第二行则命令代号稳定 码高4位为0x8
E=0; WriteCommand (p);//写命令
RS=0; WriteData (c); //写数据
RW=0; }
_nop_(); /************************************ E=1; ******************************/ Data=c; /* 写入字符串函数 E=0; */
} /************************************/******************************************************************/
******************************/ void ShowString (unsigned char line,char
*ptr) /* 写入数据函数
*/ {
/************************************ unsigned char l,i;
******************************/ l=line
void WriteData(unsigned char c) for (i=0;i
{ ShowChar (l++,*(ptr+i));//循环显示16 DelayMs(5); //操作前短暂延时,保证个字符
} 信号稳定
E=0; /************************************ RS=1; ******************************/ RW=0; /* 初始化函数 _nop_(); */
E=1; /************************************ Data=c; ******************************/ E=0; void init()
RS=0; {
} TMOD = 0x51;
/************************************ TH0 = THCon;
******************************/ TL0 = TLCon;
TH1 = 0; /* 写入字节函数
*/ TL1 = 0;
/************************************ //EA = 1;
******************************/ ET0 = 1;
void ShowChar(unsigned char pos,unsigned TR0 = 1;//开始计时器0
char c)
{ ET1 = 1;
unsigned char p; TR1 = 1;//开始计数器1
if (pos>=0x10)
{
EA = 1; ge = numa%10;
e = 0; shi = numa/10%10;
e1 = 0; bai = numa/100%10;
e2 = 0; }
} void AnalysisCu(char numa)
void InitLcd() {
{ ge1 = numa%10;
DelayMs(15); shi1 = numa/10%10;
WriteCommand(0x38); //display mode bai1 = numa/100%10;
WriteCommand(0x38); //display mode }
WriteCommand(0x38); //display mode
WriteCommand(0x06); //显示光标移动void PIDControl()
位置 {
WriteCommand(0x0c); //显示开及光标 e = SpeedSet*4 - num;
设置 duk = ( Kp*(e-e1) + Ki*e WriteCommand(0x01); //显示清屏 Kd*(e-2*e1+e2)); //kp*(error1-error2) ki*error1 + kd*(error1-2*error2+error3) DelayMs(15); uk = uk1 + duk;
sprintf(Test1,"set speed:"); //打印输出 out = (int)uk;//
第一行信息 if(out > 100)
ShowString(0,Test1); {
out = 100;
sprintf(TimeNum,"current:");//打印输 }
出第二行信息 else if(out
ShowString(1,TimeNum); {
} out = 0;
}
void keyscan() uk1 = uk;
{ e2 = e1;
if(!key1) e1 = e;
{ //按下相应的按键,数码管显 PWM_Time = out; // out
示相应的码值 }
DelayMs(5); void Delay(uchar k)
if(!key1) {
{ uint i = 0,j = 0;
SpeedSet++; for(i = k;i > 0;i--)
// P1_0=~P1_0; {
// num++; for(j = 50; j > 0; j--);
} }
} }
} void PWMOut()
void AnalysisData(char numa) {
+ +
if(cnt
{ AnalysisData(SpeedSet);
PWM_C = 1; WriteCommand(0x80+0x0c); }
else WriteData(0x30+bai); { WriteData(0x30+shi); PWM_C = 0; WriteData(0x30+ge); if(cnt >= 100) DelayMs(200);
{
cnt = 0; AnalysisCu(num/4); } WriteCommand(0x80+0x49); } WriteData(0x30+bai1); WriteData(0x30+shi1); WriteData(0x30+ge1); } DelayMs(200);
PWMOut();
}
/************************************
******************************/ }
/************************************/* 主函数
*/ ******************************/ /************************************
******************************/ void exter0() interrupt 0 using 1
void main(void) {
// Impluse++;
{ // P1_0 = ~P1_0;
init(); }
void timer0() interrupt 1 InitLcd(); //初始化LCD
{ DelayMs(15); //延时保证信号稳
// static unsigned char Bit = 0; 定
P1_0 = 1; static unsigned int time = 0;
TH0 = THCon; //sprintf(Test1," set speed:" ); //打印输
TL0 = TLCon; 出第一行信息
//ShowString(0,Test1); cnt++; //pid脉冲周期
//
//sprintf(TimeNum,"current:");//打印输 time++; //转速测量周期
出第二行信息
//ShowString(1,TimeNum);
PWMOut();
if(time >= 100)
while(1) {
{ time = 0;
num = (TH1*256+TL1);//4个脉冲,转一圈 Impluse/4
P1_1 = ~P1_1;
TH1 = 0;
TL1 = 0;
//Impluse = 0;
PIDControl();
}
}
3.3硬件原理图
3.4实验心得
本次综合实验是在课外时间完成,复习了很多东西,自动控制原理,程序编写等,在PID 的控制中,根据组长的分配任务,前期了解了一些程序编写中应该设计的控制量,基本上还是基于单片机上的程序,难度有点大,很多东西需要尹辉的帮助。
在实验中也遇到了一些问题,Kp 、Ki 、Kd 的数值上的选取、计算等,以及闭环反馈的相关调节。实际上编程难度对自己来说比较大,一是一段时间没有进行这方面的操作,二是自己编程比较薄弱。
最终通过大三时期的比例、微分、积分各个实验的程序和当时的实验资料,基本编出实现调速功能的程序,这次综合实验最大的好处就是为毕业设计做了一些好的复习。
10