直流电机的开环控制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(); }
|