闭环调速实验报告

时间:2024.4.5

     绩:           

重庆邮电大学

自动化学院综合实验报告

             目:51系列单片机直流电机闭环调速实验               

学生姓名:                            

    级:0841004                             

    号:2010213316                               

同组人员:李海涛   陈超                            

指导教师:                                

完成时间:201312                         

一、实验名称:

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

               ——基于Protuse仿真实验平台实现

基本情况:

1. 学生姓名:蒋运和

2.     号:2010213316

3.     级:0841004

4. 同组其他成员:

二、实验内容(实验原理介绍)

1、直流电机调速原理

图1所示电枢电压为V,电枢电流I,电枢回路总电阻为R,电机常数C,励磁磁通量Φ。

那么根据KVL方程:电机转速,其中,对于极对数为P,匝数为N,电枢支路数为a的电机来说:电机常数,意味着电机确定后,该值是不变的。

而在V-IR中,由于R仅为绕组电阻,导致IR非常小,所以V-IR≈V。

由此可见我们改变电枢电压,转速n即可随之改变。

实现直流电机的闭环调速

实现原理如下图所示:

2、测速软件设计

图12  软件测速的方框图

/****T1中断服务程序********单位时间(S)方波的个数*************/

void time1_int(void) interrupt 3

{  

count_speed++;

if(count_speed == 20)

{   count_speed = 0;

num_display = num_medium;

num_medium = 0;

}
}

3、PID算法的数字实现

由于DDC(Direct Digital Control)系统是一种时间离散控制系统。因此,为了用微机实现(式3-1-1)必须将其离散化,

用数字形式的差分方程来代替连续系统的微分方程。离散化的PID表达式为:

              (式3-1-2)

式中,——采样周期;

  ——第n次采样时微机输出;

——第n次采样时的偏差值;

              ——第n-1次采样时的偏差值;

        ——采样序号,n=0,1,2,…。

   通常把(式3-1-2)称为PID的位置控制算式。根据(式3-1-2)可以进一步推导出离散化的位置型PID编程表达式,如(式3-1-3):

  第K次采样PID的输出式为:

                                       (式3-1-3)

其中,设

式中,

      确定了的值后,实现(式3-1-3)的编程框图如右图所示:由(式3-1-3)还可得离散化的位置型P控制和PI控制的编程表达式。它们各自的编程框图也只需在该图的基础上稍作删减即可。

4、调速设计方案

调速采用PWM(Pulse Width Modulation)脉宽调制,工作原理:通过产生矩形波,改变占空比,以达到调整脉宽的目的。PWM的定义:脉宽调制(PWM)是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。模拟信号的值可以连续变化,其时间和幅度的分辨率都没有限制。9V电池就是一种模拟器件,因为它的输出电压并不精确地等于9V,而是随时间发生变化,并可取任何实数值。与此类似,从电池吸收的电流也不限定在一组可能的取值范围之内。模拟信号与数字信号的区别在于后者的取值通常只能属于预先确定的可能取值集合之内,例如在{0V,5V}这一集合中取值。

模拟电压和电流可直接用来进行控制,如对汽车收音机的音量进行控制。在简单的模拟收音机中,音量旋钮被连接到一个可变电阻。拧动旋钮时,电阻值变大或变小;流经这个电阻的电流也随之增加或减少,从而改变了驱动扬声器的电流值,使音量相应变大或变小。与收音机一样,模拟电路的输出与输入成线性比例。
    尽管模拟控制看起来可能直观而简单,但它并不总是非常经济或可行的。其中一点就是,模拟电路容易随时间漂移,因而难以调节。能够解决这个问题的精密模拟电路可能非常庞大、笨重(如老式的家庭立体声设备)和昂贵。模拟电路还有可能严重发热,其功耗相对于工作元件两端电压与电流的乘积成正比。模拟电路还可能对噪声很敏感,任何扰动或噪声都肯定会改变电流值的大小。通过以数字方式控制模拟电路,可以大幅度降低系统的成本和功耗。此外,许多微控制器和DSP已经在芯片上包含了PWM控制器,这使数字控制的实现变得更加容易了。

5、电路原理图

三、实验结果分析(含程序、数据记录及分析和实验总结等,可附页):

1、51系列单片机直流电机闭环调速实验程序

       /*--------------------------------------------------------------------------

REG52.H

Header file for generic 80C52 and 80C32 microcontroller.

Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc.

All rights reserved.

--------------------------------------------------------------------------*/

#ifndef __REG52_H__

#define __REG52_H__

/*  BYTE Registers  */

sfr P0    = 0x80;

sfr P1    = 0x90;

sfr P2    = 0xA0;

sfr P3    = 0xB0;

sfr PSW   = 0xD0;

sfr ACC   = 0xE0;

sfr B     = 0xF0;

sfr SP    = 0x81;

sfr DPL   = 0x82;

sfr DPH   = 0x83;

sfr PCON  = 0x87;

sfr TCON  = 0x88;

sfr TMOD  = 0x89;

sfr TL0   = 0x8A;

sfr TL1   = 0x8B;

sfr TH0   = 0x8C;

sfr TH1   = 0x8D;

sfr IE    = 0xA8;

sfr IP    = 0xB8;

sfr SCON  = 0x98;

sfr SBUF  = 0x99;

/*  8052 Extensions  */

sfr T2CON  = 0xC8;

sfr RCAP2L = 0xCA;

sfr RCAP2H = 0xCB;

sfr TL2    = 0xCC;

sfr TH2    = 0xCD;

/*  BIT Registers  */

/*  PSW  */

sbit CY    = PSW^7;

sbit AC    = PSW^6;

sbit F0    = PSW^5;

sbit RS1   = PSW^4;

sbit RS0   = PSW^3;

sbit OV    = PSW^2;

sbit P     = PSW^0; //8052 only

/*  TCON  */

sbit TF1   = TCON^7;

sbit TR1   = TCON^6;

sbit TF0   = TCON^5;

sbit TR0   = TCON^4;

sbit IE1   = TCON^3;

sbit IT1   = TCON^2;

sbit IE0   = TCON^1;

sbit IT0   = TCON^0;

/*  IE  */

sbit EA    = IE^7;

sbit ET2   = IE^5; //8052 only

sbit ES    = IE^4;

sbit ET1   = IE^3;

sbit EX1   = IE^2;

sbit ET0   = IE^1;

sbit EX0   = IE^0;

/*  IP  */

sbit PT2   = IP^5;

sbit PS    = IP^4;

sbit PT1   = IP^3;

sbit PX1   = IP^2;

sbit PT0   = IP^1;

sbit PX0   = IP^0;

/*  P3  */

sbit RD    = P3^7;

sbit WR    = P3^6;

sbit T1    = P3^5;

sbit T0    = P3^4;

sbit INT1  = P3^3;

sbit INT0  = P3^2;

sbit TXD   = P3^1;

sbit RXD   = P3^0;

/*  SCON  */

sbit SM0   = SCON^7;

sbit SM1   = SCON^6;

sbit SM2   = SCON^5;

sbit REN   = SCON^4;

sbit TB8   = SCON^3;

sbit RB8   = SCON^2;

sbit TI    = SCON^1;

sbit RI    = SCON^0;

/*  P1  */

sbit T2EX  = P1^1; // 8052 only

sbit T2    = P1^0; // 8052 only

            

/*  T2CON  */

sbit TF2    = T2CON^7;

sbit EXF2   = T2CON^6;

sbit RCLK   = T2CON^5;

sbit TCLK   = T2CON^4;

sbit EXEN2  = T2CON^3;

sbit TR2    = T2CON^2;

sbit C_T2   = T2CON^1;

sbit CP_RL2 = T2CON^0;

#endif

#ifndef TEST_H

#define TEST_H

#define u8 unsigned char

#define u16 unsigned int

////// LCD ////

sbit RS = P2^0;

sbit RW = P2^1;

sbit EN = P2^2;

//////L298/////

sbit IN1 = P2^5;

sbit IN2 = P2^6;

sbit ENA = P2^7;

void delay_ms(u16 z);

void LCD_WriteData(u8 Dat);

void LCD_WriteCOM(u8 com);

void Show_Num(u8 x,u8 y,u16 num);

void Show_fNum(u8 x,u8 y,u16 num);

void LCD_Init(void);

void set_Dir(u8 dir);

void key_scan(void);

extern void timer_init();

extern void timer0();

extern u16 count;

extern u8 num;

extern u16 set_value;

extern u8 kp,ki,kd;

#endif

#ifndef SPEED_H

#define SPEED_H

extern u16 count;

extern u8 pulse;

extern void Show_Num(u8 x,u8 y,u16 num);

#endif

 #include<reg52.h>

 #include"test.h"

u8 Dir=1;    //方向

/*************

函数功能:延时

****************/

void delay_ms(u16 z)

{

   u16 i;

   u8 j;

   for(i=z;i>0;i--)

     for(j=120;j>0;j--);                                                                 

}

/*************

函数功能:LCD写数据

****************/

void LCD_WriteData(u8 Dat)

{

   RS = 1;

   delay_ms(5);

   P0 = Dat;

   EN = 1;

   delay_ms(20);

   EN = 0;

  // delay_ms(15);

}

/*************

函数功能:LCD命令

****************/

void LCD_WriteCOM(u8 com)

{

   RS = 0;

   delay_ms(5);

   P0 = com;

   EN = 1;

   delay_ms(20);

   EN = 0;

  // delay_ms(15);

}

/*************

函数功能:Show_Num初始化

****************/

void Show_Num(u8 x,u8 y,u16 num)

{

   u8 a,b,c;

   a = num/100;

   b = num/10%10;

   c = num%10;

   if(y%2 == 1)

          LCD_WriteCOM(0x80+x);

        else

          LCD_WriteCOM(0x80+0x40+x);

   LCD_WriteData(a+0x30); 

   LCD_WriteData(b+0x30);

   LCD_WriteData(c+0x30);

}

/*************

函数功能:Show_fNum初始化 

****************/

void Show_fNum(u8 x,u8 y,u16 num)

{

   u8 a,b;

   a = num/10%10;

   b = num%10;

   if(y%2 == 1)

          LCD_WriteCOM(0x80+x);

        else

          LCD_WriteCOM(0x80+0x40+x);

   LCD_WriteData(a+0x30); 

   LCD_WriteData(b+0x30);

}

/*************

函数功能:Show_Num初始化

****************/

void Show_char(u8 x,u8 y,u8 ch)

{

   if(y%2 == 1)

          LCD_WriteCOM(0x80+x);

        else

          LCD_WriteCOM(0x80+0x40+x);

   LCD_WriteData(ch); 

}

/*************

函数功能:LCD 固定显示          

****************/

void LCD_Dispaly(void)

{

   Show_char(0,1,'P');  //实际测量值

   Show_char(1,1,'V');

   Show_char(2,1,':');

   Show_Num(3,1,0);

   Show_char(9,1,'S');  //设定值

   Show_char(10,1,'V');

   Show_char(11,1,':');

   Show_Num(12,1,set_value);

   Show_char(0,2,'P');  //P实际测量值

   Show_char(1,2,':');

   Show_fNum(2,2,kp);

   Show_char(6,2,'I');  //I实际测量值

   Show_char(7,2,':');

   Show_fNum(8,2,ki);

   Show_char(12,2,'D');  //D实际测量值

   Show_char(13,2,':');

   Show_fNum(14,2,kd);

}

/*************

函数功能:LCD初始化

****************/

void LCD_Init(void)

{

   RW = 0;

   EN = 0;

   delay_ms(20);

   LCD_WriteCOM(0x38);

   LCD_WriteCOM(0x0c);

   LCD_WriteCOM(0x06);

   LCD_WriteCOM(0x01);

   LCD_Dispaly();

}

/*************

函数功能:设置转向

****************/

void set_Dir(u8 dir)

{

   if(dir)

     {

           IN1 = 1;

              IN2 = 0;

        }

        else

        {

           IN1 = 0;

              IN2 = 1;

        }

        ENA = 1;

}

 int main(void)

  {

        LCD_Init();

        set_Dir(Dir);

        timer_init();

        EA = 1;

      

        while(1)

         {

              key_scan();

              Show_Num(3,1,count);

         }

     return  0;    

  }

void key_scan(void)

{

   u8 Temp=P1;

   static u8 Add_Ver=0,one_ten=0;

   static Tri=0,CON=0;

   Temp = Temp^0xff;

   Tri = Temp&(Temp^CON);

   CON = Temp;

   if(Tri==0x10)

     {Add_Ver++;Add_Ver=Add_Ver%2;}

   else if(Tri==0x20)

     {one_ten++;one_ten=one_ten%2;}

   else if(Tri==0x01)

      {

           if(set_value+1<=230&&Add_Ver==0&&one_ten==0)

                 set_value++;

              else if(set_value>=1&&Add_Ver==1&&one_ten==0)

                 set_value--;

              else if(set_value+10<=230&&Add_Ver==0&&one_ten==1)

                 set_value=set_value+10;

           else if(set_value>=10&&Add_Ver==1&&one_ten==1)

                 set_value=set_value-10;

               Show_Num(12,1,set_value);

         }

   else if(Tri==0x02)

      {

           if(kp+1<=100&&Add_Ver==0&&one_ten==0)

                   kp++;

              else if(kp>=1&&Add_Ver==1&&one_ten==0)

                   kp--;

              else if(kp+10<=100&&Add_Ver==0&&one_ten==1)

                   kp=kp+10;

           else if(kp>=10&&Add_Ver==1&&one_ten==1)

                   kp=kp-10;

           Show_fNum(2,2,kp);    

         }

        else if(Tri==0x04)

      {

           if(ki+1<=100&&Add_Ver==0&&one_ten==0)

                   ki++;

              else if(ki>=1&&Add_Ver==1&&one_ten==0)

                   ki--;

              else if(ki+10<=100&&Add_Ver==0&&one_ten==1)

                   ki=ki+10;

           else if(ki>=10&&Add_Ver==1&&one_ten==1)

                   ki=ki-10;

              Show_fNum(8,2,ki);

         }

         else if(Tri==0x08)

      {

           if(kd+1<=100&&Add_Ver==0&&one_ten==0)

                   kd++;

              else if(kd>=1&&Add_Ver==1&&one_ten==0)

                   kd--;

              else if(kd+10<=100&&Add_Ver==0&&one_ten==1)

                   kd=kd+10;

           else if(kd>=10&&Add_Ver==1&&one_ten==1)

                   kd=kd-10;

              Show_fNum(14,2,kd);

         }

}

#include<reg52.h>

#include"timer.h"

#include"test.h"

u16 count=0;         //脉冲计数

u8 num = 0;

u8 time=0;

u8 num1=0,pulse=50;

/*************

函数功能:计数  初始化

****************/

void timer0_init()

{

  TMOD |= 0X05;

  TH0   = 0;

  TL0   = 0;

  TR0   = 1;

}

/*************

函数功能:定时器1初始化

****************/

void timer1_init()

{

  TMOD|=0x10;

  TH1=(65535-50000)/256;  //20ms

  TL1=(65535-50000)%256;

  TR1=1;

  ET1=1;

}

/*************

函数功能:定时器2初始化

****************/

void timer2_init()

{

  RCAP2H =(65536-100)/256;    //50us

  RCAP2L =(65536-100)%256;

  TH2 = RCAP2H;

  TL2 = RCAP2L;

  ET2 = 1;

  TR2 = 1;

}

/*************

函数功能:定时器初始化

****************/

void timer_init()

{

   timer0_init();

   timer1_init();

   timer2_init();

}

void timer0() interrupt 3

{

  

  // EA = 0;

   TH1 = (65535-50000)/256;  //25ms

   TL1 = (65535-50000)%256;

     num++;

     if(num>=4)                   //100ms

     {

           num=0;

           count = TL0;

              TL0 = 0;

              TH0 = 0;

             

              speed();

        }   

  // EA = 1;

}

void timer2() interrupt 5

{

   TF2 = 0;

   num1++;

   if(num1>=pulse)

      IN1 = 0;

   if(num1>=PULSE)

         {IN1=1;num1=0;}

}

#include<reg52.h>

#include"test.h"

#include"speed.h"

u16 set_value=100;

u8 kp=25,ki=10,kd=15;

int uk=0;

/****************

函数功能:设定速度

****************/

void set_speed(u8 value)

{

   static int essd=0,essd1=0,essd2=0;

   essd = value-count;

   uk=kp*essd+ki*essd1+kd*(essd-essd2);

     essd2=essd;

     essd1+=essd;

   //uk =(int)(uk/100)+(int)(100*value/240);

   uk =(int)(uk/100);

   if(uk<0)

     pulse = 0;

        else if(uk<100)

         pulse=uk;

        else

         pulse=99;

   //Show_Num(0,2,uk);

}

void speed(void)

{

   set_speed(set_value);

}

2、实验总结

经过这次的实验,我又一次加深了对LED的认识和加强了对keil以及Protues等软件的使用技能。虽然之前做过很多的实验,但是自己任然存在很大的问题。在本次实验中任然有很多东西不会,所以又重新学了一遍单片机,加大了对单片机学习的兴趣。刚开始做实验时是很盲目的,胡乱的查资料。所以经过这次的实验我明白了做任何事之前都得有充分的准备和必要的预习。遇到困难是不可避免的,所以我们要做好随时挑战困难的准备,和同学团结,虚心请教老师,一起解决问题。做实验是需要耐心和信心的。比如在调试程序的时候要细心的检查错误。从这次的实验中我学会了把自己学的东西学以致用,学到了课本上没有的东西。很感谢学校,老师给我们这次锻炼的机会,在以后的学习中我会学好理论知识,将理论与实践相结合。不断提高自己动手能力。

 

更多相关推荐:
减速器实验报告

河北工程大学机械设计课程实验报告减速器拆装及其结构分析实验报告专业班级姓名学号实验日期年月日指导教师实验成绩一实验目的通过减速器拆装了解减速器的结构加工和装配工艺理解各种零件的结构和相互位置关系增加对整体机械产...

减速器拆装实验报告(含练习题答案)

减速器实验报告实验名称:减速器拆装实验学生姓名:***班级、组别:09机制5班实验日期:成绩:指导教师:一.实验目的1.通过拆装,了解齿轮减速器铸造箱体的结构以及轴和齿轮的结构;2.了解减速器轴上零件的定位和固…

减速器实验报告

东华理工大学长江学院课程设计报告课程设计题目二级圆柱减速器实验报告学生姓名饶坤班级11300103学号1130010316指导教师廖志良20xx年12月30日二级圆柱减速器实验报告实验减速器拆装实验一目的要求1...

减速器装拆实验报告

减速器装拆实验报告姓名班级日期同组实验者姓名报告内容1减速器测量数据记录格式及项目见下表2减速器主要零部件作用和名称格式及项目见下表3传动比计算4装配草图去除箱体零件5装配系统图15项每组一份6每人四题组内人员...

减速器实验报告

减速器实验报告1实验目的2实验内容3实验装备4实验步骤5画出拆去上盖后的减速器视图6思考题讨论

减速器拆装实验报告

哈尔滨工程大学实验报告实验名称减速器拆装及测量实验班级学号姓名实验时间成绩指导教师实验室名称机械拆装实验室哈尔滨工程大学实验室与资产管理处制一画出你所拆装的减速器的传动布置简图三说明减速器各零件与附件的用途四思...

《减速器拆装分析实验》实验指导书-实验报告11

华东理工大学短学期创新实践活动实验报告减速器拆装实践项目学院系别专业班级学号姓名指导教师报告日期20xx年12月9日减速器拆装分析实验报告一实验目的1要求了解减速器铸造箱体的结构以及轴和齿轮的结构2了解轴上零件...

减速器装拆实验报告

减速器装拆实验报告班级组别姓名日期一实验目的1了解减速器的结构熟悉装配和拆卸方法2通过拆装很好地掌握轴系部件的结构3了解减速器各个附件的名称结构安装位置和作用二实验设备画出实验用减速器传动示意简图三实验记录所选...

机械设计减速器零件测绘实验报告

实验三机械设计课程减速器零件测绘实验报告减速器名称齿轮减速器班级09车工日期20xx0626姓名一齿轮的测绘要求用CAD绘制二轴的测绘要求用CAD绘制课后作业结合课堂教学中齿轮的结构设计与轴的结构设计部分相关知...

实验六 减速器的拆装实验报告

机械设计实验报告一拆装减速器的主要参数二绘制减速器传动示意图图中应标出中心距输入轴输出轴齿轮代号及旋向轴承代号等三绘制轴系部件结构图在图中标注尺寸四列出减速器外观附件名称五轴系结构分析选择填空题1分析对象为2齿...

减速器装拆实验报告

减速器装拆实验报告班级学号姓名日期实验成绩一参照实物回答下列问题1将箱盖和箱座联接在一起的螺纹联接是双头螺栓还是普通螺栓为什么2圆锥销的作用是什么3观察减速器内的工作情况和加油用什么结构来实现4箱体和箱盖是用什...

实验报告6:减速器总装配图设计

实验报告二备注本实验报告用于各学科与计算机应用相关课程的实验务必按时完成不交此报告者本次实验为不合格九江学院

减速器实验报告(32篇)