单片机之步进电机

单片机的应用特别地多,其用途非常广泛,我们这些案例只是涉及其基本部分,没有深究,但是也是要作为一个了解的,今天就学习一下步进电机和可控步进电机


步进电机

实验现象

发现步进电机按照一定速度逆时针旋转,同时发现SM接口处左侧的led灯以一定频率闪烁
(PS:在没有步进电机的情况下,可以通过查看led的闪烁来判断步进电机是否处于工作状态下)

工作原理

步进电机
电脉冲信号转变为角位移或线位移的开环控制元步进电机件

(在非超载的情况下,电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响,)

  • 当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度,称为“步距角”,它的旋转是以固定的角度一步一步运行的。
  • 可以通过控制脉冲个数来控制角位移量,从而达到准确定位的目的;
  • 同时可以通过控制脉冲频率来控制电机转动的速度和加速度,从而达到调速的目的

励磁方式是一相励磁,励磁表在程序中为0111、1011、1101、1110,程序连续不停地在不同口送入脉冲信号,即可使步进电机旋转,通过设定定时器的定时时间减慢步进电机的旋转速度

电路原理图:
单片机之步进电机_第1张图片

扩展:
步进电机的励磁方式有三种:

  1. 一相励磁
    在每一瞬间,步进电机只有一个线圈导通。每送一个励磁信号,步进电机旋转5.625°,这是三种励磁方式中最简单的一种
    顺序表如下:
    单片机之步进电机_第2张图片

  2. 二相励磁
    在每一瞬间,步进电机有两个线圈同时导通。每送一个励磁信号,步进电机旋转5.625°
    顺序表如下:
    单片机之步进电机_第3张图片

  3. 一-二相励磁
    为一相励磁与二相励磁交替导通的方式。每送一个励磁信号,步进电机旋转2.8125°
    顺序表如下:
    单片机之步进电机_第4张图片

代码解析

设计流程图如下:

单片机之步进电机_第5张图片
设置其励磁的顺序表的元素,通过中断实现

void time0() interrupt 1
{
     
	 switch(i++)//控制步进电机不同IO脉冲电平
	 {
     
	 case 1: s1=1;s2=0;s3=0;s4=0;break;
	 case 2: s1=0;s2=1;s3=0;s4=0;break;
	 case 3: s1=0;s2=0;s3=1;s4=0;break;
	 case 4: s1=0;s2=0;s3=0;s4=1;break;
	 }
	 if(i==5)
	 i=1;
}

初始化

void init_sys()			  
{
     	
    P4M0=0Xff;  //P4口推挽输出
	P4M1=0X00;
//	LED =0;	   //数码管显示
	P4  =0X00;	 //P4口设置低电平,避免复位时对接口造成影响
	TMOD = 0x00;   //设置定时器0,16位
	TH0  = (65536-10000)/256;	//设定5ms
	TL0  = (65536-10000)%256;
	TCON = 0X10;	//定时器开始计时
	IE   = 0x82;	//开启CPU中断,定时器0中断
}

最后主函数中设置永真循环即可


可控步进电机

实验现象

现象与步进电机相同,只是增加了控制功能
即:
K2键可控制步进电机的旋转方向
K3键控制步进电机的旋转与停止

工作原理

通过在P4.1、P4.2、P4.3、P4.4口每隔5ms*sudu的时间输入高电平(sudu值由Key1键进行确定,并在数码管最右端显示,分别为1-12这12个档位,数值越大,转速越慢)
并结合Key2键确认旋转方向(按下按键则按相反方向进行旋转)
再结合Key3键控制步进电机旋转还是停止

代码解析

工程设计流程图如下:

单片机之步进电机_第6张图片

  • 反转部分代码
    (只需要判断按键是否按下,包含按键消抖,就利用条件语句,选择不同的顺序,原来1 2 3 4对应的顺序表,现在反过来对应即可)
void Xstep_Process()
{
     
    static uchar i = 1;                      
    if( btRotationFlag == 0 )                
    {
     
        switch( i++ )                      
        {
     
            case 1:
                sbtS1 = 1;  sbtS2 = 0;  sbtS3 = 0;  sbtS4 = 0;  break;
            case 2:
                sbtS1 = 0;  sbtS2 = 1;  sbtS3 = 0;  sbtS4 = 0;  break;
            case 3:
                sbtS1 = 0;  sbtS2 = 0;  sbtS3 = 1;  sbtS4 = 0;  break;
            case 4:
                sbtS1 = 0;  sbtS2 = 0;  sbtS3 = 0;  sbtS4 = 1;  break;
            default:
                sbtS1 = 0;  sbtS2 = 0;  sbtS3 = 0;  sbtS4 = 0;  break;
        }
        if( i == 5 )
            i = 1;
    }                                     
    else
    {
     
        switch( i++ )
        {
     
            case 1:
                sbtS1 = 0;  sbtS2 = 0;  sbtS3 = 0;  sbtS4 = 1;  break;
            case 2:
                sbtS1 = 0;  sbtS2 = 0;  sbtS3 = 1;  sbtS4 = 0;  break;
            case 3:
                sbtS1 = 0;  sbtS2 = 1;  sbtS3 = 0;  sbtS4 = 0;  break;
            case 4:
                sbtS1 = 1;  sbtS2 = 0;  sbtS3 = 0;  sbtS4 = 0;  break;
            default:
                sbtS1 = 0;  sbtS2 = 0;  sbtS3 = 0;  sbtS4 = 0;  break;
        }
        if( i == 5 )
            i = 1;
    }
}
  • 数码管显示部分
    设定其初始值为一定的档数,改变一个数字改变一下频率,得到不同的部分,再利用数码管部分的知识成功显示即可
void Seg7LedDisplay( uchar s, uchar  e )
{
     
    unsigned char arrSegSelect[] = {
     0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x40, 0x00}; 
    static  int  i;
    P2 = ( P2 & 0xf0 ) | i;
    switch( i )
    {
     
        case 0:
            P0 = arrSegSelect[cstDig0];   break;
        case 1:
            P0 = arrSegSelect[cstDig1];   break;
        case 2:
            P0 = arrSegSelect[cstDig2];   break;
        case 3:
            P0 = arrSegSelect[cstDig3];   break;
        case 4:
            P0 = arrSegSelect[cstDig4];   break;
        case 5:
            P0 = arrSegSelect[cstDig5];   break;
        case 6:
            P0 = arrSegSelect[cstDig6];   break;
        case 7:
            P0 = arrSegSelect[cstDig7];   break;
        case 8:
            P0 = cstDig8;           break;
        default:
            P0 = 0x00;            break;
    }
    if( ++i > e ) i = s;
}

  • 主函数部分
    包含其判断使能是否有效,即步进电机能否工作
    以及是什么挡位的使能有效,从而得到多长时间的间隔改变转动频率
void main()
{
     
    Init();
    ucLedTmp = 0x00;            
    while( 1 )
    {
     
        if( btT10usFlag )
        {
     
            btT10usFlag = 0;  T10us_Process();
        }
        if( btT100usFlag )
        {
     
            btT100usFlag = 0;  T100us_Process();
        }
        if( btT1msFlag )
        {
     
            btT1msFlag = 0;  T1ms_Process();
        }
        if( btT10msFlag )
        {
     
            btT10msFlag = 0;  T10ms_Process();
        }
        if( btT100msFlag )
        {
     
            btT100msFlag = 0; T100ms_Process();
        }
        if( ( btTXmsFlag && btTXmsFlag_en ) ) 
        {
     
            btTXmsFlag = 0;  TXms_Process();
        }
    }
}
  • 中断服务处理部分
    中断为10次,即计数10次,就会开启一种新状态

  • 初始化部分
    与步进电机类似,增加部分统计变量的初值

  • 各节拍的处理函数
    不同地方的显示,选择不同的频率

void T10us_Process()
{
     

}
void T100us_Process()          
{
     
    ucClockXms++;
    if ( ucClockXms == ( cstClockXmsMaxNum ) )
    {
     
        ucClockXms = 0;   btTXmsFlag = 1;
    }
}
void T1ms_Process()
{
     
    Seg7LedDisplay( cstDigBegin, cstDigEnd );
}
void T10ms_Process() 
{
     
    Key_Scan();
}
void TXms_Process()  
{
     
    Xstep_Process();
}
void T100ms_Process()   
{
     
    ucSpeed_Seg = ucSpeed;
}
  • 按键扫描即消抖部分
    参照按键消抖代码即可

你可能感兴趣的:(单片机,单片机,步进电机,可控步进电机)