直流电机控制Keil c51源代码
2012-12-06
标签: 电机 C51

直流电机的开环控制Keil c51源代码
//-----------------------函数声明,变量定义--------------------------------------------------------
#include <reg51.h>
#include <intrins.h>
#include <ABSACC.H>
//-----------------------定义管脚--------------------------------------------------------
sbit PWM = P1 ^ 0; //PWM波形输出
sbit DR = P1 ^ 1; //方向控制
#definetimer_data(256-100) //定时器预置值,12M时钟是,定时0.1ms
#definePWM_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();
}
<h5>直流电机闭环控制Keil c51源代码 < / h5 >
//-----------------------函数声明,变量定义--------------------------------------------------------
#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 Ts1000//定义光电编码器采样时间为10ms
#definetimer_data(256-10) //定时器预置值,12M时钟是,定时0.01ms
//-----------------------预设定值--------------------------------------------------------
bit direction;//方向标志位用户设定
unsigned char R;//需要得到的直流电机转速用户设定
//-----------------------实际运行状态--------------------------------------------------------
bit real_direction;//电机实际运行方向
unsigned char Rr;//直流电机实际转速
//-----------------------计算所得补偿状态------------------------------------------
bitcompensate_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();
}


可能会用到的工具/仪表
本站简介 | 意见建议 | 免责声明 | 版权声明 | 联系我们
CopyRight@2024-2039 嵌入式资源网
蜀ICP备2021025729号