找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5494|回复: 21
打印 上一主题 下一主题
收起左侧

步进电机程序

  [复制链接]
跳转到指定楼层
楼主
                         #include <reg52.h>
/********IO引脚定义***********************************************************/
sbit SW1=P1^0;                        //四个独立按键定义
sbit SW2=P1^1;
sbit SW3=P1^2;
sbit SW4=P1^3;       
sbit SMG1 = P1^4;                                        //数码管第一位定义
sbit SMG2 = P1^5;                                        //数码管第二位定义
sbit SMG3 = P1^6;                                        //数码管第三位定义
sbit SMG4 = P1^7;                                        //数码管第四位定义
int table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x40};           //共阴极数码管段值
unsigned char flag;                   //right(lhj[i+1],lhj[i+2]);        //正转,两个参数代表步进量和转速
/********数据定义***********************************************************/
// 512个脉冲    90
unsigned char dataout[8]={0xf1,0xf2,0xf4,0xf8};
                //这里我们定义4组数,分别对应四拍:A-B-C-D  从板上设计来分配,选择P2口的低四位输出
                //P20A相,P21B相,P22C相,P23D相,将高四位都置1,也就是F
                //我们用索引的方式输出,比如正转,元素由03这样的循环,反转则由30的循环
                //程序中我们保存索引号,比如上次转在第2元素停下,则下次的正转由3开始向后计数,反转则由1开始向前计数
                //这样,电机的转角度就会很精确
unsigned char datac=0;        //存放索引号(元素号)
unsigned int gStep = 0;
unsigned long gMainchong = 0;
unsigned int gJd = 0;
unsigned int gKey_flag = 0;
unsigned int b1,b2,b3;                                        //临时变量
void delayms(xms);
void Timer0_Init();
void Display();
void rightAll();
void leftAll();
void stepAll();
void Ang();
void KeyScan();
/********函数声明*************************************************************/
void right(unsigned int Speed,unsigned int road);        //正转
void left(unsigned int Speed,unsigned int road);        //反转
void mDelay(unsigned int DelayTime);                //延时函数
/***********主函数开始********************************************************/
void main()
{  
        unsigned char i=0;
        P2&=0XF0;                        //ULN2003A直接驱动,为高电平输出,初始时为低电平,这里一定不能少了
   mDelay(100);
   Timer0_Init();
        while(1)
        {
                KeyScan();
                Ang();
        }
               
}
/******************************************************************************
* 名称: Timer0_Init()
* 功能: 定时器0初始化
* 输入: 无
* 输出: 无
* 说明:
******************************************************************************/
void Timer0_Init()
{
        TMOD=0x01;                    //定时器方式一
        TH0=(65536-500)/256;                                //定义高字节
        TL0=(65536-500)%256;                          //定义低字节
        ET0=1;                                    //计数器中断
        EA=1;                            //开总中断
//        TR0 = 1;
}
/******************************************************************************
/******************************************************************************
* 名称: Set_Display()
* 功能: 数码管显示函数
* 输入: 无
* 输出: 无
* 说明:
******************************************************************************/
void Display()
{                                                              //以下把num值区分开 以便数码管显示
        b1=gJd%1000/100;                         //百位
    b2=gJd%1000%100/10;                         //十位
        b3=gJd%1000%100%10;                         //个位
        P0=0x40;
    SMG1=0;                                                         //显示"-"
    delayms(3);
    SMG1=1;
        P0=table[b1];
    SMG2=0;                                                         //显示百位
    delayms(3);
    SMG2=1;
       
P0=table[b2];
        SMG3=0;                                                         //显示十位
        delayms(3);
        SMG3=1;
        P0=table[b3];
    SMG4=0;
    delayms(3);                                                 //显示个位
    SMG4=1;
}
/***********左转,两个参数代表步进量和转速*************************************/
void right(unsigned int Speed,unsigned int road)
{
        //步进节拍:A-B-C-D
        do{               
                if(datac==3)                //索引号超出3回到0
                        datac=0;
                else
                        datac++;
                P2=dataout[datac];        //这里就在P2口输出我们定义好的相序步进,P20A相,P21B相,P22C相,P23D
                                                        //这里我们不考虑P2的高四位,直接赋值
                mDelay(road);                //这里的延时就可控制转速
                Speed--;
        }       
        while(Speed);
        P2&=0XF0;                //将四个脚复位0
}
/***********右转,两个参数代表步进量和转速*************************************/
void rightAll()
{
        if(gStep == 3)
                gStep = 0;
        else
                gStep++;
        P2=dataout[gStep];
        if(gMainchong == 2048)
                gMainchong = 0;
        else
       
       
gMainchong++;
}
/***********整体左转*************************************/
void leftAll()
{
        if(gStep == 0)
                gStep = 3;
        else
                gStep--;
        P2=dataout[gStep];
        if(gMainchong == 0)
//                gMainchong = 4096;
                gMainchong = 2048;
        else
                gMainchong--;
}
/***********固定动作*************************************/
void  stepAll()
{
        right(512, 50);
        left(1024, 50);
        right(215, 50);
}
/***********计算并显示角度*************************************/
void Ang()          // 计算角度
{
        unsigned int i;
//        gJd = gMainchong*5.625/32.0;
        gJd = gMainchong*11.25/64.0;
       
        b1=gJd%1000/100;                          //将得到的数据拆分,以便数码管显示 百位
        b2=gJd%1000%100/10;                          //十位4
        b3=gJd%1000%100%10;                          //个位
    for(i=0;i<20;i++)  Display(); //显示20遍,防止显示数据抖动,变化太快               
}
/***********反转,两个参数代表步进量和转速*************************************/
void left(unsigned int Speed,unsigned int road)
{
        //步进节拍A-D-C-B
        do{               
                if(datac==0)                //索引号超出0回到3
                        datac=3;
                else
                        datac--;
                P2=dataout[datac];        //这里就在P2口输出我们定义好的相序步进,P20A相,P21B相,P22C相,P23D
                                                        //这里我们不考虚P2的低四位,直接赋值
                mDelay(road);                //这里的延时就可控制转速
                Speed--;
        }       
        while(Speed);
        P2&=0XF0;                //将四个脚复位0
}
/***********延时函数*******************************************************/
void mDelay(unsigned int DelayTime)                         // 10ms
{   
        unsigned char j=0;
     while(DelayTime--)
         {
                 for(j=0;j<10;j++){}
         }
}
// 延时函数
void delayms(xms)
{
         
     unsigned int x,y;
         for(x=xms;x>0;x--)
                 for(y=110;y>0;y--)
                        ;
}
/***********按键扫描函数*************************************/
void KeyScan()
{
        if(SW1 == 0)
        {
                delayms(10);
                if(SW1 == 0)        // 正传
                {
                        TR0 = 0;
                        gKey_flag = 1; //
                        Timer0_Init();
                        TR0 = 1;
                }       
        }
        if(SW2 == 0)
        {
                delayms(10);
                if(SW2 == 0)        // 反传
                {
                        TR0 = 0;
                        gKey_flag = 2;
                        Timer0_Init();
                        TR0 = 1;
                }       
        }
        if(SW3 == 0)
        {
                delayms(10);
                if(SW3 == 0)        // 自定义动作
                {
                        TR0 = 0;
                        gKey_flag = 3;
                        Timer0_Init();
                        TR0 = 1;
                }       
        }
        if(SW4 == 0)
        {
                delayms(10);
                if(SW4 == 0)        // 停止
                {
                        TR0 = 0;
                        gKey_flag = 0;
                        Timer0_Init();
                        TR0 = 1;
                }       
        }
}
/******************************************************************************
* 名称:  T0_int() interrupt 1
* 功能:  定时器0 中断函数
* 输入:  无
* 输出:  无
* 说明:
******************************************************************************/
void T0_int() interrupt 1
{       
//        flag=1;                           //标志位之一          
        TR0 = 0;
        switch(gKey_flag)
        {
                case 0x00:
                                P2&=0XF0;
                                break;
                case 0x01:
                                rightAll();
                                TH0=(65536-10000)/256;                                //定义高字节
                                TL0=(65536-10000)%256;                          //定义低字节
                               
              TR0 = 1;
                                break;
                case 0x02:
                                leftAll();
                               
TH0=(65536-10000)/256;                                //定义高字节
                                TL0=(65536-10000)%256;                          //定义低字节
                                TR0 = 1;
                                break;
                case 0x03:
                                stepAll();
                                break;
                default:
                        break;
        }
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏4 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:51088 发表于 2014-11-11 13:13 来自手机 | 只看该作者
51单片机按钮,控制,步进电机,,有电路图共享吗
回复

使用道具 举报

板凳
ID:67573 发表于 2014-11-15 13:58 | 只看该作者
有电路图共享
回复

使用道具 举报

地板
ID:66729 发表于 2014-12-12 21:10 | 只看该作者

电路图发上来看一看吧
回复

使用道具 举报

5#
ID:68659 发表于 2014-12-24 21:23 | 只看该作者
回复

使用道具 举报

6#
ID:68659 发表于 2014-12-24 21:26 | 只看该作者
nojiya88 发表于 2014-12-12 21:10
电路图发上来看一看吧

电路图

QQ截图20141224212140.png (13.97 KB, 下载次数: 179)

QQ截图20141224212140.png
回复

使用道具 举报

7#
ID:67573 发表于 2014-12-25 14:00 | 只看该作者
51单片机按钮,控制,步进电机,,有电路图共享吗
回复

使用道具 举报

8#
ID:70769 发表于 2014-12-26 02:34 | 只看该作者
GOOD!!!
回复

使用道具 举报

9#
ID:71359 发表于 2014-12-30 12:37 | 只看该作者
谢谢楼主分享
回复

使用道具 举报

10#
ID:56948 发表于 2015-5-8 14:26 | 只看该作者

谢谢楼主分享
回复

使用道具 举报

11#
ID:95360 发表于 2015-11-11 04:01 | 只看该作者
收藏学习,谢谢楼主。
回复

使用道具 举报

12#
ID:46091 发表于 2015-11-21 18:39 | 只看该作者
能不能设成按一下起动步进半圈松开停止啊
回复

使用道具 举报

13#
ID:16003 发表于 2015-11-23 00:51 来自手机 | 只看该作者
谢谢楼主分享,认真学习学习。
回复

使用道具 举报

14#
ID:102611 发表于 2016-1-10 12:21 | 只看该作者
谢谢   很好的资料
回复

使用道具 举报

15#
ID:104183 发表于 2016-6-17 18:49 | 只看该作者
数码管连接的电路可否共享呢
回复

使用道具 举报

16#
ID:119261 发表于 2016-7-18 15:40 | 只看该作者
怎么平稳转动
回复

使用道具 举报

17#
ID:134543 发表于 2016-7-29 20:14 | 只看该作者
楼主好人啊
回复

使用道具 举报

18#
ID:185661 发表于 2017-5-17 22:09 | 只看该作者
很好的资料
回复

使用道具 举报

19#
ID:192534 发表于 2017-5-18 08:38 | 只看该作者
谢谢楼主分享,认真学习学习。
回复

使用道具 举报

20#
ID:217754 发表于 2017-7-22 22:55 | 只看该作者
谢谢分享。明天试一下。。感觉学一样东西好难呀。
回复

使用道具 举报

21#
ID:224536 发表于 2017-8-5 11:57 | 只看该作者
求步进电机的点动控制程序,,现在才只能控制正反转
回复

使用道具 举报

22#
ID:224939 发表于 2017-8-5 12:27 | 只看该作者
新手,学习了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表