找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3694|回复: 8
收起左侧

带插补计算的四象限步进电机控制仿真与单片机源程序

[复制链接]
ID:366841 发表于 2018-7-7 15:03 | 显示全部楼层 |阅读模式
51单片机使用ULN2003A芯片驱动步进电机程序加Proteus仿真。

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
TIM截图20180707150244.png 0.png

单片机源程序如下:
  1. #include<reg51.h>
  2. #define uint unsigned int
  3. #define uchar unsigned char
  4. sbit KEY1=P1^0;
  5. sbit KEY2=P1^1;
  6. sbit KEY3=P1^2;
  7. sbit KEY4=P1^3;
  8. sbit KEY5=P1^4;
  9. sbit KEY6=P1^5;
  10. sbit KEY7=P1^6;

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

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


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


  26. void main(void)
  27. {
  28.         EA = 1;                                           /*************************************/
  29.         ET0 = 1;                                                          
  30.         TMOD = 0x01;                                                 //定时器初始化//
  31.         TH0= (65536-1000) / 256;                        
  32.         TL0= (65536-1000)%256;          /*************************************/
  33.         TR0 = 1;
  34.         while(1)
  35.         {
  36.                   keyscan();                                                                  //按键计数获取
  37.                 chabu();                                                                  //插补计算,生成步数轨迹
  38.                 start();                                                                  //电机按照轨迹运行
  39.         }
  40. }

  41. void keyscan(void)
  42. {
  43.         static uint key_up=1;
  44.         if(key_up&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0||KEY5==0||KEY6==0||KEY7==0))
  45.         {
  46.                 key_up=0;                                                      // 不支持连按。       
  47.                 if(key_change==1)                                                  //消抖,等待10ms
  48.                 {
  49.                         if(KEY1==0)         Xe++;
  50.                         if(KEY2==0)  Ye++;
  51.                         if(KEY3==0) {key_flag=1;xiangxian=1;}
  52.                         if(KEY4==0) {key_flag=1;xiangxian=2;}
  53.                         if(KEY5==0) {key_flag=1;xiangxian=3;}
  54.                         if(KEY6==0) {key_flag=1;xiangxian=4;}
  55.                         if(KEY7==0) {P0=0X99;}

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

  60. void chabu(void)
  61. {
  62.         int i,a=0,b=0;
  63.        
  64.         if(key_flag==1)
  65.         {
  66.                 J=Xe+Ye;
  67.                 for(i=0;i<J;i++)
  68.                 {
  69.                         F=((Ym*Xe)-(Xm*Ye));                           //插补计算公式
  70.                         if(F==0||F>0)                                        //如果F大于等于零往X方向走
  71.                         {
  72.                                 a++;
  73.                                 if(a==8)a=0;
  74.                                 bushu[i]=(a-1);
  75.                                 Xm++;       
  76.                         }
  77.                         else                                                         //否则往Y方向走
  78.                         {
  79.                                 b++;
  80.                                 if(b==8)b=0;
  81.                                 bushu[i]=(b+7);
  82.                                 Ym++;
  83.                         }
  84.                         if(i==(J-1))                                         //判断是否到达终点
  85.                         {
  86.                                 chabu_flag=1;
  87.                                 key_flag=0;
  88.                                 start_flag=1;       
  89.                         }       
  90.                 }
  91.                
  92.         }       
  93. }

  94. void start(void)
  95. {
  96.        
  97.         if(chabu_flag==1&&motor_flag==1&&start_flag==1&&xiangxian==1)//判断是否为第一象限
  98.         {          
  99.                 motor_flag=0;
  100.                 P0=motor_1[bushu[dat]];
  101.                 if(bushu[dat]<8)
  102.                 {
  103.                         P2=shuma[bushu[dat]];
  104.                 }
  105.                 else
  106.                 {
  107.                         P3=shuma[(bushu[dat]-8)];
  108.                 }
  109.                 if(dat==(J-1))
  110.                 {
  111.                         Xe=0;Ye=0;Xm=0;Ym=0;dat=0;              //初始化变量
  112.                         key_flag=0;key_change=0;chabu_flag=0;
  113.                         motor_flag=1;start_flag=0;              //初始化标志量
  114.                 }       
  115.         }


  116.         if(chabu_flag==1&&motor_flag==1&&start_flag==1&&xiangxian==2)//判断是否为第二象限
  117.         {          
  118.                 motor_flag=0;
  119.                 P0=motor_2[bushu[dat]];
  120.                 if(bushu[dat]<8)
  121.                 {
  122.                         P2=shuma[bushu[dat]];
  123.                 }
  124.                 else
  125.                 {
  126.                         P3=shuma[(bushu[dat]-8)];
  127.                 }
  128.                 if(dat==(J-1))
  129.                 {
  130.                         Xe=0;Ye=0;Xm=0;Ym=0;dat=0;              //初始化变量
  131.                         key_flag=0;key_change=0;chabu_flag=0;
  132.                         motor_flag=1;start_flag=0;              //初始化标志量
  133.                 }       
  134.         }

  135.         if(chabu_flag==1&&motor_flag==1&&start_flag==1&&xiangxian==3)//判断是否为第三象限
  136.         {          
  137.                 motor_flag=0;
  138.                 P0=motor_3[bushu[dat]];
  139.                 if(bushu[dat]<8)
  140.                 {
  141.                         P2=shuma[bushu[dat]];
  142.                 }
  143.                 else
  144.                 {
  145.                         P3=shuma[(bushu[dat]-8)];
  146.                 }
  147.                 if(dat==(J-1))
  148.                 {
  149.                         Xe=0;Ye=0;Xm=0;Ym=0;dat=0;              //初始化变量
  150.                         key_flag=0;key_change=0;chabu_flag=0;
  151.                         motor_flag=1;start_flag=0;              //初始化标志量
  152.                 }       
  153.         }

  154.    if(chabu_flag==1&&motor_flag==1&&start_flag==1&&xiangxian==4) //判断是否为第四象限
  155.         {          
  156.                 motor_flag=0;
  157.                 P0=motor_4[bushu[dat]];
  158.                 if(bushu[dat]<8)
  159.                 {
  160.                         P2=shuma[bushu[dat]];
  161.                 }
  162.                 else
  163.                 {
  164.                         P3=shuma[(bushu[dat]-8)];
  165.                 }
  166.                 if(dat==(J-1))
  167.                 {
  168.                         Xe=0;Ye=0;Xm=0;Ym=0;dat=0;              //初始化变量
  169.                         key_flag=0;key_change=0;chabu_flag=0;
  170.                         motor_flag=1;start_flag=0;              //初始化标志量
  171.                 }       
  172.         }
  173. }

  174. void Timer0( ) interrupt 1
  175. {
  176.         static uchar key_jishu=0,motor_jishu=0,motor_jishu_a=0;
  177.         TR0 = 0;
  178.         TH0= (65536-1000) / 256;                                                 //定时1ms
  179.         TL0= (65536-1000)%256;
  180.         key_jishu++;       
  181.         if(key_jishu==10&&key_change==0)                                 //按键延时
  182.         {
  183.                 key_change=1;                                                                 //按键标志量置1
  184.                 key_jishu=0;                                                                 //计数清零
  185.         }                                                               
  186.         if(chabu_flag==1)                                                                   //计数10ms的次数,因为500太大
  187.         {
  188.                 motor_jishu++;
  189.                 if(motor_jishu==10)
  190.                 {
  191.                         motor_jishu_a++;
  192.                         motor_jishu=0;
  193.                 }
  194.         }

  195.         if(motor_flag==0&&motor_jishu_a==50)                                 //50ms计时
  196.         {
  197.                 motor_flag=1;                                                                        //电机标志量置1
  198.                 dat++;                                                                                         //数组位置,电机步数
  199.                 motor_jishu_a=0;                                                                 //计数值清零
  200.         }
  201.         TR0 = 1;       
  202. }
复制代码

所有资料51hei提供下载:
步进电机控制.rar (63.11 KB, 下载次数: 70)

评分

参与人数 2黑币 +55 收起 理由
MrXirt + 5 很给力!
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:367194 发表于 2018-7-10 09:25 | 显示全部楼层
小白有个问题想要问一下,F,Xe=0,Ye=0,J,Xm=0,Ym=0,dat=0,xiangxian=0这些变量从  int  改为  uchar
型为什么就只有X电机运动啊??
回复

使用道具 举报

ID:367194 发表于 2018-7-10 09:38 | 显示全部楼层
int F,Xe=0,Ye=0,J,Xm=0,Ym=0,dat=0,xiangxian=0;这条语句把 int 改为 uchar 就只有
回复

使用道具 举报

ID:367194 发表于 2018-7-10 09:39 | 显示全部楼层
int F,Xe=0,Ye=0,J,Xm=0,Ym=0,dat=0,xiangxian=0;
这条语句将 int 改为 uchar 为什么只有电机X运动??
回复

使用道具 举报

ID:218113 发表于 2018-7-14 10:35 | 显示全部楼层
谢谢分享
回复

使用道具 举报

ID:89286 发表于 2018-7-25 07:52 | 显示全部楼层
thanks for sharing
回复

使用道具 举报

ID:317629 发表于 2018-9-7 14:46 | 显示全部楼层
谢谢分享
回复

使用道具 举报

ID:748774 发表于 2020-5-15 02:25 来自手机 | 显示全部楼层
请问怎么输入坐标呀
回复

使用道具 举报

ID:748774 发表于 2020-5-15 02:46 来自手机 | 显示全部楼层
MrXirt 发表于 2018-7-10 09:39
int F,Xe=0,Ye=0,J,Xm=0,Ym=0,dat=0,xiangxian=0;
这条语句将 int 改为 uchar 为什么只有电机X运动??

你好,我想请问下怎么把xy的坐标输入进去,是通过改程序还是按键
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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