论坛首页 > 初学者园地 > 学学单片机 > 直流电机控制Keil c51源代码
查看:92  |  回复:0
直流电机控制Keil c51源代码
青锋断尘
15
主题
5
回复
发表于Sat Oct 20 15:31:53 CST 2018   |  只看该作者 1# 电梯直达

直流电机开环控制Keil c51源代码

//-----------------------函数声明,变量定义------------------------
#include <reg51.h>
#include <intrins.h>
#include<ABSACC.H>  
//-----------------------定义管脚----------------------------------
sbit PWM=P1^0;                      //PWM波形输出 
sbit DR=P1^1;                        //方向控制
#define  timer_data  (256-100) //定时器预置值,12M时钟是,定时0.1ms
#define  PWM_T 100                //定义PWM的周期T为10ms
unsigned char PWM_t;             //PWM_t为脉冲宽度(0~100)时间为0~10ms
unsigned char PWM_count;      //输出PWM周期计数
unsigned char time_count;       //定时计数
bit direction;                           //方向标志位
//-----------------------------------------------------------------
// 函数名称:timer_init
// 函数功能:初始化设施定时器
//-----------------------------------------------------------------
void timer_init()
{
      TMOD=0x22; /*定时器1为工作模式2(8位自动重装),0为模式2(8位自动重装) */
      PCON=0x00;
      TF0=0; 
      TH0=timer_data;         //保证定时时长为0.1ms
      TL0=TH0;
      ET0=1;
      TR0=1;                      //开始计数
      EA=1;                        //中断允许
}
//-----------------------------------------------------------------
// 函数名称:setting_PWM
// 函数功能:设置PWM的脉冲宽度和设定方向
//-----------------------------------------------------------------
void setting_PWM()
{
     if(PWM_count==0)        //初始设置
     {
         PWM_t=20;
         direction=1;
     }
}
//-----------------------------------------------------------------
// 函数名称:IntTimer0
// 函数功能:定时器中断处理程序
//-----------------------------------------------------------------
void IntTimer0() interrupt 1
{
     time_count++;
     DR=direction;
     if(time_count>=PWM_T)
     {
         time_count=0;
         PWM_count++;
         setting_PWM();          //每输出一个PWM波调用一次
     }
     if(time_count<PWM_t)
         PWM=1;
     else 
         PWM=0;
}
//-----------------------------------------------------------------
// 函数名称:main
// 用户主函数
// 函数功能:主函数
//-----------------------------------------------------------------
void main()
{
    timer_init();
    setting_PWM();
}

//=·=·=·=·=·=·=·=·=·=·=·=·=·=·=·=·=·=·=·=·=·=·=·=·=·=·=·=

直流电机闭环控制Keil c51源代码

//-----------------------函数声明,变量定义------------------------
#include <reg51.h>
sbit INT_0 =P3^2;                  // 将p3.2外部中断0
sbit pulse_A=P1^2;                // P1.2为脉冲A输入
sbit PWM=P1^0;                    //PWM波形输出 
sbit DR=P1^1;                      //方向控制
//-----------------------预定义值----------------------------------
#define PWM_T 1800               //定义PWM的周期T为18ms
#define Ts    1000                   //定义光电编码器采样时间为10ms
#define  timer_data  (256-10)   //定时器预置值,12M时钟是,定时0.01ms
//-----------------------预设定值----------------------------------
bit direction;                           //方向标志位                   用户设定
unsigned char R;                    //需要得到的直流电机转速   用户设定
//-----------------------实际运行状态------------------------------
bit real_direction;                   //电机实际运行方向   
unsigned char Rr;                  //直流电机实际转速
//-----------------------计算所得补偿状态--------------------------
bit    compensate_polarity;     //补偿极性
unsigned char dR;                 //转速补偿
//-----------------------经补偿后得到的脉宽------------------------
unsigned char PWM_t;            //PWM_t为脉冲宽度(320~400)时间为3.2~4.0ms
unsigned char PWM_count;        //输出PWM周期计数
//-----------------------各中间计数值------------------------------
unsigned char pulseB_count;     //脉冲计数
unsigned char time0_count;      //定时计数
unsigned char time1_count;      //定时计数
//-----------------------------------------------------------------
// 函数名称:timer_init
// 函数功能:初始化设置定时器
//-----------------------------------------------------------------
void timer_init()
{
      TMOD=0x22; /*定时器1为工作模式2(8位自动重装),0为模式2(8位自动重装) */
      PCON=0x00;
      TF0=0; 
      TH0=timer_data;           //保证定时时长为0.01ms
      TL0=TH0;
      TH1=timer_data;           //保证定时时长为0.01ms
      TL1=TH0;
      ET0=1;                        //定时器0中断允许
      TR0=1;                        //定时器0开始计数
      ET1=1;                        //定时器1中断允许
      TR1=1;                        //定时器1开始计数
      EA=1;                          //中断允许
}
//-----------------------------------------------------------------
// 函数名称: INT0_init()
// 函数功能: 初始化设置
//            设定INT0的工作方式
//-----------------------------------------------------------------
void INT0_init(void )  
{
      pulseB_count=0;          //脉冲计数器清零
      IT0=1;                        //选择INT0为沿触发方式
      EX0=1;                       //外部中断允许
      EA=1;                         //系统中断允许
}
//-----------------------------------------------------------------
// 函数名称:setting_PWM
// 函数功能:设置PWM的脉冲宽度和设定方向
//-----------------------------------------------------------------
void setting_PWM()
{
 // direction=1;                   //设定转动方向
 // R=540;                         //设定转速
 // dR=0;                           //转速补偿为零
 // calculate_PWM_t();         //重新计算脉宽
}
//-----------------------------------------------------------------
// 函数名称: calculate_PWM_t
// 入口参数: R需要得到的直流电机转速,dR转速补偿
// 出口参数: PWM_t为脉冲宽度(320~400)时间为3.2~4.0ms
// 函数功能: 计算脉冲宽度,PWM_t=R/150;
//-----------------------------------------------------------------
void calculate_PWM_t()
{
      if(compensate_polarity==1)    //正补偿
          PWM_t=(R+dR)/150;
      else
          PWM_t=(R-dR)/150;          //负修正
}
//-----------------------------------------------------------------
// 函数名称: calculate_Rr
// 入口参数: pulseB_count脉冲计数
// 出口参数: Rr直流电机实际转速
// 函数功能: 计算实际转速
//-----------------------------------------------------------------
void calculate_Rr()
{
      Rr=pulseB_count/6;
}
//-----------------------------------------------------------------
// 函数名称: compensate_dR
// 入口参数: Rr直流电机实际转速
//            R需要得到的直流电机转速
// 出口参数: dR转速补偿
// 函数功能: 计算实际补偿值和补偿极性 ,根据不同的补偿算法重新设计
//-----------------------------------------------------------------
void compensate_Rr()
{
      Rr=1;
      if(Rr>R)
          compensate_polarity=0;     //补偿极性
      else 
          compensate_polarity=1;
}
//-----------------------------------------------------------------
// 函数名称: INT0_intrupt
// 函数功能: 外部中断0处理程序
//-----------------------------------------------------------------
void INT0_intrupt() interrupt 0 using 1
{
     pulseB_count++;
     if(pulse_A==0)
     {   
          real_direction=1;  //若P1.2为低电平,则电机为正转,计数器N的值加1
     }
     else                         //若为高电平,则电机为反转,计数器N值减l。
     {
          real_direction=1;
     }
}
//-----------------------------------------------------------------
// 函数名称:IntTimer0
// 函数功能:定时器中断处理程序
//-----------------------------------------------------------------
void IntTimer0() interrupt 1
{
     time0_count++;
     DR=direction;
     if(time0_count>=PWM_T)
     {
         time0_count=0;
         PWM_count++;
         setting_PWM();         //每输出一个PWM波调用一次
     }
     if(time0_count<PWM_t)
         PWM=1;
     else 
         PWM=0;
}
//-----------------------------------------------------------------
// 函数名称:IntTimer1
// 函数功能:定时器中断处理程序
//-----------------------------------------------------------------
void IntTimer1() interrupt 3
{
     time1_count++;
     if(time1_count==1)
     {
         INT0_init();                //初始化外部中断设置
     }
     if(time1_count>=Ts)
     {
         time1_count=0;         //一个补偿周期结束,计数器清零
         calculate_Rr();            //计算实际转速
         compensate_Rr();       //计算实际补偿值和补偿极性
         calculate_PWM_t();      //重新计算脉宽
     }
}
//-----------------------------------------------------------------
// 函数名称:main
// 用户主函数
// 函数功能:主函数
//-----------------------------------------------------------------
void main()
{
     direction=1;                 //设定转动方向
     R=540;                       //设定转速
     dR=0;                        //转速补偿为零
     calculate_PWM_t();      //重新计算脉宽
     timer_init();
}

回复 收藏
  举报
  • 温馨提示:标题不合格、重复发帖、发布广告贴,将会被删除帖子或禁止发言。 详情请参考:社区发帖规则
  • 您当前输入了 0个文字。还可以输入8000个文字。 已添加复制上传图片功能,该功能目前仅支持chrome和火狐

顶部