【XR806开发板试用】跑个步进电机
-
从垃圾堆里翻出来个电机,今天就玩它好了,对于电机的理解已经全部还给了大学老师,所以打算先研究一番:
百度了一下,这个东西学名叫作四相五线步进电机,电机就是这个圆陀陀,板子是他的驱动器。板载芯片是ULN2003,TI出品。查了一下技术文档,就是一个集成的达令顿管放大器。
很早以前就了解过:步进电机是吃脉冲信号工作,转化信号成相应的角位移和线位移。输入一个脉冲信号,转子就转动一个角度或前进一步,其输出的角位移或线位移与输入的脉冲数成正比,转速与脉冲频率成正比。因此,步进电动机又称脉冲电动机。
步进电机相对于其它控制用途电机的最大区别是,它接收数字控制信号(电脉冲信号)并转化成与之相对应的角位移或直线位移。也就是说,它本身就可以把信号转化成运动。而且它可开环位置控制,输入一个脉冲信号就得到一个规定的位置增量,与传统的直流控制系统相比,其成本明显减低,几乎不必进行系统调整。所以他给我们带来了很大的方便。要是想要他执行起来也很简单,只要控制脉冲的数量、频率和电机绕组的相序,即可获得所需的转角、速度和方向。
从具体的硬件来看,我这里需要接六条线才能让这个电机跑起来,电源端口就不说了,IN1~IN4这四个通道口要怎么输入信号才是问题所在。
如上就是内部原理图,右侧四个开关其实就是我们的四个信号端口。右侧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连接上驱动板后,通上电,电机就正常工作了。
当然光转起来有些过于简单了,所以打算加一些可控元素进去,也方便后面做各种开发。于是又从垃圾堆里翻到了这个:
用翻出来的示波器研究了一下(没有万用表555),可以理解为由上下、左右两个方向的滑动变阻器和一个按键组成,总共三个信号输出口。保持在中间位置的时候测得是2.5v,移动向两边就是0跟5v,按下就是按钮。
既然是输出模拟信号最合理就是用ADC检测,无奈鸿蒙1.x.x的版本貌似都还没适配好806的接口,hal库的代码也找不到说明文档,用hal库尝试配置了一下ADC一直没成功,只能放到后面解决了。。。
所以最终决定还是用GPIO接口去读电平高低,具体代码如下:
#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);
看看效果:
至于为什么要顶个风扇叶呢,一方面是方便观察转动,另一方面也算是致敬一张大部分程序员应该都见过的图:
ok,又水了一贴,今天也是平安夜,祝各位圣诞快乐!
也挖个坑:下周会整合一下前面的内容做个小作品放出来。Merry Christmas!
-
圣诞快到了,能不能从垃圾堆里翻个女朋友陪我过节[doge]
-
@killer_p 元旦到了可能也翻不出来
-
大佬,能把你下载的源码,传我一份吗,我这编译一直通不过
-
@shan_ 你可以把你的报错信息全部贴出来吗?
Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号