黄工无刷电机学习
直播中

孔朱磊

7年用户 900经验值
私信 关注
[问答]

请问51单片机如何控制TB6600驱动器驱动42步进电机?

请问51单片机如何控制TB6600驱动器驱动42步进电机?

回帖(1)

余柳婵

2021-10-15 16:27:36
第一次

以前总是看别人写的博客,通过别人的博客解决了我很多问题,从中也学到了各种知识,虽然不是很系统,但也比较有针对性。所以本次我将我这两天做的东西写成了博客,毕竟水平有限还需学习,所以此文仅供参考,但倘若能帮助到别人解决某些问题,明白某些知识那我将甚感欣慰。
这是我第一次写博客,难免有很多不足之处,如有意见敬请发表评论 甚是感谢!
功能实现目标



  • 控制电机停止与启动。
  • 控制电机正反转。
  • 控制电机旋转速度。
  • 能按一定角度进行步进。

硬件简介

本次采用的就是最最最简单的51单片机(不要问我后面程序为什么是reg52.h,问一次打一次)没有外接任何外围器件(除了按键)。只是单纯的控制I/O口,关于单片机的硬件结构就不讲了(其实我也不懂,只会控制下I/O口)。
TB6600驱动器怎么说呢,我觉的它最大的优势就是性价比吧,几十块钱就可以买一个,而且也能实现要求不是很高的实验,对于学生党来说再合适不过了。输出电流和细分都可以通过拨片按需选择,最高细分可达1/32。电源:要求9-42V直流开关电源。电流的话自己看你的电机功率选择就行。
-------------此处省略一万字-------------其他的我就不讲了自行百度下使用手册就行了,相信读懂这种简单的使用手册就不在话下了。
硬件连接

----先说说驱动器和电机的连接----





我此次选用的是两相四线的步进电机,把它的4根线按照电机给的说明书分别接到驱动的的A+,A-,B+,B-即可,驱动器的电源接线就不用说了吧!
接下来重点来了,因为控制器与驱动器有两种接法,如下图










虽然我们可以每一种都试一下也不耽误时间,但我还是要在这里讲解下为什么我选择了共阳而不选共阴。看过TB6600驱动器说明书的童靴,应该知道它与控制器(就是本文的单片机)的连接有两种方式,即共阴或者共阳,此刻有没有想到数码管的共阴共阳哈哈。其实都是一样的概念。我一看说明书毫不犹豫的就按照共阴的接法接好电路,结果一试,电机它丝毫不动。后来我看了下驱动器的接口是光驱动的,而选择共阴接法的话,就意味着我们得靠单片机I/0口的电流来驱动里面的发光二极管,我们都知道单片机I/o口的驱动能力非常小,查看手册可知I/O口的拉电流只有几uA根本不足以驱动发光二极管,的而它的灌电流可达15mA,此时足以驱动发光二极管,这就是为什么要选择共阳接法。
程序代码


// An highlighted block
/*******************程序功能*********************
   1.控制电机停止与启动
   2.控制电机正反转
   3.控制电机转速
   3.控制电机按一定角度步进
************************************************/
#include
//电机控制引脚
***it CLK  = P1^0;
***it ENA  = P1^1;
***it DIR  = P1^2;                  
//按键控制端
***it P_TS  = P2^0;               //正转控制端
***it N_TS  = P2^1;                   //反转控制端
***it P_ADJ = P2^2;         //调速+
***it N_ADJ = P2^3;         //调速-
***it StopStart  = P2^4;           //停止与启动
***it P_Step = P2^5;
***it N_Step = P2^6;
***it SS_Step = P2^7;


unsigned int Tspeed[3]={20,4000,10000};               //调速等级表
unsigned int StepAngle[4]={100,200,400,800};   //步进角度表--90度/180度/360度/720度
bit Run_Status=0;
bit CY_status=0;
unsigned int CYCLE=20;
unsigned int cy_count=0;
unsigned PWM_count=0;


void Init_time();
void Key_scan();
void Step(unsigned int step_count);
/*void delay()                                  //延时函数
{
        unsigned int i = 200;
        while (i--);
} */
void main()
{
        ENA=1;
        CLK=0;
        DIR=0;                   //初始化电机
        Init_time();   //初始化定时器          
        while(1)
        {
                Key_scan();
        }       
}
void Init_time()                                 //初始化定时器
{
        TMOD |= 0x01;
        TH0=(65536-CYCLE)/256;                  //给time0装初值
        TL0=(65536-CYCLE)%256;
        //TH1=(65536-2000)/256;                 //给time1装初值
        //TL1=(65536-2000)%256;
    IE = 0x82;
        //PT1=1;                       //使得time1的优先级高于time0
        TR0=1;                                         //打开两个中断
        //TR1=1;
}
void Enter_Timer0() interrupt 1                                //进入定时器中断
{
        TH0=(65536-CYCLE)/256;
        TL0=(65536-CYCLE)%256;
        CLK=~CLK;
        PWM_count++;
        if(PWM_count==(2*cy_count)&&CY_status)
        {
                PWM_count=0;
                TR0=0;
                ENA=0;
        }       
}
/*void Enter_timer1() interrupt 3
{
        TH1=(65536-2000)/256;                 //给time1装初值
        TL1=(65536-2000)%256;
        Key_scan();
} */


/************************按键扫描程序************************
   功能:读取各按键值,判断是否按下,再处理相应事件
   
   注:按键控制程序,由于按键中断优先级高,且每个按键都设计
       为弹起有效, 所以长时间按住不放会导致电机减速甚至停
           止直至放开按键                     
*************************************************************/
void Key_scan()                                             
{
        static char i=0,j=0;
        if(P_TS==0)                                           //正反转切换
        {
                //delay();                                   //按键消抖
                if(P_TS==0)
                {
                        while(!P_CW);                           //按键按下直到放开
                        DIR=1;
                }
        }
        if(N_TS==0)                                           //正反转切换
        {
                //delay();                                   //按键消抖
                if(N_TS==0)
                {
                        while(!N_CW);                           //按键按下直到放开
                        DIR=0;
                }
        }
        if(P_ADJ==0)                                   //加速
        {
                //delay();                       
                if(P_ADJ==0)
            {
                        while(!P_ADJ);
                        i--;
                        if(i<1)
                        i=0;
                        CYCLE=Tspeed;               
                }
        }
        if(N_ADJ==0)                                   //减速
        {
                //delay();
                if(N_ADJ==0)
                {
                        while(!N_ADJ);
                        i++;
                        if(i>2)
                        i=2;
                        CYCLE=Tspeed;
                }
        }
        if(StopStart==0)
        {
                //delay();
                if(StopStart==0)
                {
                        while(!StopStart);
                        Run_Status=~Run_Status;
                        if(Run_Status)
                        {
                                ENA=1;                  //启动电机
                                TR0=1;                  //开启中断产生脉冲信号
                        }
                        else
                        {
                                ENA=0;                  //关闭电机
                                TR0=0;                  //关闭中断停止脉冲信号
                                CY_status=0;  //刷新步进标志位
                        }
                }
        }
        if(P_Step==0)
        {
                //delay();
                if(P_Step==0)                  //步进角度+
                {
                        while(!P_Step);
                        j++;
                        if(j>3)
                        j=3;
                        Step(StepAngle[j]);                       
                }
        }
        if(N_Step==0)                          //步进角度-
        {
        //        delay();
                if(N_Step==0)
                {
                        while(!N_Step);
                        j--;
                        if(j<1)
                        j=0;
                        Step(StepAngle[j]);                       
                }
        }
        if(SS_Step==0)   //按一定步进角度步进,每按下一次转动一定步进角后停止
        {
                //delay();
                if(SS_Step==0)
                {
                        while(!SS_Step);
                        Step(StepAngle[j]);
                }
        }
}
/***********************角度控制函数*************************/
void Step(unsigned int step_count)
{
        PWM_count=0;
        CY_status=1;
        cy_count=step_count;
        ENA=1;
        TR0=1;
}
举报

更多回帖

×
20
完善资料,
赚取积分