[资料分享] 带插补计算的四象限步进电机控制仿真与单片机源程序

Jacktang   2019-2-13 20:01 楼主
51单片机使用ULN2003A芯片驱动步进电机程序加Proteus仿真
单片机源程序如下:
#include
#define uint unsigned int
#define uchar unsigned char
sbit KEY1=P1^0;
sbit KEY2=P1^1;
sbit KEY3=P1^2;
sbit KEY4=P1^3;
sbit KEY5=P1^4;
sbit KEY6=P1^5;
sbit KEY7=P1^6;


uchar code motor_1[]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09,
                                          0x10,0x30,0x20,0x60,0x40,0xc0,0x80,0x90}; //第一象限
uchar code motor_2[]={0x08,0x0c,0x04,0x06,0x02,0x03,0x01,0x09,
                                          0x10,0x30,0x20,0x60,0x40,0xc0,0x80,0x90}; //第二象限
uchar code motor_3[]={0x08,0x0c,0x04,0x06,0x02,0x03,0x01,0x09,
                                          0x80,0xc0,0x40,0x60,0x20,0x30,0x10,0x90};        //第三象限
uchar code motor_4[]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09,
                                          0x80,0xc0,0x40,0x60,0x20,0x30,0x10,0x90};
uchar code shuma[]={0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //第四象限


uchar bushu[50];  //路径存储
int F,Xe=0,Ye=0,J,Xm=0,Ym=0,dat=0,xiangxian=0;
uint key_flag=0,key_change=0,chabu_flag=0,motor_flag=1,start_flag=0;




void keyscan(void);                                               //获取按键
void chabu(void);                                                //插补计算
void start(void);                                                //步进电机执行与数码管显示




void main(void)
{
        EA = 1;                                           /*************************************/
        ET0 = 1;                                                           
        TMOD = 0x01;                                                 //定时器初始化//
        TH0= (65536-1000) / 256;                        
        TL0= (65536-1000)%256;          /*************************************/
        TR0 = 1;
        while(1)
        {
                  keyscan();                                                                  //按键计数获取
                chabu();                                                                  //插补计算,生成步数轨迹
                start();                                                                  //电机按照轨迹运行
        }
}


void keyscan(void)
{
        static uint key_up=1;
        if(key_up&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0||KEY5==0||KEY6==0||KEY7==0))
        {
                key_up=0;                                                      // 不支持连按。      
                if(key_change==1)                                                  //消抖,等待10ms
                {
                        if(KEY1==0)         Xe++;
                        if(KEY2==0)  Ye++;
                        if(KEY3==0) {key_flag=1;xiangxian=1;}
                        if(KEY4==0) {key_flag=1;xiangxian=2;}
                        if(KEY5==0) {key_flag=1;xiangxian=3;}
                        if(KEY6==0) {key_flag=1;xiangxian=4;}
                        if(KEY7==0) {P0=0X99;}


                }
        }
        else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1&&KEY5==1&&KEY6==1)key_up=1;//按键松开        
}


void chabu(void)
{
        int i,a=0,b=0;
        
        if(key_flag==1)
        {
                J=Xe+Ye;
                for(i=0;i
                {
                        F=((Ym*Xe)-(Xm*Ye));                           //插补计算公式
                        if(F==0||F>0)                                        //如果F大于等于零往X方向走
                        {
                                a++;
                                if(a==8)a=0;
                                bushu=(a-1);
                                Xm++;        
                        }
                        else                                                         //否则往Y方向走
                        {
                                b++;
                                if(b==8)b=0;
                                bushu=(b+7);
                                Ym++;
                        }
                        if(i==(J-1))                                         //判断是否到达终点
                        {
                                chabu_flag=1;
                                key_flag=0;
                                start_flag=1;        
                        }        
                }
               
        }        
}


void start(void)
{
        
        if(chabu_flag==1&&motor_flag==1&&start_flag==1&&xiangxian==1)//判断是否为第一象限
        {           
                motor_flag=0;
                P0=motor_1[bushu[dat]];
                if(bushu[dat]<8)
                {
                        P2=shuma[bushu[dat]];
                }
                else
                {
                        P3=shuma[(bushu[dat]-8)];
                }
                if(dat==(J-1))
                {
                        Xe=0;Ye=0;Xm=0;Ym=0;dat=0;              //初始化变量
                        key_flag=0;key_change=0;chabu_flag=0;
                        motor_flag=1;start_flag=0;              //初始化标志量
                }        
        }




        if(chabu_flag==1&&motor_flag==1&&start_flag==1&&xiangxian==2)//判断是否为第二象限
        {           
                motor_flag=0;
                P0=motor_2[bushu[dat]];
                if(bushu[dat]<8)
                {
                        P2=shuma[bushu[dat]];
                }
                else
                {
                        P3=shuma[(bushu[dat]-8)];
                }
                if(dat==(J-1))
                {
                        Xe=0;Ye=0;Xm=0;Ym=0;dat=0;              //初始化变量
                        key_flag=0;key_change=0;chabu_flag=0;
                        motor_flag=1;start_flag=0;              //初始化标志量
                }        
        }


        if(chabu_flag==1&&motor_flag==1&&start_flag==1&&xiangxian==3)//判断是否为第三象限
        {           
                motor_flag=0;
                P0=motor_3[bushu[dat]];
                if(bushu[dat]<8)
                {
                        P2=shuma[bushu[dat]];
                }
                else
                {
                        P3=shuma[(bushu[dat]-8)];
                }
                if(dat==(J-1))
                {
                        Xe=0;Ye=0;Xm=0;Ym=0;dat=0;              //初始化变量
                        key_flag=0;key_change=0;chabu_flag=0;
                        motor_flag=1;start_flag=0;              //初始化标志量
                }        
        }


   if(chabu_flag==1&&motor_flag==1&&start_flag==1&&xiangxian==4) //判断是否为第四象限
        {           
                motor_flag=0;
                P0=motor_4[bushu[dat]];
                if(bushu[dat]<8)
                {
                        P2=shuma[bushu[dat]];
                }
                else
                {
                        P3=shuma[(bushu[dat]-8)];
                }
                if(dat==(J-1))
                {
                        Xe=0;Ye=0;Xm=0;Ym=0;dat=0;              //初始化变量
                        key_flag=0;key_change=0;chabu_flag=0;
                        motor_flag=1;start_flag=0;              //初始化标志量
                }        
        }
}


void Timer0( ) interrupt 1
{
        static uchar key_jishu=0,motor_jishu=0,motor_jishu_a=0;
        TR0 = 0;
        TH0= (65536-1000) / 256;                                                 //定时1ms
        TL0= (65536-1000)%256;
        key_jishu++;        
        if(key_jishu==10&&key_change==0)                                 //按键延时
        {
                key_change=1;                                                                 //按键标志量置1
                key_jishu=0;                                                                 //计数清零
        }                                                               
        if(chabu_flag==1)                                                                   //计数10ms的次数,因为500太大
        {
                motor_jishu++;
                if(motor_jishu==10)
                {
                        motor_jishu_a++;
                        motor_jishu=0;
                }
        }


        if(motor_flag==0&&motor_jishu_a==50)                                 //50ms计时
        {
                motor_flag=1;                                                                        //电机标志量置1
                dat++;                                                                                         //数组位置,电机步数
                motor_jishu_a=0;                                                                 //计数值清零
        }
        TR0 = 1;        
}

回复评论 (1)

学习了,谢谢!

点赞  2023-6-10 11:16
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复