PID转速闭环调速控制系统仿真

来源:本站
导读:目前正在解读《PID转速闭环调速控制系统仿真》的相关信息,《PID转速闭环调速控制系统仿真》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《PID转速闭环调速控制系统仿真》的详细说明。
简介:PID转速闭环调速控制系统仿真

基于uC/COS的直流电机PID转速闭环调速控制系统Proteus仿真实现

在工业自动控制系统和各种智能产品中常常会用用电动机进行驱动、传动和控制,而现代智能控制系统中,对电机的控制要求越来越精确和迅速,对环境的适应要求越来越高。随着科技的发展,通过对电机的改造,出现了一些针对各种应用要求的电机,如伺服电机、步进电机、开关磁阻电机等非传统电机。但是在一些对位置控制要求不高的电机控制系统如传动控制系统中,传统电机如直流电机乃有很大的优势,而要对其进行精确而又迅速的控制,就需要复杂的控制系统。随着微电子和计算机的发展,数字控制系统应用越来越广泛,数字控制系统有控制精确,硬件实现简单,受环境影响小,功能复杂,系统修改简单,有很好的人机交换界面等特点。

在电机控制系统开发中,常常需要消耗各种硬件资源,系统构建时间长,而在调试时很难对硬件系统进行修改,从而延长开发周期。随着计算机仿真技术的出现和发展,可用计算机对电机控制系统进行仿真,从而减小系统开发开支和周期。计算机仿真可分为整体仿真

和实时仿真。整体仿真是对系统各个时间段对各个对象进行计算和分析,从而对各个对象的变化情况有直观的整体的了解,即能对系统进行精确的预测,如Matlab就是一个典型的实时仿真软件。实时仿真是对时间点的动态仿真,即随着时间的推移它能动态仿真出当时系统的状态。Proteus是一个实时仿真软件,用来仿真各种嵌入式系统。它能对各种微控制器进行仿真,本系统即用Proteus对直流电机控制系统进行仿真。

在系统软件开发中开发中可用操作系统,也可不用操作系统。如用操作系统,程序可实现模块化,并能对系统资源进行统筹管理,最主要的是可实现多任务运行。如果需要多任务并行运行,并且需要一定的时间间隔,某些任务对时间的要求不高时,如不用操作系统则要占用定时器资源,并且对栈空间和硬件资源很难进行管理,所以在这种情况下需要操作系统。本系统用操作系统uC/COS.

uC/COS是一个完整的、可移植、可固化、可剪裁的占先式实时多任务内核.uC/COS

已经有很多产品成功使用的案例且得到美国军方的认证,说明了该系统的可靠性。uC/COS

源代码公开,代码短,源代码大部分是使用ANSI C编写的,移植性和裁减性好,功能强大,

能可靠应用于各种控制系统中。

系统构成

SHAPEPID转速闭环调速控制系统仿真

硬件全图

PID转速闭环调速控制系统仿真

各子系统

1. 转速控制输入

如用按键输入则需要复杂的软件实现,并且需要足够的引脚资源,本系统用ADC0832采样电位器上的电压信号来实现转速信号输入。

PID转速闭环调速控制系统仿真

2.LPC2106微控制器

LPC2106是Phlip公司推出的核心为ARM的控制器。LPC2106 包含一个支持仿真的ARM7TDMI-S CPU、与片内存储器控制器接口的ARM7 局部总线、与中断控制器接口的AMBA 高性能总线(AHB)和连接片内外设功能的VLSI 外设总线(VPB,ARMAMBA 总线的兼容超集)。片内有64K 字节静态RAM和128K的FLASH存储器。可寻址4GB。

在本仿真中LPC2106没加晶振电路,频率在芯片属性中设置。

PID转速闭环调速控制系统仿真

3.液晶显示

本系统采用Proteus仿真库有的液晶显示模块AMPIRE128X64,为8192像素的单色LCD

屏幕分为两半控制,控制引脚为CS1和CS2。数据通过移位寄存器输入。

PID转速闭环调速控制系统仿真

4.电机驱动电路

本系统仿真的是最大输入电压为12伏的微型电机,故用通用电机驱动电路实现假设该电路输入电阻为无穷大,输出电阻为0。

PID转速闭环调速控制系统仿真

5.仿真电机的51单片机

虽然Proteus有电机模块,但其电机模块没有输出转速接口故用一单片机代替它,单片机用ADC0832采样输入的电压,经过处理即输出和真实电机同步的转速(需要大量的浮点运算,可考虑用DSP)。通过两个按键改变转矩没按一次增大或减小0.001,上面的是增大。

PID转速闭环调速控制系统仿真

6.仿真结果

仿真1.8秒钟后得下图,可看到转速逐渐增大然后稳定下来。

PID转速闭环调速控制系统仿真

增大转矩后,可看到转速下降后又恢复

PID转速闭环调速控制系统仿真

7.程序;

1.系统主程序:main.c

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

** 实时微型直流电机PID转速闭环调速控制系统程序(基于移植于LPC2106上的uc/cos实时操作系统)

** 程序编写者: 吴斌

** 编写日期: 2007年11月14日

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

#include "config.h"

#include "LCD.h"

#define TASK_STK_SIZE 512 //各任务栈大小

#define IO_Init()

PINSEL0= 2;

IODIR|= 0x00007FB0; //P0.4P0.5P0.7-P1.4为输出其他的为输入

#define Umax 1000 //最大调节转速

#define Kp 0.7 //比例放大系数

#define Ts 0.03 //采样周期

#define t0 4 //积分时间常数

#define td 0.0005 //微分时间常数

#define q0 Kp*(1+Ts*t0+td/Ts)

#define q1 -Kp*(1+2*td/Ts)

#define q2 Kp*td/Ts

#define ADC_DO 0x00000040 //P0.6

#define ADC_CS 0x00000080 //P0.7

#define ADC_CLK 0x00000100 //P0.8

#define ADC_DI 0x00000200 //P0.9

OS_STK Main_TaskStk[TASK_STK_SIZE];

OS_STK Task1_TaskStk[TASK_STK_SIZE];

OS_STK Task2_TaskStk[TASK_STK_SIZE];

OS_STK Task3_TaskStk[TASK_STK_SIZE];

OS_STK Task4_TaskStk[TASK_STK_SIZE]; //各任务栈

OS_EVENT *Conbox; //控制信号邮箱

float n=0; // 输入转速

float nb=0; // 反馈转速

void Main_Task(void *data);

void Task1(void *p_arg);

void Task2(void *p_arg);

void Task3(void *p_arg);

void Task4(void *p_arg); //函数声明

void PWMInit(void)

{

PWMPR = 0x00; // 不分频,计数频率为Fpclk

PWMMCR = 0x02; // 设置PWMMR0匹配时复位PWMTC

PWMMR0 = 2765; // 设置PWM周期

PWMMR1 = 0; // 设置PWM占空比

PWMLER = 0x03; // PWMMR0、PWMMR1锁存

PWMPCR = 0x0200; // 允许PWM1输出,单边PWM

PWMTCR = 0x09; // 启动定时器,PWM使能

PWMMR0 = 2765; // 设置PWM周期

PWMMR1 = 0; // 设置PWM占空比

PWMLER = 0x03; // PWMMR0、PWMMR1锁存

}

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

** 函数名称: main

** 功能描述: c语言的主函数,由它启动多任务环境

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

int main (void)

{

OSInit();

OSTaskCreate(Main_Task, (void*)0, &Main_TaskStk[TASK_STK_SIZE - 1], 0);

OSStart();

return 0;

}

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

** 函数名称: Main_Task

** 功能描述: 初始化系统及建立任务

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

void Main_Task(void *p_arg)

{

p_arg = p_arg; // 避免编译警告

TargetInit();

IO_Init();

Conbox = OSMboxCreate((void*)0);

LCD_Main();

OSTaskCreate(Task1, (void *)0, &Task1_TaskStk[TASK_STK_SIZE - 1], 2);

OSTaskCreate(Task2, (void *)0, &Task2_TaskStk[TASK_STK_SIZE - 1], 3);

OSTaskCreate(Task3, (void *)0, &Task3_TaskStk[TASK_STK_SIZE - 1], 1);

OSTaskCreate(Task4, (void *)0, &Task4_TaskStk[TASK_STK_SIZE - 1], 5);

OSTaskSuspend(0);

}

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

** 函数名称: Task1_Task

** 功能描述: 实时任务,负责采样和处理数据

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

void Task1(void *p_arg)

{ float us; //上次输出控制信号

float es; //上次采样误差信号

float es2 = 0; //上次的上次的采样误差信号

uint32 nj; //采样转速信号

float u; //此次输出控制信号

float e; //此次采样误差信号

p_arg = p_arg;

PWMInit(); //PWM初始化

while(1)

{ nj=IOPIN>>16;

nb=(float)nj/10; //采样反馈转速

e=n-nb;

u=us+q0*e+q1*es+q2*es2; //PID处理

if(u>=Umax)

u=Umax;

es2=es;

es=e;

us=u;

OSMboxPost(Conbox,(void*)&u); //发送处理后的信号

OSTimeDlyHMSM(0,0,0,30);

}

}

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

** 函数名称: Task2_Task

** 功能描述: 根据控制信号输出PWM波

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

void Task2(void *p_arg)

{ uint8 err;

float *nh;

p_arg = p_arg;

while(1)

{nh=(float*)OSMboxPend(Conbox,0,&err);

if(*nh>=Umax-0.5)

{PWMMR0 = 2765;

PWMMR1= 2764;

PWMLER = 0x03;

}

else

{PWMMR0 = 2765;

PWMMR1=(uint32)(*nh/Umax*2765);

PWMLER = 0x03;

}

}

}

void Delay(uint8 n) //延时函数

{uint8 i;

for(i=1;i<=n;i++);

}

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

** 函数名称: Task3_Task

** 功能描述: 定时采样输入的转速要求(0832采样)

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

void Task3(void *p_arg)

{ uint8 ch,i,flag=0;

p_arg=p_arg;

ch=0;

IOCLR=ADC_CS;

IOCLR=ADC_DI;//片选,DO为高阻态

for(i=0;i<10;i++)

{;}

IOCLR=ADC_CLK;

Delay(4);

IOSET=ADC_DI;

IOSET=ADC_CLK;

Delay(4); //第一个脉冲,起始位

IOCLR=ADC_CLK;

Delay(4);

IOSET=ADC_DI;

IOSET=ADC_CLK;

Delay(4); //第二个脉冲,DI=1表示双通道单极性输入

IOCLR=ADC_CLK;

Delay(4);

IOSET=ADC_DI;

IOSET=ADC_CLK;

Delay(4); //第三个脉冲,DI=1表示选择通道1(CH2)

IOCLR=ADC_DI; //DI转为高阻态,DO脱离高阻态为输出数据作准备

IOSET=ADC_CLK;

Delay(4);

IOCLR=ADC_CLK;

Delay(4); //经实验,这里加一个脉冲AD便能正确读出数据

for (i=0; i<8; i++)

{ IOSET=ADC_CLK;

Delay(4);

IOCLR=ADC_CLK;

Delay(4);

if((IOPIN & ADC_DO)!=0)

ch=(ch<<1)|1;//在每个脉冲的下降沿DO输出一位数据,最终ch为8位二进制数

else

ch=(ch<<1)|0;

}

IOSET=ADC_CS;

n=(float)ch*1000/256;

if(flag==0)

{flag=1;

OSTaskChangePrio(1,4);

}

OSTimeDlyHMSM(0,0,0,300);

}

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

** 函数名称: Task4_Task

** 功能描述: 液晶显示任务

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

void Task4(void *p_arg)

{

#if OSCRITICAL_METHOD ==3

OS_CPU_SR cpu_sr;

#endif

uint16 w,q,k;

uint8 i;

uint8 shu1[6],shu2[6];

p_arg=p_arg;

for(;;)

{shu1[4]=10;

w=(uint16)(n*10);

k=10000;

for(i=0;i<4;i++)

{shu1[i]=(uint8)(w/k);

w=w%k;

k=k/10;

}

shu1[5]=(uint8)w;

OS_ENTER_CRITICAL();

LCD_num(80,2,shu1,6);

shu2[4]=10;

q=(uint16)(nb*10);

k=10000;

for(i=0;i<4;i++)

{shu2[i]=(uint8)(q/k);

q=q%k;

k=k/10;

}

shu2[5]=(uint8)q;

LCD_num(80,4,shu2,6);

OS_EXIT_CRITICAL();

OSTimeDlyHMSM(0,0,0,100);

}

}

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

** End Of File

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

2.自编的LCD驱动程序

(1)头文件LCD.h

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

** LCD驱动头文件LCD.h(基于LPC21**)

** 程序编写者: 吴斌

** 编写日期: 2007年11月12日

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

#ifndef _LCD_H_

#define _LCD_H_

#include "config.h"

#define SPI_CLK 0x00000010 //P0.4

#define SPI_DATA 0x00000020 //P0.5

#define RW 0x00000800 //RW

#define RS 0x00000400 //RS

#define CS1 0x00001000 //CS1

#define CS2 0x00002000 //CS2

#define E 0x00004000 //E

#define Kai 0x3F

#define Guang 0x3E

#define Hang 0xC0

#define Ye 0xB8

#define Lie 0x40

#define Setlie(a)

IOCLR = RW;

IOCLR = RS;

send(Lie+a);

#define Setye(a)

IOCLR = RW;

IOCLR = RS;

send(Ye+a);

#define Setweizi(a,b)

IOCLR = RW;

IOCLR = RS;

send(Lie+a);

send(Ye+b);

#define Write(a)

IOCLR = RW;

IOSET = RS;

send(a);

void send(uint8 dat);

void LCD_disp(uint8 a,uint8 b,uint8 c,uint8 d,uint8 m,uint8 *shuju) ;

void SetCS(uint8 a);

void LCD(uint8 a,uint8 b,uint8 c,uint8 d, uint8 *shuju);

void LCD_num(uint8 a,uint8 b,uint8 *shuju,uint8 n);

void LCD_str(uint8 a,uint8 b,uint8 *strtab,uint8 n);

void LCD_hanzi(uint8 a,uint8 b,uint8 *hanzitab,uint8 n);

void LCD_xian(uint8 a,uint8 b,uint8 *strtab,uint8 n);

void LCD_Main(void);

#endif

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

** End Of File

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

(2)LCD驱动程序LCD.c

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

** LCD驱动程序(基于LPC21**)

** 程序编写者: 吴斌

** 编写日期: 2007年11月12日

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

#include"LCD.h"

void send(uint8 dat) //用移位寄存器输出一字节数据

{ uint8 i;

IOSET = E; // E = 1

for(i=0; i<8; i++) // 发送8位数据

{ IOCLR = SPI_CLK; // SPI_CLK = 0

if( (dat&0x80)!=0 ) IOSET = SPI_DATA;

else IOCLR = SPI_DATA;

dat <<= 1;

IOSET = SPI_CLK; // SPI_CLK = 1

}

IOCLR = E; // E = 0

}

void LCD_disp(uint8 a,uint8 b,uint8 c,uint8 d,uint8 m,uint8 *shuju) /*LCD显示函数,在第a列b页输出大小为c*d的图像(只能选择在左或右屏幕显示) */

{uint8 i,j,f;

SetCS(m);

for(j=0;j<d;j++)

{Setweizi(a,j+b);

for(i=0;i<c;i++)

{Write(*(shuju+i));

for(f=0;f<0xFF;f++);

}

}

}

void SetCS(uint8 a)

{if(a==0)

{IOSET =CS2;

IOCLR =CS1;

}

else

{IOSET =CS1;

IOCLR =CS2;

}

}

void LCD(uint8 a,uint8 b,uint8 c,uint8 d, uint8 *shuju) /*LCD主显示函数,在第a列b页输出大小为c*d的图像*/

{uint8 i,j,m,f,n;

uint8 *p=shuju;

if(a+c<=64)

{SetCS(0);

for(j=0;j<d;j++)

{Setweizi(a,j+b);

for(i=0;i<c;i++)

{Write(*p);

p++;

for(f=0;f<0xFF;f++);

}

}

}

else if(a<64&&(a+c)>64)

{m=64-a;

n=c-m;

for(j=0;j<d;j++)

{SetCS(0);

Setweizi(a,j+b);

for(i=0;i<m;i++)

{Write(*p);

p++;

for(f=0;f<0xFF;f++);

}

SetCS(1);

Setweizi(0,j+b);

for(i=0;i<n;i++)

{Write(*p);

p++;

for(f=0;f<0xFF;f++);

}

}

}

else

{SetCS(1);

for(j=0;j<d;j++)

{Setweizi(a-64,j+b);

for(i=0;i<c;i++)

{Write(*p);

p++;

for(f=0;f<0xFF;f++);

}

}

}

}

void LCD_num(uint8 a,uint8 b,uint8 *shuju,uint8 n) /*在第a列b页显示shuju数组的数字或小数点和空格*/

{uint8 numzimo[192]={0xFF,0x1F,0xEF,0xF7,0xF7,0xEF,0x1F,0xFF,0xFF,0xF0,0xEF,0xDF,0xDF,

0xEF,0xF0,0xFF, /*"0",0*/

0xFF,0xEF,0xEF,0x07,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF,0xDF,0xC0,0xDF,0xDF,0xFF,0xFF,

/*"1",1*/

0xFF,0x8F,0xF7,0xF7,0xF7,0x77,0x8F,0xFF,0xFF,0xCF,0xD7,0xDB,0xDD,0xDE,0xCF,0xFF,

/*"2",2*/

0xFF,0xCF,0xF7,0x77,0x77,0xB7,0xCF,0xFF,0xFF,0xE7,0xDF,0xDF,0xDF,0xEE,0xF1,0xFF,

/*"3",3*/

0xFF,0xFF,0x3F,0xDF,0xEF,0x07,0xFF,0xFF,0xFF,0xF8,0xFB,0xDB,0xDB,0xC0,0xDB,0xFF,

/*"4",4*/

0xFF,0x07,0xF7,0x77,0x77,0xF7,0xF7,0xFF,0xFF,0xE6,0xDE,0xDF,0xDF,0xEE,0xF1,0xFF,

/*"5",5*/

0xFF,0x1F,0xEF,0x77,0x77,0xE7,0xFF,0xFF,0xFF,0xF0,0xEE,0xDF,0xDF,0xEE,0xF1,0xFF,

/*"6",6*/

0xFF,0xC7,0xF7,0xF7,0x37,0xC7,0xF7,0xFF,0xFF,0xFF,0xFF,0xC0,0xFF,0xFF,0xFF,0xFF,

/*"7",7*/

0xFF,0x8F,0x77,0xF7,0xF7,0x77,0x8F,0xFF,0xFF,0xE3,0xDD,0xDE,0xDE,0xDD,0xE3,0xFF,

/*"8",8*/

0xFF,0x1F,0xEF,0xF7,0xF7,0xEF,0x1F,0xFF,0xFF,0xFF,0xCE,0xDD,0xDD,0xEE,0xF0,0xFF,

/*"9",9*/

0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCF,0xCF,0xFF,0xFF,0xFF,0xFF,0xFF,

/*".",10*/

0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};

/*" ",11*/

uint8 i,f;

uint8 *p;

for(i=0;i<n;i++)

{f=*(shuju++);

p=numzimo+f*16;

LCD(a,b,8,2,p);

a=a+8;

}

}

void LCD_str(uint8 a,uint8 b,uint8 *strtab,uint8 n) /*在第a列b页显示ASCII字符串(要点阵数据)*/

{uint8 i;

for(i=0;i<n;i++)

{LCD(a,b,8,2,strtab);

a=a+8;

strtab=strtab+16;

}

}

void LCD_hanzi(uint8 a,uint8 b,uint8 *hanzitab,uint8 n) /*在第a列b页显示汉字串(要点阵数据)*/

{uint8 i;

for(i=0;i<n;i++)

{LCD(a,b,16,2,hanzitab);

a=a+16;

hanzitab=hanzitab+32;

}

}

void LCD_xian(uint8 a,uint8 b,uint8 *strtab,uint8 n) //显示ASCII字符串到顶时换行

{uint8 m;

if(a+(n-1)*8<=120)

LCD_str(a,b,strtab,n);

else

{if(a%8>0)

m=a/8+1+n-16;

else

m=a/8+n-16;

LCD_str(a,b,strtab,n-m);

LCD_str(0,b+2,strtab+16*(n-m),m);

}

}

void LCD_Main(void) //本系统显示主界面

{uint8 i;

uint8 zifu[80]={0xF7,0x07,0xF7,0xFF,0xFF,0xF7,0x07,0xF7,0xFF,0xE0,0xDF,0xDF,0xDF,0xDF,

0xE0,0xFF,/*"U",0*/

0xFF,0xFF,0xFF,0xFF,0x7F,0x9F,0xE7,0xFB,0xFF,0x9F,0xE7,0xF9,0xFE,0xFF,0xFF,0xFF,

/*"/",1*/

0xFF,0xFF,0xFF,0x7F,0x7F,0x7F,0xFF,0xFF,0xFF,0xF1,0xEE,0xDF,0xDF,0xDF,0xEE,0xFF,

/*"c",2*/

0xFF,0xFF,0x7F,0x7F,0x7F,0x7F,0xFF,0xFF,0xFF,0xE0,0xDF,0xDF,0xDF,0xDF,0xE0,0xFF,

/*"o",3*/

0xFF,0xFF,0x7F,0x7F,0x7F,0x7F,0x7F,0xFF,0xFF,0xCC,0xDB,0xDB,0xDB,0xDB,0xE6,0xFF};/*"s",4*/

uint8 inputn[160]=

{0xBB,0x0B,0xB0,0x1B,0xBB,0x9B,0x6F,0x67,0x6B,0x6C,0xEB,0x67,0xF7,0x2F,0xEF,0xFF,

0xFB,0xFB,0xFB,0x00,0xFD,0xFD,0x00,0xB5,0x75,0x80,0xFF,0xC0,0x7F,0x00,0xFF,0xFF,

/*"输",0*/

0xFF,0xFF,0xFF,0xFF,0xFE,0x7C,0x89,0xE7,0x9F,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,

0xBF,0xDF,0xEF,0xF7,0xF9,0xFE,0xFF,0xFF,0xFF,0xFF,0xFC,0xFB,0xE7,0xCF,0xEF,0xFF,

/*"入",1*/

0x37,0x57,0x63,0x14,0x77,0x77,0x77,0xBF,0xB7,0x07,0xB0,0xB7,0xB7,0xB7,0xBF,0xFF,

0xF7,0xF7,0xFB,0x00,0xFB,0xFB,0xFF,0xFD,0xF4,0xED,0xDD,0x2D,0xF1,0xFD,0xFF,0xFF,/*"转",2*/

0xBF,0xBD,0x33,0xFF,0xFB,0x1B,0xDB,0xDB,0x0,0xDB,0xDB,0xDB,0x1B,0xFB,0xFF,0xFF,

0xBF,0xDF,0xE0,0xDF,0xB7,0xB6,0xBA,0xBC,0x80,0xBE,0xBC,0xBA,0xB2,0xBF,0xBF,

0xFF,/*"速",3*/

0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,

0xFF,0xFF,0xC9,0xC9,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};

/*":",4*/

uint8 outputn[160]={0xBB,0x0B,0xB0,0x1B,0xBB,0x9B,0x6F,0x67,0x6B,0x6C,0xEB,0x67,0xF7,

0x2F,0xEF,0xFF,

0xFB,0xFB,0xFB,0x00,0xFD,0xFD,0x00,0xB5,0x75,0x80,0xFF,0xC0,0x7F,0x00,0xFF,0xFF,

/*"输",0*/

0xFF,0xFF,0x03,0xBF,0xBF,0xBF,0xBF,0x00,0xBF,0xBF,0xBF,0xBF,0xBF,0x03,0xFF,0xFF,

0xFF,0xFF,0x81,0xDF,0xDF,0xDF,0xDF,0xC0,0xDF,0xDF,0xDF,0xDF,0xDF,0x81,0xFF,0xFF,

/*"出",1*/

0x37,0x57,0x63,0x14,0x77,0x77,0x77,0xBF,0xB7,0x07,0xB0,0xB7,0xB7,0xB7,0xBF,0xFF,

0xF7,0xF7,0xFB,0x00,0xFB,0xFB,0xFF,0xFD,0xF4,0xED,0xDD,0x2D,0xF1,0xFD,0xFF,0xFF,/*"转",2*/

0xBF,0xBD,0x33,0xFF,0xFB,0x1B,0xDB,0xDB,0x0,0xDB,0xDB,0xDB,0x1B,0xFB,0xFF,0xFF,

0xBF,0xDF,0xE0,0xDF,0xB7,0xB6,0xBA,0xBC,0x80,0xBE,0xBC,0xBA,0xB2,0xBF,0xBF,

0xFF,/*"速",3*/

0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,

0xFF,0xFF,0xC9,0xC9,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};

/*":",4*/

uint8 xinhao[16]={0xBF,0xBF,0x7F,0x0F,0x7F,0xBF,0xBF,0xFF,0xFD,0xFD,0xFE,0xF0,0xFE,

0xFD,0xFD,0xFF};/*"*",0*/

LCD_str(44,0,zifu,5);

LCD_hanzi(0,2,inputn,5);

LCD_hanzi(0,4,outputn,5);

for(i=0;i<16;i++)

{ LCD_str(i*8,6,xinhao,1);

}

}

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

** End Of File

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

3. 用AT89S52单片机仿真直流电动机程序

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

** 用AT89S52单片机仿真直流电动机程序

** 程序编写者: 吴斌

** 编写日期: 2007年11月11日

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

#include

#include

#include

#define La 0.1 //电枢电感

#define CeQ 0.005

#define CmQ 0.2 //

#define Ja 0.0000018 //转动惯量

#define Ra 10

#define Ra-La 11.9

sbit ADC_CS =P3^4;

sbit ADC_CLK=P3^5;

sbit ADC_DI =P3^6;

unsigned int nc;

float TL=0.1;

float Te;

float Tz=0;

float Ts=0;

float U=0.68;

float Uz=0;

float ia=0;

float iaz=0;

float ias=0;

float ea=0;

float eaz=0;

float eas=0;

float n=0;

bit f=0;

bit e=0;

void Delay(unsigned char x)

{

unsigned char i;

for(i=0;i<x;i++);

}

void INTf0(void)interrupt 0

{TL=TL+0.001;

}

void INTf1(void)interrupt 2

{TL=TL-0.001;

}

void timer0(void)interrupt 1

{unsigned int i,ch;

ch=0;

ADC_CS=0;

ADC_DI=0;

for(i=0;i<10;i++)

{;}

ADC_CLK=0;

Delay(2);

ADC_DI=1;

ADC_CLK=1;

Delay(2);

ADC_CLK=0;

Delay(2);

ADC_DI=0;

ADC_CLK=1;

Delay(2);

ADC_CLK=0;

Delay(2);

ADC_DI=0;

ADC_CLK=1;

Delay(2);

ADC_DI=0;

ADC_DI=1;

ADC_CLK=1;

Delay(2);

ADC_CLK=0;

Delay(2);

for (i=0; i<8; i++)

{ ADC_CLK=1;

Delay(2);

ADC_CLK=0;

Delay(2);

ch=(ch<<1)|ADC_DI;

}

ADC_CS=1;

U=0.1*(float)ch/256;

Uz=Uz+U;

ia=(Uz-iaz*Ra-eaz)/(Ra*0.01+La);

Te=CmQ *ia;

if(f==0);

{f=1;

ias=ia;

Ts=Te-TL;

}

if(n<=0&&Te<TL&&e==0)

n=0;

else

{e=1;

Tz=Tz+(1.5*(Te-TL)-0.5*Ts)*0.01;

Ts=Te-TL;

n=Tz/Ja;

}

ea=CeQ *n;

eaz=eaz+(1.5*ea-0.5*eas)*0.01-U*0.9727;

eas=ea;

Uz=Uz-U;

iaz=iaz+(1.5*ia-0.5*ias)*0.01-U*0.0273/Ra;

ias=ia;

nc= (unsigned int)(n*10);

P2=nc/256;

P0=nc%256;

printf("n=%f,i=%fn",n,ia);

TH0 =-(9216/256);

TL0 =-(9216%256);

}

main()

{int i;

TCON = 0x0F;

SCON = 0xDA;

TMOD |= 0x20;

TH1 = 0xFD;

TR1 = 1;

TI = 1;

TH0 = -(9216/256);

TL0 = -(9216%256);

EX0=1;

EX1=1;

PX1=1;

EA =1;

ET0 =1;

TR0= 1;

while(1)

{;}

}

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

** End Of File

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

提醒:《PID转速闭环调速控制系统仿真》最后刷新时间 2024-03-14 01:19:05,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《PID转速闭环调速控制系统仿真》该内容的真实性请自行鉴别。