基于51单片机的直流电机PID闭环调速系统.doc_第1页
基于51单片机的直流电机PID闭环调速系统.doc_第2页
基于51单片机的直流电机PID闭环调速系统.doc_第3页
基于51单片机的直流电机PID闭环调速系统.doc_第4页
基于51单片机的直流电机PID闭环调速系统.doc_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

基于51单片机的直流电机PID闭环调速系统1.电机转速反馈:原理:利用光电编码器作为转速的反馈元件,设电机转一周光电编码器发送N个PWM波形,利用测周法测量电机转速。具体实现:将定时器0设置在计数模式,用来统计一定的时间T内接受到的脉冲个数M个,而定时器0置在计时模式,用来计时T时间。则如果T时间接受到M个PWM波形,而电机转一圈发出N个PWM波形,则根据测周法原理,电机的实际的转速为:real_speed=M/(N*T),单位转/秒。若将定时器1置在计数模式,则PWM波形应该由P33脚输入。代码实现:/定时器0初始化,用来定时10msvoid Init_Timer0(void)TMOD |= 0x01; /使用模式1,16位定时器 ,且工作在计时模式 TH0=(65536-10000)/256; /定时10msTL0=(65536-10000)%6; EA=1; /总中断打开ET0=1; /定时器中断打开TR0=1; /定时器开关打开/ 计数器1初始化,用来统计定时器1计时250ms内PWM波形个数void Init_Timer1(void)TMOD |= 0x50; /使用计数模式1,16位计数器模式 TH1=0x00; /给定初值,由0往上计数TL1=0x00;EA=1; /总中断打开ET1=1; /定时器中断打开TR1=1; /定时器开关打开 /定时器0的中断服务子函数,主要完成脉冲个数的读取,实际转速的计算和PID控制以及控制结/果输出等工作void Timer0_isr(void) interrupt 1unsigned char count;TH0=(65536-10000)/256; /重新赋值 10msTL0=(65536-10000)%6; count+; if (count=25) /如果达到250ms,则计算一次转速并进行一次控制运算 count=0;/清零以便于定时下一个250ms TR1=0;/关闭定时器1,统计脉冲个数 real_speed=(256*TH1+TL1)*4/N;/250ms内脉冲个数并由此计算转速 TH1=0x00; /计数器1清零,重新开始计数 TL1=0x00; TR1=1; OUT=contr_PID();/进入PID控制 ,PID控制子函数代码在后面给出 write_add(0x40,OUT);/进行DA转换,将数字量转换为模拟量,后面会介绍到 2.PID控制: PID的基本原理在这里不作具体讲解,这里主要给出PID算法的实现,通过调节结构体中比例常数(Proportion)、积分常数(Integral)、微分常数( Derivative)使得转速控制达到想要的精度。试凑法:注意这里参数调节采用实验凑试法,试凑法也有其规律,下面做出讲解: 实验凑试法是通过闭环运行或模拟,观察系统的输出结果,然后根据各参数对系统的影响,反复凑试参数,直至出现满意的响应,从而确定PID控制参数。 实验凑试法的整定步骤为先比例,再积分,最后微分。(1)整定比例控制 将比例控制作用由小变到大,观察各次响应,直至得到反应快、超调小的响应曲线。(2)整定积分环节 若在比例控制下稳态误差不能满足要求,需加入积分控制。 先将步骤(1)中选择的比例系数减小为原来的5080,再将积分时间置一个较大值,观测响应曲线。然后减小积分时间,加大积分作用,并相应调整比例系数,反复试凑至得到较满意的响应,确定比例和积分的参数。(3)整定微分环节 若经过步骤(2),PI控制只能消除稳态误差,而动态过程不能令人满意,则应加入微分控制,构成PID控制。 先置微分时间TD=0,逐渐加大TD,同时相应地改变比例系数和积分时间,反复试凑至获得满意的控制效果和PID控制参数。代码实现unsigned int Proportion=8;/比例常数 Proportional Constunsigned int Integral=3;/积分常数 Integral Constunsigned int Derivative=1;/微分常数 Derivative Constunsigned int LastError=0;/Error-1unsigned int PrevError=0;/Error-2 unsigned int Error=0;/Error0int Out=0;/outcome int contr_PID() Error=expc_speed-real_speed;/计算偏差 /进行增量式PID计算 Out=Out+ Proportion*(Error-LastError)+ Integral*Error+ Derivative*(Error+PrevError-2*LastError); /进行误差更新 PrevError=LastError; LastError=Error; /上下限幅处理 if(Out255) Out=255;/DA转换为8位,最大数值为255,故当大于255时,限制为255 return Out; 3.电机驱动:原理:直流有刷电机既可以用模拟电压驱动,又可以用PWM驱动.如果用PWM驱动时,刚刚PID后的输出可以直接对应到PWM高电平持续的时间,PWM周期为T,则低电平对应为T-Out即可,这个实现比较简单。这里介绍利用DA将数字量Out转化为模拟电压驱动电机的方法。模拟电压驱动实现:将数字量转化为模拟量的最常用方法就是使用DA转换。在一般的使用中我比较喜欢的一款芯片是PCF8591。它内部集成了4路8位AD转换和1路8位DA转换,与单片机之间使用IIC通信方式。由于IIC通信只需要SDA和SCL两根信号线,因此很省IO口,并且一个芯片AD,DA都有了,很方便。具体的PCF8591资料请参考其datasheet,这里直接给出其封装好的IIC通信代码,使用直接就可以了。这里面其他的函数不用管,因为它们最终在两个函数中被调用,即write_add()和read_add()中。前者实现DA转换,有两个参数,第一个参数是控制DA转换对应寄存器地址,取0x40,第二个是要转换的数据,即返回的OUT,使用时直接一句代码:write_add(0x40,OUT)就能将数字信号转换为模拟电压信号。后者实现AD转换,只有一个参数,就是选择AD转换的4个通道,通过宏定义可以定义出其四个通道:#define AD_IN0 0x40#define AD_IN1 0x41#define AD_IN2 0x42#define AD_IN3 0x43使用时只需要一句代码:dat=read_add(AD_IN2)就能实现将第二个通道的模拟信号转换为数字信号。 代码实现:/PCF8591.h #define uchar unsigned char/延时4usvoid delay(void); /iic初始化void init(void); / iic开始信号void start(void) ;/ iic停止信号void stop(void) ;/ iic应答 相当于一个智能的延时函数void respons(void) ;/ iic读一个字节数据uchar read_byte(void) ;/iic写一字节数据void write_byte(uchar date) ;/ 控制DA转换 void write_add(uchar control,uchar date);/ 控制AD转换 uchar read_add(uchar control) ; /PCF8591.c #include#include #define PCF8591 0x90 /默认为写,如果为读,则为0x91 sbit SDA=P20;sbit SCL=P21;/延时4usvoid delay(void) unsigned char i; for(i=1;i0;i-); / iic初始化 void init() SDA=1; delay(); SCL=1; delay(); / iic开始信号void start() SDA=1; delay(); SCL=1; delay(); SDA=0; delay();/ iic停止信号void stop() SDA=0; delay(); SCL=1; delay(); SDA=1; delay(); / iic应答 相当于一个智能的延时函数 void respons() uchar i; SCL=1; delay(); while(SDA=1)&(i250) i+; SCL=0; delay();/ iic读一个字节数据uchar read_byte() uchar i,k; SCL=0; delay(); SDA=1; delay(); for(i=0;i8;i+) SCL=1; delay(); k=(k1)|SDA;/先左移一位,再在最低位接受当前位 SCL=0; delay(); return k; /iic写一字节数据void write_byte(uchar date) uchar i,temp; temp=date; for(i=0;i8;i+) temp=temp1; /左移一位 移出的一位在CY中 SCL=0; /只有在scl=0时sda能变化值 delay(); SDA=CY; delay(); SCL=1; delay(); SCL=0; delay(); SDA=1; delay(); / 控制DA转换 void write_add(uchar control,uchar date) start(); write_byte(PCF8591); respons(); write_byte(control); respons(); write_byte(date); respons(); stop(); / 控制AD转换 uchar read_add(uchar control) uchar date; start(); write_byte(PCF8591); respons(); write_byte(control); respons(); start(); write_byte(PCF8591+1);/把最后一位变成1,读数据 respons(); date=read_byte(); stop(); return date; 主函数:主函数中主要是一些初始化工作,还有按键检测和实际转速和期望转速显示。关于显示部分可以用液晶或者数码管,这里不再具体讲解。 #include#include#include #define uint unsigned int#define uchar unsigned char #define PCF8591 0x90 /默认为写,如果为读,则为0x91#define AD_IN0 0x40#define AD_IN1 0x41#define AD_IN2 0x42#define AD_IN3 0x43 #define KeyPort P1 #define CYCLE 100 /限定的最大转速unsigned int Proportion=8;/比例常数 Proportional Constunsigned int Integral=3;/积分常数 Integral Constunsigned int Derivative=1;/微分常数 Derivative Constunsigned int LastError=0;/Error-1unsigned int PrevError=0;/Error-2 unsigned int Error=0;/Error0int Out=0;/outcome unsigned int expc_speed=0; unsigned int real_speed=0; main() unsigned char num; Init_Timer0(); /初始化定时器0 Init_Timer1(); /初始化计数器1 lcd_init(); init(); while (1) /主循环 num=KeyScan(); /循环调用按键扫描 switch (num) case 1: if(expc_speed0) expc_speed-; lcd_display(4,expc_speed); lcd_display(5,real_speed); /按键扫描函数,返回扫描键值unsigned char KeyScan(void)unsigned char keyvalue;if(KeyPort!=0xff) delay_ms(10); if(KeyPort!=0xff) keyvalue=KeyPort; while(KeyPort!=0xff); switch(keyvalue) case 0xfe:return 1;break; case 0xfd:return 2;break; case 0xfb:return 3;break; case 0xf7:return 4;break; case 0xef:return 5;break; case 0xdf:return 6;break; case 0xbf:return 7;break; case 0x7f:return 8;break; default:return 0;break; return 0;分享: 我个人对MCS-51单片机定时器和计数器区别的理解 2008-02-25 18:43:30| 分类: 默认分类|字号 订阅在51单片机的学习过程中,我们经常会发现中断、计数器/定时器、串口是学习单片机的难点,对于初学者来说,这几部分的内容很难理解。但是我个人觉得这几部分内容是单片机学习的重点,如果在一个学期的课堂学习或者自学中没有理解这几部分内容,那就等于还没有掌握51单片机,那更谈不上单片机的开发了,我们都知道在成品的单片机项目中,有很多是以这几部分为理论基础的,万年历是以定时器为主的,报警器是以中断为主的,联机通讯是以串口为主的。在这几部分内容中,计数器/定时器对于初学者说很容易搞混淆,下面我将对这方面的内容结合自己的学习经验谈几点看法。计数器和定时器的本质是相同的,他们都是对单片机中产生的脉冲进行计数,只不过计数器是单片机外部触发的脉冲,定时器是单片机内部在晶振的触发下产生的脉冲。当他们的脉冲间隔相同的时候,计数器和定时器就是一个概念。在定时器和计数器中都有一个溢出的概念,那什么是溢出了。呵呵,我们可以从一个生活小常识得到答案,当一个碗放在水龙头下接水的时候,过了一会儿,碗的水满了,就发生溢出。同样的道理,假设水龙头的水是一滴滴的往碗里滴,那么总有一滴水是导致碗中的水溢出的。在碗中溢出的水就浪费了,但是在单片机的定时计数器中溢出将导致一次中断,至于什么是中断我们下次再讲,这里只是初步的提下概念,中断就

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论