17、28BYJ-48 电机驱动

什么,学完了pinctrl子系统和GPIO子系统还只会点灯?
今天就来个高级点的点灯

这个电机驱动程序说白了就是 点灯

1、28BYJ-48 电机是四相八拍电机,所以需要4个GPIO来控制

简介:

28:步进电机的有效最大外径是28毫米

B:表示是步进电机

Y:表示是永磁式

J:表示是减速型(减速比1:64)

48:表示四相八拍

内部结构示意图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qYxCbNM4-1619338578619)(linux%E9%A9%B1%E5%8A%A8.assets/image-20210331103907659.png)]

1、相数:是指产生不同对极N、S磁场的激磁线圈对数。常用m表示 例如上图 有四对线圈 A、B、C、D

2、拍数:完成一个磁场周期性变化所需脉冲数,以四相电机为例,

​ 有单相四拍运行方式即A-B-C-D,

​ 有双相四拍运行方式即AB-BC-CD-DA

​ 有四相八拍运行方式即A-AB-B-BC-C-CD-D-DA

3、步进角:

​ 步进电机的定子绕组每改变一次通电状态,转子转过的角度称步进角。

转子磁极数越多,步进角 越小

定子相数越多,步进角越小

通电方式节拍越多,步进角越小

例如 八拍模式下 360/(4 * 8 * 2) = 5.625

​ 关于启动频率,也就是pps 这里间隔时间最好是大于1200us

与开发板的管脚连接

第一步 在pinctrl子系统中,对这几个管脚进行配置

exynos4412-pinctrl.dtsi 文件中

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5tk1Be60-1619338578629)(linux%E9%A9%B1%E5%8A%A8.assets/image-20210420154940506.png)]

     mymoter: mymoter {samsung,pins = "gpj0-3", "gpj0-4", "gpj0-5", "gpj0-6";samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>; //设置为输出模式samsung,pin-val = <0x0>;  //默认输出低电平//  samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;};

2、第二步 在根节点下添加MOTOR节点

exynos4412-itop-elite.dts 文件中 在根节点中添加节点

 /*motor*/my_motor:my_motor{compatible = "motor";         //描述pinctrl-names = "default";       pinctrl-0 = <&mymotor>;      status = "okay"/*GPIO管脚  "gpj0-3", "gpj0-4", "gpj0-5", "gpj0-6";*/motorA-gpios = <&gpj0 3 GPIO_ACTIVE_HIGH>;  //GPJ0_3 GPIO_ACTIVE_HIGH 表示高电平有效motorB-gpios = <&gpj0 4 GPIO_ACTIVE_HIGH>;motorC-gpios = <&gpj0 5 GPIO_ACTIVE_HIGH>;motorD-gpios = <&gpj0 6 GPIO_ACTIVE_HIGH>;}

3、 编写driver程序

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/device.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/cdev.h>#include <linux/pinctrl/consumer.h>
#include <dt-bindings/pinctrl/samsung.h>#include <linux/of_gpio.h>/*  字符设备框架1、注册 platform driver2、构建file_operations3、获取硬件资源4、注册字符设备驱动4、生成字符设备节点
*/
/*  定义各个管脚的命令
*/
#define MOTOR_CMD_A _IOW('M',0,long)
#define MOTOR_CMD_B _IOW('M',1,long)
#define MOTOR_CMD_C _IOW('M',2,long)
#define MOTOR_CMD_D _IOW('M',3,long)struct device *device_cdev;
struct class *class_cdev;int GPIO_ID_A;
int GPIO_ID_B;
int GPIO_ID_C;
int GPIO_ID_D;int motor_open(struct inode *inode, struct file *file)
{printk("open is success!\n");return 0;
}
int motor_release (struct inode *inode, struct file *file)
{printk("release is success!\n");return 0;
}
long motor_ioctrl(struct file *file, unsigned int cmd, unsigned long value)
{switch(cmd){case MOTOR_CMD_A:gpio_set_value(GPIO_ID_A, value);break;case MOTOR_CMD_B:gpio_set_value(GPIO_ID_B, value);break;     case MOTOR_CMD_C:gpio_set_value(GPIO_ID_C, value);break;case MOTOR_CMD_D:gpio_set_value(GPIO_ID_D, value);break;}
}/*2、获取硬件资源 */
int motor_probe(struct platform_device *pdev)
{int ret;/*1、获取GPIO号*/GPIO_ID_A = of_get_named_gpio(pdev->dev.of_node, "motorA-gpios", 0);//index=0 ,因为在设备树中只引用了一个if (GPIO_ID_A < 0){printk("of get named gpio is error!\n");return -1;}GPIO_ID_B = of_get_named_gpio(pdev->dev.of_node, "motorB-gpios", 0);//index=0 ,因为在设备树中只引用了一个if (GPIO_ID_B < 0){printk("of get named gpio is error!\n");return -1;}GPIO_ID_C = of_get_named_gpio(pdev->dev.of_node, "motorC-gpios", 0);//index=0 ,因为在设备树中只引用了一个if (GPIO_ID_C< 0){printk("of get named gpio is error!\n");return -1;}GPIO_ID_D = of_get_named_gpio(pdev->dev.of_node, "motorD-gpios", 0);//index=0 ,因为在设备树中只引用了一个if (GPIO_ID_D< 0){printk("of get named gpio is error!\n");return -1;}/*2、申请一个GPIO管脚*/ret = gpio_request(GPIO_ID_A, "motor_A_GPIO");if (ret != 0){printk("gpio request is error!\n");return -1;}ret = gpio_request(GPIO_ID_B, "motor_B_GPIO");if (ret != 0){printk("gpio request is error!\n");return -1;}ret = gpio_request(GPIO_ID_C, "motor_C_GPIO");if (ret != 0){printk("gpio request is error!\n");return -1;}ret = gpio_request(GPIO_ID_D, "motor_D_GPIO");if (ret != 0){printk("gpio request is error!\n");return -1;}/*3、 将管脚设置为输出*//* 这里先不设置,因为在pinctrl复用中已经将管脚设置为了OUTPUT*/return 0;
}
int motor_remove(struct platform_device *pdev)
{return 0;
}struct of_device_id of_match_table = {      // 与设备树节点进行匹配.compatible = "motor"
};/*1、初始化platform driver*/
struct platform_driver pdev = {.probe = motor_probe,          // 与 of_match_table 匹配成功后进入probe函数获取硬件资源.remove = motor_remove,.driver = {.name = "motor",     //无设备树时 使用.name 与device进行匹配.owner = THIS_MODULE,.of_match_table = &of_match_table,}
};
//3、注册字符设备驱动
/*3.1 分配设备号*/
dev_t dev_number;
/*3.2 定义cdev*/
struct cdev cdev_;/*3.3 构建file_operation结构体*/
struct file_operations fop = {.owner = THIS_MODULE,.open    = motor_open,.release = motor_release,.unlocked_ioctl = motor_ioctrl
};
static int char_driver_init(void)
{/*1、注册platform driver*/int ret = platform_driver_register(&pdev);if (0 != ret){   printk("platform driver register is error!\n");return -1;}/*3.1 分配设备号(动态分配设备号)*/ret = alloc_chrdev_region(&dev_number, 0, 1, "my_motor");if (0 != ret){printk("alloc chrdev region is error!\n");return ret;}/*3.4 初始化cdev*/cdev_.owner = THIS_MODULE;cdev_init(&cdev_, &fop);/*3.5 注册字符设备到内核*/ret = cdev_add(&cdev_, dev_number, 1);if (0 != ret){printk("cdev add is error!\n");return -1;}/*4、生成设备节点*//*4.1 创建字符设备类*/class_cdev =  class_create(THIS_MODULE, "motor");if (NULL == class_cdev){printk("class create is error!\n");return -1;}/*生成设备节点*/device_cdev = device_create (class_cdev, NULL, dev_number, NULL,  "my_motor");if (NULL == device_cdev){printk("device create is error!\n");}return 0;
};static void char_driver_exit(void)
{gpio_free(GPIO_ID_A);  gpio_free(GPIO_ID_B);    gpio_free(GPIO_ID_C);    gpio_free(GPIO_ID_D);    //释放GPIOdevice_destroy(class_cdev, dev_number); // 卸载设备节点class_destroy(class_cdev);              //卸载设备类cdev_del(&cdev_);                       //卸载cdev//   iounmap(led_con);                       // 取消地址映射//   iounmap(led_dat);                   unregister_chrdev_region(dev_number, 1);// 注销设备号 platform_driver_unregister(&pdev);       // 注销platform driver}module_init(char_driver_init);
module_exit(char_driver_exit);
MODULE_LICENSE("GPL");

4、应用程序

#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>#include <sys/ioctl.h>
#define MOTOR_DEV "/dev/my_motor"/* 一个节拍 转动 5.625*/#define MOTOR_CMD_A _IOW('M',0,long)
#define MOTOR_CMD_B _IOW('M',1,long)
#define MOTOR_CMD_C _IOW('M',2,long)
#define MOTOR_CMD_D _IOW('M',3,long)#define HIGH 1
#define LOW 0#define NUMBER 10000
#define SPEED 1500
//SPEED 越小转速越快
int fd;
int motor_off(void)
{ioctl(fd, MOTOR_CMD_A, LOW);ioctl(fd, MOTOR_CMD_B, LOW);ioctl(fd, MOTOR_CMD_C, LOW);ioctl(fd, MOTOR_CMD_D, LOW);}
static int meter_turn(int n)
{switch(n){case 0:ioctl(fd, MOTOR_CMD_A, LOW);ioctl(fd, MOTOR_CMD_B, HIGH);ioctl(fd, MOTOR_CMD_C, HIGH);ioctl(fd, MOTOR_CMD_D, HIGH);break;case 1:ioctl(fd, MOTOR_CMD_A, LOW);ioctl(fd, MOTOR_CMD_B, LOW);ioctl(fd, MOTOR_CMD_C, HIGH);ioctl(fd, MOTOR_CMD_D, HIGH);break;case 2:ioctl(fd, MOTOR_CMD_A, HIGH);ioctl(fd, MOTOR_CMD_B, LOW);ioctl(fd, MOTOR_CMD_C, HIGH);ioctl(fd, MOTOR_CMD_D, HIGH);break;case 3:ioctl(fd, MOTOR_CMD_A, HIGH);ioctl(fd, MOTOR_CMD_B, LOW);ioctl(fd, MOTOR_CMD_C, LOW);ioctl(fd, MOTOR_CMD_D, HIGH);break;case 4:ioctl(fd, MOTOR_CMD_A, HIGH);ioctl(fd, MOTOR_CMD_B, HIGH);ioctl(fd, MOTOR_CMD_C, LOW);ioctl(fd, MOTOR_CMD_D, HIGH);break;case 5:ioctl(fd, MOTOR_CMD_A, HIGH);ioctl(fd, MOTOR_CMD_B, HIGH);ioctl(fd, MOTOR_CMD_C, LOW);ioctl(fd, MOTOR_CMD_D, LOW);break;case 6:ioctl(fd, MOTOR_CMD_A, HIGH);ioctl(fd, MOTOR_CMD_B, HIGH);ioctl(fd, MOTOR_CMD_C, HIGH);ioctl(fd, MOTOR_CMD_D, LOW);break;case 7:ioctl(fd, MOTOR_CMD_A, LOW);ioctl(fd, MOTOR_CMD_B, HIGH);ioctl(fd, MOTOR_CMD_C, HIGH);ioctl(fd, MOTOR_CMD_D, LOW);break;}return 0;
}void motor_direction(const char direction, int number)
{int i ;int step ;if (direction == 'R')step = -1;elsestep = 8;for (i = 0; i < number; i++){if (direction == 'R'){step++;if (step > 7)step = 0;}else {if (step == 0)step = 8;step--;}meter_turn(step);usleep(SPEED);}}
int main(int argc, char * argv[])
{fd = open(MOTOR_DEV, O_RDWR);if (-1 == fd){perror("open");return -1;}printf("open success!\n");motor_direction('L', NUMBER);motor_off();return 0;
}

28BYJ-48 电机驱动(Linux)相关推荐

  1. Linux学习总结(48)——Linux防火墙iptables与firewalld学习总结

    iptables命令是Linux上常用的防火墙软件,是netfilter项目的一部分.可以直接配置,也可以通过许多前端和图形界面配置. 语法 iptables(选项)(参数) 选项 -t<表&g ...

  2. 2009-07-03 19:48 在linux中如何获得微秒精度的时间?-转

    ※使用C的<time.h>库函数是无法达到微秒级别的时间的,所以上网找了一下答案,原文如下: ------------------------ 使用C语言进行计时,在用户空间中可以使用C语 ...

  3. 48、Linux共享内存传递cv::Mat

    基本思想:最近在研究RoboMater源码,学习了如何使用共享内存传递cv::Mat 所以记录一下: send.cpp 读取了一张576*768*3通道的图片 #include <iostrea ...

  4. Linux期末复习题库(1)

    [试题分类]: 1.下列哪种说法是错误的( ) . A.操作系统是裸机之上的第一层软件 B.操作系统控制和管理全部的计算机资源 C.Microsoft Office 是操作系统的一种 D.操作系统应为 ...

  5. linux相关面试题总结!

    选择题 1 在终端下输入mount -a命令的作用是:C A 强制进行磁盘检查 B 显示当前挂载的所有磁盘分区的信息 C 挂载/etc/fstab文件中的除noauto以外的所有磁盘分区 D 以只读方 ...

  6. linux软件安装非系统盘,linux操作系统可不可以像安装windows软件一样在windows系统下的硬盘上安装...

    linux操作系统可不可以像安装windows软件一样在windows系统下的硬盘上安装 答案:2  信息版本:手机版 解决时间 2020-07-24 14:13 已解决 2020-07-23 16: ...

  7. linux下被遗忘的gpio_keys按键驱动

    我们新项目硬件设计上使用gpio口做按键,所以我就需要搞定这个驱动,本来想自己写一个gpio口的按键驱动,然后看了下内核下面的代码,已经有现成的了.Linux内核下游很多很多的现成驱动,只要你想得到的 ...

  8. RPM方式安装MySQL5.5.48 (Aliyun CentOS 7.0 卸载MySQL5.7)

    环境是阿里云的CentOS7.0,更新了yum源(更新yum源请参考https://help.aliyun.com/knowledge_detail/5974184.html)之后先是尝试安装了MyS ...

  9. 【备忘】linux视频

    参考笔记 内部参考脚本 [M哥linux-多年内部积累电子书-无价之宝]Books7  01.M哥亲讲Linux运维发展与学习路线图.mp4 02.Linux云计算学习环境介绍.mp4 03.Linu ...

最新文章

  1. (转)有关Android线程的学习
  2. 测试集的构成比例对网络分类性能的影响cp
  3. SpringBoot配置嵌入式Servlet容器
  4. 梅森增益matlab求解,梅森公式互不接触回路及其增益
  5. oracle分区和锁的难,oracle使用三(锁和表分区)
  6. 《笑傲网湖》第二回 VLAN
  7. python 把list中的所有元素串起来变为字符串
  8. 2020年下系统集成项目管理工程师真题基础知识+解析1/3
  9. 深度学习:文本CNN-textcnn
  10. 什么是0day漏洞?
  11. java 获取本机地址_java如何获取本机IP地址
  12. 关于英语论文范文参考步骤的详细介绍
  13. 叉积的证明_矢量叉乘分配律的几何证明
  14. Tesla M40 下Ubuntu anaconda pycharm pytorch安装
  15. 华师大计算机基础在线作业,华东师范大学计算机作业答案
  16. Chino with Rewrite
  17. ubuntu home目录下的主用户目录被删处理
  18. 自己搭建的三相永磁同步电机直接转矩控制(DTC)模型
  19. 打印100-200以内的素数
  20. PAT(B) 1044 火星数字(Java)进制转换

热门文章

  1. Android ijkplayer播放rtsp直播流
  2. 通过在线制图工具绘制阿里云部署图
  3. python多个箱线图_python-matplotlib | 箱线图及解读
  4. Linux文件系统与持久性内存介绍:块设备、闪存(NAND/NOR)、NVDIMM(非易失性内存)、PMEM(PMDK)- ndctl
  5. B: 火车站(stack)
  6. 天地水火雷风山泽 乾坤坎离震巽艮兑
  7. 通过Windows防火墙禁止某程序(或软件)联网
  8. Django企业开发实战--by胡阳,学习记录1127
  9. easy-mock使用
  10. 精彩回顾|展会圆满收官,落幕不散场,期待与您的再次相遇,下一站上海!