我的直流电机驱动程序不能世道电机匀速转动

2019-03-24 19:29发布

 如题,   我们实训选了直流电机可调转速的项目,但是我想领导程序完美一点,电机达到那个要求的转速后,只能在要求速度上下徘徊,不能达到那个指定速度后匀速转动。 程序如下:   //文件名:main.c
//文件功能:包含液晶显示子文件
#include<reg52.h>//包含52单片机头文件
#include<lcd1602.h>
sbit S1=P1^5;
sbit S2=P1^6;
sbit S3=P1^7;
sbit PWM=P2^7;
bit flag=0;
unsigned int sec;
unsigned char fun_num=0;
unsigned int  T0_num=0;
unsigned int  num1=0;    //本秒圈数
unsigned int  num2=0;    //上一秒圈数
unsigned int  fre0=20; //设定
unsigned int  fre =0;    //差:fre=num1-num2;
unsigned int  PWM_H=25; //高电平  所谓的“PWM”就是脉冲宽度调制
/*-------------------------------------------------------------------
 //0123456789012345  
  [T:00001 Fre:9999]
  [N:12345 fre:9999]
  ------------------------------------------------------------------*/
void display()
{
     unsigned int i,j;
     j=0;
  i=0;LCD_dis(j,i,'t');
  i++;LCD_dis(j,i,':');
  i++;LCD_dis(j,i,0x30+sec/10000);
  i++;LCD_dis(j,i,0x30+sec%10000/1000);
  i++;LCD_dis(j,i,0x30+sec%1000/100);
  i++;LCD_dis(j,i,0x30+sec%100/10);
  i++;LCD_dis(j,i,0x30+sec%10);
  i++;LCD_dis(j,i,' ');
  i++;LCD_dis(j,i,'F');
  i++;LCD_dis(j,i,'R');
  i++;LCD_dis(j,i,'E');
  i++;LCD_dis(j,i,':');
  i++;LCD_dis(j,i,0x30+fre0%10000/1000);
  i++;LCD_dis(j,i,0x30+fre0%1000/100);
  i++;LCD_dis(j,i,0x30+fre0%100/10);
  i++;LCD_dis(j,i,0x30+fre0%10);
  //--------------------------------------------
     j=1;
  i=0;LCD_dis(j,i,'N');
  i++;LCD_dis(j,i,':');
  i++;LCD_dis(j,i,0x30+num1/10000);
  i++;LCD_dis(j,i,0x30+num1%10000/1000);
  i++;LCD_dis(j,i,0x30+num1%1000/100);
  i++;LCD_dis(j,i,0x30+num1%100/10);
  i++;LCD_dis(j,i,0x30+num1%10);
  i++;LCD_dis(j,i,' ');
  i++;LCD_dis(j,i,'F');
  i++;LCD_dis(j,i,'R');
  i++;LCD_dis(j,i,'E');
  i++;LCD_dis(j,i,':');
  i++;LCD_dis(j,i,0x30+fre%10000/1000);
  i++;LCD_dis(j,i,0x30+fre%1000/100);
  i++;LCD_dis(j,i,0x30+fre%100/10);
  i++;LCD_dis(j,i,0x30+fre%10);
}
//-----------------延时函数------------------------
void delay_20ms()
{
     unsigned int i=200;
  while(i--);
}
//----------------按键扫描函数----------------------
void scan_key()//按键扫描
{
  //-------------------------------------
  if(S1==0)
  {
      delay_20ms();
   if(S1==0)
   {
      //------------------------
         fun_num++;
   if(fun_num>=5) fun_num=0;
   //------------------------
   while(S1==0);
   delay_20ms();
   //------------------------
   }
  }
  //-------------------------------------
  if(S2==0)
  {
      delay_20ms();
   if(S2==0)
   {
      //------------------------
         if(fun_num==1)      {fre0+=1000;}
   else if(fun_num==2) {fre0+=100; } 
   else if(fun_num==3) {fre0+=10;  }
   else if(fun_num==4) {fre0+=1;   }
   //-------------------------------- 
   while(S2==0);
   delay_20ms();
   //------------------------
   }
  }
  //-------------------------------------
  if(S3==0)
  {
      delay_20ms();
   if(S3==0)
   {
         if(fun_num==1)      {fre0-=1000;}
   else if(fun_num==2) {fre0-=100; } 
   else if(fun_num==3) {fre0-=10;  }
   else if(fun_num==4) {fre0-=1;   } 
          
   while(S3==0);
   delay_20ms();
   }
  }
  //-------------------------------------
}
//------------------------------------------
void ex0_server() interrupt 0    //外部中断0
{
  num1++; }
//-----------------------------------------------
void t0_server()  interrupt 1    //定时器0中断
{
     TH0=(65536-5000)/256;
     TL0=(65536-5000)%256;
  T0_num++;
  if(T0_num<PWM_H)    //10ms*25=250ms
  {
   PWM=1;
  }
  else if(T0_num<100)  //10ms*100=1000ms=1s
  {
      PWM=0;
  }  
  if (T0_num>=200)  //200*5ms=1s
  {
   T0_num=0;
   PWM=1;
   flag=1;
   fre=num1-num2;
   num2=num1;
   sec++;
   if(fre>fre0) { if(PWM_H>0)   PWM_H--;}
   if(fre<fre0) { if(PWM_H<100) PWM_H++;}   
   SBUF=0x30+fre%1000/100;while(TI==0);TI=0;  
   SBUF=0x30+fre%100/10;  while(TI==0);TI=0;
   SBUF=0x30+fre%10;    while(TI==0);TI=0;
   SBUF=0x0d;            while(TI==0);TI=0;
   SBUF=0x0a;            while(TI==0);TI=0;  
  }
}
//***************串口中断函数**********************//
void serial_sever() interrupt 4  
{
       if(RI==1) { RI  = 0; }
}
//--------------外部中断0的初始化函数----------------------------
void EX0_Init()
{
    IT0=1; EX0=1; EA=1; PX0=1;
}
//---------------定时中断0的初始化函数----------------------------
void ET0_Init()
{
    TMOD=0X01;
 TH0=(65536-5000)/256;
 TL0=(65536-5000)%256;
 ET0=1;
 EA =1;
 PT0=1;
 TR0=1;
}
//************串口中断的初始化函数*****************//
void s_Init()
{
 SCON  = 0x50;  // 串口工作在方式1, 允许接收
 PCON |= 0x80;  // SMOD=1;波特率倍增
 TMOD |= 0x20;  // 定时器1工作在方式2,重载
 TH1   = 0xf3;  // 波特率4800,fosc=12MHz
 TL1   = 0xf3;  // 波特率4800,fosc=12MHz 
 EA = 1;
 ES = 1;        // 允许串行中断,interrupt enable
 TR1 = 1;       // 启动定时器1,timer1 run
 TI = 0;  //发送中断溢出标志
 RI = 0; //接收中断溢出标志
}
//-------------------主函数----------------------------------
void main()//
{
   Init_LCD();//液晶初始化
      EX0_Init();//调用外部中断0的初始化函数
   ET0_Init();//调用定时中断0的初始化函数
   s_Init();//调用串口中断的初始化函数
 //-----------------------------------------------
 while(1)
 {
     if(flag==1)
  {    
     flag=0;
           display();
  }   scan_key();//按键扫描
 }
}
    希望有高手帮忙改改!!  拜托了。 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
11条回答
David_Lee
1楼-- · 2019-03-25 00:10

原帖由 UC_gundam 于 2011-12-21 15:10 发表  如题,   我们实训选了直流电机可调转速的项目,但是我想领导程序完美一点,电机达到那个要求的转速后,只能在要求速度上下徘徊,不能达到那个指定速度后匀速转动。程序如下:   / ...

 

有点波动是正常的吧,就算加入了闭环控制,使用pid等控制算法,也是会有点波动的,能满足精度需求就可以了吧。

UC_gundam
2楼-- · 2019-03-25 05:07
 精彩回答 2  元偷偷看……
Li_Lei
3楼-- · 2019-03-25 06:42
转速和电流平均和输出力矩有关.没有反馈负载变了你就不能恒速了.
小小白
4楼-- · 2019-03-25 10:48
速度和负载有关吧!他的本质感觉是输出功率恒定吧!加入反馈控制会好一点,不知道你用的是什么电机,电机响应需要时间这个你要注意
jishuaihu
5楼-- · 2019-03-25 11:18
要想匀速肯定得有反馈,而引入反馈之后肯定会有波动,这个就要看你反馈信号的处理及响应的速度了,响应快了波动就显不出来了,
ssawee
6楼-- · 2019-03-25 11:27
PI控制

一周热门 更多>