找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机如何写用脉冲控制步进电机呢?

[复制链接]
跳转到指定楼层
楼主
ID:475888 发表于 2019-2-18 21:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1黑币
  1. #include <reg52.h>

  2. signed long beats = 0;  //电机转动节拍总数

  3. void KeyDriver();

  4. void main()
  5. {
  6.     EA = 1;       //使能总中断
  7.     TMOD = 0x01;  //设置T0为模式1
  8.     TH0  = 0xFC;  //为T0赋初值0xFC67,定时1ms
  9.     TL0  = 0x67;
  10.     ET0  = 1;     //使能T0中断
  11.     TR0  = 1;     //启动T0
  12.         
  13.     while (1)
  14.     {
  15.         KeyDriver();   //调用按键驱动函数
  16.     }
  17. }
  18. /* 步进电机启动函数,angle-需转过的角度 */
  19. void StartMotor(signed long angle)
  20. {
  21.     //在计算前关闭中断,完成后再打开,以避免中断打断计算过程而造成错误
  22.     EA = 0;
  23.     beats = (angle * 4076) / 360; //实测为4076拍转动一圈
  24.     EA = 1;
  25. }
  26. /* 步进电机停止函数 */
  27. void StopMotor()
  28. {
  29.     EA = 0;
  30.     beats = 0;
  31.     EA = 1;
  32. }
  33. /* 按键动作函数,根据键码执行相应的操作,keycode-按键键码 */
  34. void KeyAction(unsigned char keycode)
  35. {
  36.     static bit dirMotor = 0;  //电机转动方向
  37.    
  38.     if ((keycode>=0x30) && (keycode<=0x39))  //控制电机转动1-9圈
  39.     {
  40.         if (dirMotor == 0)
  41.             StartMotor(360*(keycode-0x30));
  42.         else
  43.             StartMotor(-360*(keycode-0x30));
  44.     }
  45.     else if (keycode == 0x26)  //向上键,控制转动方向为正转
  46.     {
  47.         dirMotor = 0;
  48.     }
  49.     else if (keycode == 0x28)  //向下键,控制转动方向为反转
  50.     {
  51.         dirMotor = 1;
  52.     }
  53.     else if (keycode == 0x25)  //向左键,固定正转90度
  54.     {
  55.         StartMotor(90);
  56.     }
  57.     else if (keycode == 0x27)  //向右键,固定反转90度
  58.     {
  59.         StartMotor(-90);
  60.     }
  61.     else if (keycode == 0x1B)  //Esc键,停止转动
  62.     {
  63.         StopMotor();
  64.     }
  65. }
  66. /* 按键驱动函数,检测按键动作,调度相应动作函数,需在主循环中调用 */
  67. void KeyDriver()
  68. {
  69.     unsigned char i, j;
  70.     static unsigned char backup[4][4] = {  //按键值备份,保存前一次的值
  71.         {1, 1, 1, 1},  {1, 1, 1, 1},  {1, 1, 1, 1},  {1, 1, 1, 1}
  72.     };
  73.    
  74.     for (i=0; i<4; i++)  //循环检测4*4的矩阵按键
  75.     {
  76.         for (j=0; j<4; j++)
  77.         {
  78.             if (backup[i][j] != KeySta[i][j])    //检测按键动作
  79.             {
  80.                 if (backup[i][j] != 0)           //按键按下时执行动作
  81.                 {
  82.                     KeyAction(KeyCodeMap[i][j]); //调用按键动作函数
  83.                 }
  84.                 backup[i][j] = KeySta[i][j];     //刷新前一次的备份值
  85.             }
  86.         }
  87.     }
  88. }
  89. /* 电机转动控制函数 */
  90. void TurnMotor()
  91. {
  92.     unsigned char tmp;  //临时变量
  93.     static unsigned char index = 0;  //节拍输出索引
  94.     unsigned char code BeatCode[8] = {  //步进电机节拍对应的IO控制代码
  95.         0xE, 0xC, 0xD, 0x9, 0xB, 0x3, 0x7, 0x6
  96.     };
  97.    
  98.     if (beats != 0)  //节拍数不为0则产生一个驱动节拍
  99.     {
  100.         if (beats > 0)  //节拍数大于0时正转
  101.         {
  102.             index++;               //正转时节拍输出索引递增
  103.             index = index & 0x07;  //用&操作实现到8归零
  104.             beats--;               //正转时节拍计数递减
  105.         }
  106.         else            //节拍数小于0时反转
  107.         {
  108.             index--;               //反转时节拍输出索引递减
  109.             index = index & 0x07;  //用&操作同样可以实现到-1时归7
  110.             beats++;               //反转时节拍计数递增
  111.         }
  112.         tmp = P1;                    //用tmp把P1口当前值暂存
  113.         tmp = tmp & 0xF0;            //用&操作清零低4位
  114.         tmp = tmp | BeatCode[index]; //用|操作把节拍代码写到低4位
  115.         P1  = tmp;                   //把低4位的节拍代码和高4位的原值送回P1
  116.     }
  117.     else  //节拍数为0则关闭电机所有的相
  118.     {
  119.         P1 = P1 | 0x0F;
  120.     }
  121. }
  122. /* T0中断服务函数,用于按键扫描与电机转动控制 */
  123. void InterruptTimer0() interrupt 1
  124. {
  125.     static bit div = 0;
  126.    
  127.     TH0 = 0xFC;  //重新加载初值
  128.     TL0 = 0x67;
  129.     KeyScan();   //执行按键扫描
  130.     //用一个静态bit变量实现二分频,即2ms定时,用于控制电机
  131.     div = ~div;
  132.     if (div == 1)
  133.     {
  134.         TurnMotor();
  135.     }
  136. }
复制代码

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

使用道具 举报

沙发
ID:477932 发表于 2019-2-19 00:07 | 只看该作者
步进电机的程式很多,你那不叫脉冲,是占空比
回复

使用道具 举报

板凳
ID:164602 发表于 2019-2-19 08:57 | 只看该作者
步进电机有很多种吧,如:五线四相步进电机、四线双极性步进电机等等,你用的是哪种呢?不同的电机的控制信号不一样哦
回复

使用道具 举报

地板
ID:475888 发表于 2019-2-19 12:54 | 只看该作者
HC6800-ES-V2.0 发表于 2019-2-19 08:57
步进电机有很多种吧,如:五线四相步进电机、四线双极性步进电机等等,你用的是哪种呢?不同的电机的控制信 ...

四线二相的呢
回复

使用道具 举报

5#
ID:475888 发表于 2019-2-19 14:39 | 只看该作者
static 发表于 2019-2-19 00:07
步进电机的程式很多,你那不叫脉冲,是占空比

想学脉冲   然后转动一定角度的例程
回复

使用道具 举报

6#
ID:475888 发表于 2019-2-19 14:40 | 只看该作者
HC6800-ES-V2.0 发表于 2019-2-19 08:57
步进电机有很多种吧,如:五线四相步进电机、四线双极性步进电机等等,你用的是哪种呢?不同的电机的控制信 ...

大佬有脉冲 控制转动固定角度的51单片机例程参考吗
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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