标题: 51单片机+ULN2003为什么电机转动不明显 [打印本页]

作者: 上好佳kkk    时间: 2025-9-13 14:55
标题: 51单片机+ULN2003为什么电机转动不明显
这是我的程序,电机会转动,但是最快转一圈用了10s,怎么让它更快呢?定时器的时间也该过了,但是还是不快#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int

sbit jiasu = P3^2;    //加速
sbit jiansu = P3^3;   //减速
sbit begin = P3^0;    //开始
sbit fangxiang = P3^7; //方向键
sbit MOTOR_A=P1^0;
sbit MOTOR_B=P1^1;
sbit MOTOR_C=P1^2;
sbit MOTOR_D=P1^3;

                  
uchar code PHASE_CW[]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09};   //四相八拍电平表
uchar code PHASE_CCW[]={0x01,0x09,0x08,0x0c,0x04,0x06,0x02,0x03};
uchar code tab1[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff };

bit fx_flag = 0;      // 方向标志位
uchar phase = 0;      // 当前相位
uint cycle_cnt = 0;   // 计数器
uint timelong =10; // 固定每个相位
uchar sudu = 0;       // 默认速度档位
uchar sudu_num;       // 数码管显示
void motor_speed();         
volatile uchar phaseIndex = 0;  // 相序索引(全局变量,需加volatile)
volatile bit   direction  = 0;  // 转向(全局变量)


         
void Timer0_Init(void)
{
    TMOD &= 0xF0;   // 清除T0模式
    TMOD |= 0x01;   // 设置T0为模式1(16位自动重装)
    TH0 = 0xFC;     // 定时初值(1ms@12MHz)
    TL0 = 0x18;     // 65536 - 1000 = 64536 = 0xFC18
    ET0 = 1;       // 使能T0中断
    TR0 = 1;       // 启动T0
    EA  = 1;       // 使能总中断
}

       
         
void Timer0_ISR(void) interrupt 1
{
    static uint cnt=0;
        TH0 = 0xFC;  // 重装初值(1ms)
    TL0 = 0x18;
        cnt++;
        if(cnt>=timelong)
        {
                cnt=0;
    // 输出当前相序电平
                if (direction == 0)
                {  // 正转
                        switch (PHASE_CW[phaseIndex])
                        {
                                case 0x01: MOTOR_A=1; MOTOR_B=0; MOTOR_C=0; MOTOR_D=0; break;
                                case 0x03: MOTOR_A=1; MOTOR_B=1; MOTOR_C=0; MOTOR_D=0; break;
                                case 0x02: MOTOR_A=0; MOTOR_B=1; MOTOR_C=0; MOTOR_D=0; break;
                                case 0x06: MOTOR_A=0; MOTOR_B=1; MOTOR_C=1; MOTOR_D=0; break;
                                case 0x04: MOTOR_A=0; MOTOR_B=0; MOTOR_C=1; MOTOR_D=0; break;
                                case 0x0C: MOTOR_A=0; MOTOR_B=0; MOTOR_C=1; MOTOR_D=1; break;
                                case 0x08: MOTOR_A=0; MOTOR_B=0; MOTOR_C=0; MOTOR_D=1; break;
                                case 0x09: MOTOR_A=1; MOTOR_B=0; MOTOR_C=0; MOTOR_D=1; break;
                        }
                }
                        else
                        {  // 反转
                                switch (PHASE_CCW[phaseIndex])
                                {
                                case 0x01: MOTOR_A=1; MOTOR_B=0; MOTOR_C=0; MOTOR_D=0; break;
                                case 0x09: MOTOR_A=1; MOTOR_B=0; MOTOR_C=0; MOTOR_D=1; break;
                                case 0x08: MOTOR_A=0; MOTOR_B=0; MOTOR_C=0; MOTOR_D=1; break;
                                case 0x0C: MOTOR_A=0; MOTOR_B=0; MOTOR_C=1; MOTOR_D=1; break;
                                case 0x04: MOTOR_A=0; MOTOR_B=0; MOTOR_C=1; MOTOR_D=0; break;
                                case 0x06: MOTOR_A=0; MOTOR_B=1; MOTOR_C=1; MOTOR_D=0; break;
                                case 0x02: MOTOR_A=0; MOTOR_B=1; MOTOR_C=0; MOTOR_D=0; break;
                                case 0x03: MOTOR_A=1; MOTOR_B=1; MOTOR_C=0; MOTOR_D=0; break;
                                }
                        }

                // 相序索引递增(循环0~7)
                phaseIndex++;
                if (phaseIndex >= 8) phaseIndex = 0;
        }
}         
         
                  


void Delays(uint Xms)
{
    unsigned int i,j;
    for(i=Xms;i>0;i--)
        for(j=110;j>0;j--);
}


void keyscan()
{
    if(jiasu == 0)
    {
        Delays(5);
        if(jiasu == 0)
        {
            sudu++;
            if(sudu >= 5)  
                sudu = 4;
            motor_speed();  
            while(jiasu == 0);
        }            
    }
   
    if(jiansu == 0)
    {
        Delays(5);
        if(jiansu == 0)
        {   
            if(sudu > 0)
                sudu--;
            motor_speed();
            while(jiansu == 0);
        }        
    }
   
    if(begin == 0)
    {
        Delays(5);
        if(begin == 0)
        {   
            sudu = 2;  
            motor_speed();  
            while(begin == 0);  
        }
    }
   
    if(fangxiang == 0)
    {
        Delays(5);
        if(fangxiang == 0)
        {   
            fx_flag = ~fx_flag;
                        direction = fx_flag;  // 同步方向标志
            while(fangxiang == 0);
        }        
    }
}


void motor_speed()
{
    switch(sudu)
    {
        case 0:
            sudu_num = 1;
                        timelong = 20;  //最慢
            break;
        case 1:
            sudu_num = 2;  
                        timelong = 10;
            break;
        case 2:
            sudu_num = 3;  
                        timelong = 5;
            break;
        case 3:
            sudu_num = 4;
                        timelong = 3;
            break;
        case 4:
            sudu_num = 5;  
                        timelong = 1;  //最快
            break;        
    }
}

void main()
{
    motor_speed();
    Timer0_Init();  // 初始化定时器
    while(1)
    {
        keyscan();  // 循环扫描按键
    }
}



作者: 上好佳kkk    时间: 2025-9-13 17:15
补充:是步进电机
作者: rundstedt    时间: 2025-9-13 17:58
ULN2003只能接电压控制的玩具级步进电机,本来就转不快。
作者: keemee    时间: 2025-9-13 19:13
减速电机,要考虑减速比
作者: lei848200    时间: 2025-9-13 22:52
上好佳kkk 发表于 2025-9-13 17:15
补充:是步进电机

驱动电压、电流是否足够。不足的话容易失步。另步进电机好像有启动频率,启动的时候频率要低,后面逐步加速。


作者: a399288395    时间: 2025-9-14 07:50
电机是多少V, 供电电压又是多少V?  如果是5V 是不是接的USB 5V, 功率不足;
作者: chchking    时间: 2025-9-14 15:18
脉冲数 驱动具力
作者: suncat0504    时间: 2025-9-14 15:45
步进电机转动快慢,由两个因素决定:
1、步进脉冲时序变化速度
2、步进电机自身的参数




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1