Navigation

    全志在线开发者论坛

    • Register
    • Login
    • Search
    • Categories
    • Tags
    • 在线文档
    • 社区主页

    【XR806开发板试用】跑个步进电机

    Wireless & Analog Series
    3
    5
    2508
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Randolph
      Randolph LV 6 last edited by Randolph

      从垃圾堆里翻出来个电机,今天就玩它好了,对于电机的理解已经全部还给了大学老师,所以打算先研究一番:5b19c10f-294f-4028-864a-8308c7fa7f37-image.png

      百度了一下,这个东西学名叫作四相五线步进电机,电机就是这个圆陀陀,板子是他的驱动器。板载芯片是ULN2003,TI出品。查了一下技术文档,就是一个集成的达令顿管放大器。

      很早以前就了解过:步进电机是吃脉冲信号工作,转化信号成相应的角位移和线位移。输入一个脉冲信号,转子就转动一个角度或前进一步,其输出的角位移或线位移与输入的脉冲数成正比,转速与脉冲频率成正比。因此,步进电动机又称脉冲电动机。

      步进电机相对于其它控制用途电机的最大区别是,它接收数字控制信号(电脉冲信号)并转化成与之相对应的角位移或直线位移。也就是说,它本身就可以把信号转化成运动。而且它可开环位置控制,输入一个脉冲信号就得到一个规定的位置增量,与传统的直流控制系统相比,其成本明显减低,几乎不必进行系统调整。所以他给我们带来了很大的方便。要是想要他执行起来也很简单,只要控制脉冲的数量、频率和电机绕组的相序,即可获得所需的转角、速度和方向。

      从具体的硬件来看,我这里需要接六条线才能让这个电机跑起来,电源端口就不说了,IN1~IN4这四个通道口要怎么输入信号才是问题所在。ea157a3d-a0ef-4d51-bb5d-987677717467-image.png

      如上就是内部原理图,右侧四个开关其实就是我们的四个信号端口。右侧ABCD为定子,上面绕有线圈,为四相,与之相对应的对面四个定子上面也有线圈,相对应的两个定子之间线圈是相互连接形成一个绕组。

      下面来分析一种运行模式,单四拍运行:假如说现在我闭合0对着的那个开关,则由高中学过的电能生磁原理,0对应的线圈就会产生磁力,同时他的下端,也就是对应的B线圈,也就一起导通了。接下来B断开,C导通产生磁力,1和C(这里指的是右上角那个端)就会因为两者间夹角最小而互相吸引靠近,吸引过去后C断开,D通电,继续把离他最近的2吸引过去,如此一来类推下去就形成了一个逆时针旋转的过程。

      上述过程直到0被吸引到A相时,就是一个周期的完成,旋转角度为360/8=45度。

      还有其他控制方法,如双拍工作、单双拍工作等等,可以根据需求调节精度速度等等···决定先放一边,适当做点容易让人有成就感的事情:用代码实现这个过程,把舵机跑起来。

      了解了原理就用最简单的方法去实现好了。主要代码如下:

      			IoTGpioSetOutputVal(12,0);
      	IoTGpioSetOutputVal(13,0);
      	IoTGpioSetOutputVal(19,1);
      	IoTGpioSetOutputVal(20,1);
      	OS_MSleep(2);
      		IoTGpioSetOutputVal(12,1);
      	IoTGpioSetOutputVal(13,0);
      	IoTGpioSetOutputVal(19,0);
      	IoTGpioSetOutputVal(20,1);
      	OS_MSleep(2);
      		IoTGpioSetOutputVal(12,1);
      	IoTGpioSetOutputVal(13,1);
      	IoTGpioSetOutputVal(19,0);
      	IoTGpioSetOutputVal(20,0);
      	OS_MSleep(2);
      		IoTGpioSetOutputVal(12,0);
      	IoTGpioSetOutputVal(13,1);
      	IoTGpioSetOutputVal(19,1);
      	IoTGpioSetOutputVal(20,0);
      	OS_MSleep(2);
      

      像前面几篇一样,烧录程序,将对应IO连接上驱动板后,通上电,电机就正常工作了。

      当然光转起来有些过于简单了,所以打算加一些可控元素进去,也方便后面做各种开发。于是又从垃圾堆里翻到了这个:feb33d98-ecf3-452a-ae1b-09a3057012df-image.png

      用翻出来的示波器研究了一下(没有万用表555),可以理解为由上下、左右两个方向的滑动变阻器和一个按键组成,总共三个信号输出口。保持在中间位置的时候测得是2.5v,移动向两边就是0跟5v,按下就是按钮。
      e0e7bea0-44e0-40ee-b3fd-a48b98e5a05d-image.png

      既然是输出模拟信号最合理就是用ADC检测,无奈鸿蒙1.x.x的版本貌似都还没适配好806的接口,hal库的代码也找不到说明文档,用hal库尝试配置了一下ADC一直没成功,只能放到后面解决了。。。

      所以最终决定还是用GPIO接口去读电平高低,具体代码如下:

      BUILD.gn

      #Create by Randolph.
      
      
      import("//device/xradio/xr806/liteos_m/config.gni")
      
      static_library("app_Stepper") 
      {
         configs = []
      
         sources = ["main.c",]
      
         cflags = board_cflags
      
         include_dirs = board_include_dirs
         include_dirs += [
            "//kernel/liteos_m/kernel/arch/include",
            "//base/iot_hardware/peripheral/interfaces/kits",
                  "//device/xradio/xr806/xr_skylark/src/rom/rom_bin/src/driver",
         ]
      }
      
      

      main.c

      //Create by Randolph
      
      #include <stdio.h>
      #include "kernel/os/os.h"
      #include "ohos_init.h"
      #include "iot_gpio.h"
      
      
      static OS_Thread_t g_main_thread;
      
      unsigned char mode;
      
      static void gpio_init(void)
      {
      	IoTGpioInit(11);
      	IoTGpioInit(12);
      	IoTGpioInit(13);
      	IoTGpioInit(19);
      	IoTGpioInit(20);
      	IotGpioDir dir;
      			IoTGpioSetDir(11, IOT_GPIO_DIR_IN);
      	IoTGpioGetDir(11, &dir);
      		IoTGpioSetDir(12, IOT_GPIO_DIR_OUT);
      		IoTGpioSetDir(13, IOT_GPIO_DIR_OUT);
      		IoTGpioSetDir(19, IOT_GPIO_DIR_OUT);
      		IoTGpioSetDir(20, IOT_GPIO_DIR_OUT);
      }
      
      static void Servo_mode(unsigned char mode)
      {
      	if (mode == 1)
      	{
      			IoTGpioSetOutputVal(12,0);
      	IoTGpioSetOutputVal(13,0);
      	IoTGpioSetOutputVal(19,1);
      	IoTGpioSetOutputVal(20,1);
      	OS_MSleep(2);
      		IoTGpioSetOutputVal(12,1);
      	IoTGpioSetOutputVal(13,0);
      	IoTGpioSetOutputVal(19,0);
      	IoTGpioSetOutputVal(20,1);
      	OS_MSleep(2);
      		IoTGpioSetOutputVal(12,1);
      	IoTGpioSetOutputVal(13,1);
      	IoTGpioSetOutputVal(19,0);
      	IoTGpioSetOutputVal(20,0);
      	OS_MSleep(2);
      		IoTGpioSetOutputVal(12,0);
      	IoTGpioSetOutputVal(13,1);
      	IoTGpioSetOutputVal(19,1);
      	IoTGpioSetOutputVal(20,0);
      	OS_MSleep(2);
      	}
      	else if (mode == 0)
      	{
      		IoTGpioSetOutputVal(12,0);
      	IoTGpioSetOutputVal(13,1);
      	IoTGpioSetOutputVal(19,1);
      	IoTGpioSetOutputVal(20,0);
      	OS_MSleep(2);	
      		IoTGpioSetOutputVal(12,1);
      	IoTGpioSetOutputVal(13,1);
      	IoTGpioSetOutputVal(19,0);
      	IoTGpioSetOutputVal(20,0);
      	OS_MSleep(2);
      		IoTGpioSetOutputVal(12,1);
      	IoTGpioSetOutputVal(13,0);
      	IoTGpioSetOutputVal(19,0);
      	IoTGpioSetOutputVal(20,1);
      	OS_MSleep(2);	
      			IoTGpioSetOutputVal(12,0);
      	IoTGpioSetOutputVal(13,0);
      	IoTGpioSetOutputVal(19,1);
      	IoTGpioSetOutputVal(20,1);
      	OS_MSleep(2);
      	}
      }
      
      static void MainThread(void *arg)
      {   
      	while (1) {
      		IoTGpioGetInputVal(11,&mode);
      		Servo_mode(mode);
      	}
      }
      
      void Stepper_TestMain(void)
      {
      	printf("Test Start\n");
          gpio_init();
      
      	if (OS_ThreadCreate(&g_main_thread,"MainThread",MainThread, NULL, OS_THREAD_PRIO_APP, 4096) != OS_OK) 
      	{
      		printf("[ERR] Create HelloWorld_Task Failed\n");
      	}
      }
      
      SYS_RUN(Stepper_TestMain);
      

      看看效果:

      至于为什么要顶个风扇叶呢,一方面是方便观察转动,另一方面也算是致敬一张大部分程序员应该都见过的图:
      a14f694a-e6b5-48c4-aee3-83a67705bf28-image.png

      ok,又水了一贴,今天也是平安夜,祝各位圣诞快乐!
      也挖个坑:下周会整合一下前面的内容做个小作品放出来。

      Merry Christmas!

      1 Reply Last reply Reply Quote Share 2
      • K
        killer_p LV 3 last edited by

        圣诞快到了,能不能从垃圾堆里翻个女朋友陪我过节[doge]

        Randolph 1 Reply Last reply Reply Quote Share 0
        • Randolph
          Randolph LV 6 @killer_p last edited by Randolph

          @killer_p 元旦到了可能也翻不出来🙄

          1 Reply Last reply Reply Quote Share 0
          • S
            shan_ LV 2 last edited by

            大佬,能把你下载的源码,传我一份吗,我这编译一直通不过
            75cd0d1c-2d8f-4240-9dd9-cca1a08755b3-图片.png

            Randolph 1 Reply Last reply Reply Quote Share 0
            • Randolph
              Randolph LV 6 @shan_ last edited by

              @shan_ 你可以把你的报错信息全部贴出来吗?

              1 Reply Last reply Reply Quote Share 0
              • 1 / 1
              • First post
                Last post

              Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号

              行为准则 | 用户协议 | 隐私权政策