本人从0开始学习linux,使用的是韦东山的教程,在跟着课程学习的情况下的所遇到的问题的总结,理论虽枯燥但是是基础。本人将前几章的内容大致学完之后,考虑到后续驱动方面得更多的开始实操,后续的内容将以韦东山教程Linux驱动入门实验班的内容为主,学习其中的代码并手敲。做到锻炼动手能力的同时钻研其中的理论知识点。
摘要:这篇文档主要介绍的是步进电机的控制,其实步进电机就是引脚的高低电平控制,所以没有特别深入的内容,此章节较短。
摘要关键词:步进电机驱动

本文详细介绍以下问题,如果你遇到了以下问题,看看我的方案能否解决。

步进电机

1.引脚配置

1.原理图参考引脚设置

1.引脚对应原理图
由于本人没有买他的拓展板,只好看原理图来找引脚的分布,然后发现原理图对不上只能看封装图。
在这里插入图片描述
想着确定图片中红色框的引脚位置,找半天没找着j5,说实在的原理图画的有点不好。
在这里插入图片描述
这部分也是自己采购的模块,使用的引脚和它一样的,使用的是GPIO4_19、20、21、22。
其实这个章节没有什么很难的地方,就是输入高低电平控制引脚。

在这里插入图片描述
本人使用的步进电机驱动模块如图所示。IN1,IN2,IN3,IN4也就是连接对应的GPIO引脚。步进电机有防呆接口直接连接就行。注意跳帽不用拔。
输入以下命令行即可。

make clean
bear make
ctrl+h
arm-buildroot-linux-gnueabihf-gcc  编译设置
make
adb push gpio_drv.ko button_test root

越到后面代码没有啥好讲解的了,更多的是引脚功能配置和逻辑了

驱动代码

#include <linux/module.h>
#include <linux/poll.h>#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>
#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/slab.h>
#include <linux/fcntl.h>
#include <linux/timer.h>
#include <linux/delay.h>
struct gpio_desc{int gpio;char *name;} ;static struct gpio_desc gpios[] = {{115, "motor_gpio0", },{116, "motor_gpio1", },{117, "motor_gpio2", },{118, "motor_gpio3", },
};/* 主设备号                                                                 */
static int major = 0;
static struct class *gpio_class;/* int buf[2];
*  buf[0] = 步进的次数,》0:逆时针;《 0:顺时针
*  buf[1] = mdelay的时间
*/
// 马达引脚设置数组
static int g_motor_pin_ctrl[8] = {0x2,0x3,0x1,0x9,0x8,0xc,0x4,0x6};
static int g_motor_index = 0;void set_pin_for_motor(int index)
{int i ;for(i = 0;i < 4;i++){gpio_set_value(gpios[i].gpio,g_motor_pin_ctrl[index] & (1<<i) ? 1:0);}
}
static ssize_t motor_drv_write(struct file *file, const char __user *buf, size_t size, loff_t *offset)
{int ker_buf[2];int err;int step;if (size != 8)return -EINVAL;err = copy_from_user(ker_buf, buf, size);if (ker_buf[0] > 0){/*逆时针旋转*/for(step = 0;step<ker_buf[0];step++){set_pin_for_motor(g_motor_index);mdelay(ker_buf[1]);g_motor_index--;if(g_motor_index == -1)g_motor_index = 7 ;}}else{ker_buf[0] = 0 - ker_buf[0];/*顺时针旋转*/for(step = 0;step<ker_buf[0];step++){set_pin_for_motor(g_motor_index);mdelay(ker_buf[1]);g_motor_index ++;if(g_motor_index == 8)g_motor_index = 0 ;}}return 2;    
}/* 定义自己的file_operations结构体                                              */
static struct file_operations gpio_key_drv = {.owner	 = THIS_MODULE,.write   = motor_drv_write,};/* 在入口函数 */
static int __init motor_drv_init(void)
{int err;int i;int count = sizeof(gpios)/sizeof(gpios[0]);printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);for (i = 0; i < count; i++){		err = gpio_request(gpios[i].gpio,gpios[i].name);gpio_direction_output(gpios[i].gpio,0);}/* 注册file_operations 	*/major = register_chrdev(0, "100ask_gpio_key", &gpio_key_drv);  /* /dev/gpio_desc */gpio_class = class_create(THIS_MODULE, "100ask_gpio_key_class");if (IS_ERR(gpio_class)) {printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);unregister_chrdev(major, "100ask_gpio_key");return PTR_ERR(gpio_class);}device_create(gpio_class, NULL, MKDEV(major, 0), NULL, "motor"); /* /dev/motor */return err;
}/* 有入口函数就应该有出口函数:卸载驱动程序时,就会去调用这个出口函数*/
static void __exit motor_drv_exit(void)
{int i;int count = sizeof(gpios)/sizeof(gpios[0]);printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);device_destroy(gpio_class, MKDEV(major, 0));class_destroy(gpio_class);unregister_chrdev(major, "100ask_gpio_key");for (i = 0; i < count; i++){gpio_free(gpios[i].gpio);}
}/* 7. 其他完善:提供设备信息,自动创建设备节点                                     */module_init(motor_drv_init);
module_exit(motor_drv_exit);MODULE_LICENSE("GPL");

应用程序代码


#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <poll.h>
#include <signal.h>
#include <stdlib.h>static int fd;/** ./button_test /dev/motor -100  1**/
int main(int argc, char **argv)
{int buf[2];int ret;/* 1. 判断参数 */if (argc != 4) {printf("Usage: %s <dev> <step_number> <mdelay_number>\n", argv[0]);return -1;}/* 2. 打开文件 */fd = open(argv[1], O_RDWR | O_NONBLOCK);if (fd == -1){printf("can not open file %s\n", argv[1]);return -1;}buf[0] = strtol(argv[2], NULL, 0);buf[1] = strtol(argv[3], NULL, 0);ret = write(fd, buf, 8);close(fd);return 0;
}
rmmod gpio_drv.ko
[root@100ask:~]# insmod gpio_drv.ko
[root@100ask:~]# ./button_test /dev/motor 100 1 
[root@100ask:~]# ./button_test /dev/motor 100 1 
[root@100ask:~]# ./button_test /dev/motor 100 1

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/90925.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/90925.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/90925.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高性能反向代理与负载均衡 HAProxy 与 Nginx

在现代高并发 Web 架构中&#xff0c;HAProxy 和 Nginx 是两个非常重要的工具。它们在反向代理、负载均衡、SSL 终止、缓存、限流等方面发挥着关键作用。 一、HAProxy 与 Nginx 简介 1. HAProxy 简介 HAProxy&#xff08;High Availability Proxy&#xff09; 是一个使用 C …

AI安全“面壁计划”:我们如何对抗算法时代的“智子”封锁?

> 在算法窥视一切的今天,人类需要一场数字世界的“面壁计划” 2025年,某医院部署的AI分诊系统被发现存在严重偏见:当输入相同症状时,系统为白人患者分配急诊通道的概率是黑人患者的**1.7倍**。调查发现,训练数据中少数族裔样本不足**15%**,导致AI在“认知”上形成了结…

数据库数据恢复—报错“system01.dbf需要更多的恢复来保持一致性”的Oracle数据恢复案例

Oracle数据库故障&#xff1a; 某公司一台服务器上部署Oracle数据库。服务器意外断电导致数据库报错&#xff0c;报错内容为“system01.dbf需要更多的恢复来保持一致性”。该Oracle数据库没有备份&#xff0c;仅有一些断断续续的归档日志。Oracle数据库恢复流程&#xff1a; 1、…

Spring Cloud Gateway 服务网关

Spring Cloud Gateway是 Spring Cloud 生态系统中的一个 API 网关服务&#xff0c;用于替换由Zuul开发的网关服务&#xff0c;基于Spring 5.0Spring Boot 2.0WebFlux等技术开发&#xff0c;提供了网关的基本功能&#xff0c;例如安全、监控、埋点和限流等&#xff0c;旨在为微服…

[数据结构]#6 树

树是一种非线性的数据结构&#xff0c;它由节点组成&#xff0c;并且这些节点之间通过边连接。树的每个节点可以有一个或多个子节点&#xff0c;并且有一个特殊的节点叫做根节点&#xff08;没有父节点&#xff09;。树在计算机科学中应用广泛&#xff0c;尤其是在数据库索引、…

车辆网络安全规定之R155与ISO/SAE 21434

随着科技的不断进步&#xff0c;车辆已经从传统的机械装置演变为高度智能化的移动终端。现代汽车不仅配备了先进的驾驶辅助系统&#xff08;ADAS&#xff09;、车载信息娱乐系统&#xff08;IVI&#xff09;&#xff0c;还具备联网功能&#xff0c;能够实现远程诊断、自动驾驶、…

Go语言实战案例-合并多个文本文件为一个

以下是《Go语言100个实战案例》中的 文件与IO操作篇 - 案例21&#xff1a;合并多个文本文件为一个 的完整内容&#xff0c;适用于初学者学习文件读取与写入的综合运用。&#x1f3af; 案例目标使用 Go 语言将指定目录下的多个 .txt 文件&#xff0c;合并成一个新的总文件。&…

基坑渗压数据不准?选对渗压计能实现自动化精准监测吗?

一、渗压监测的背景 渗压计是一种专门用于测量构筑物内部孔隙水压力或渗透压力的传感器&#xff0c;适用于长期埋设在水工结构物或其它混凝土结构物及土体内&#xff0c;以测量结构物或土体内部的渗透&#xff08;孔隙&#xff09;水压力。 在水利工程中&#xff0c;大坝、水库…

Linux网络:阿里云轻量级应用服务器配置防火墙模板开放端口

1.问题介绍在使用Udp协议或其他协议进行两台主机或同一台主机通信时&#xff0c;常常会出现bind成功&#xff0c;但是在客户端向服务端发送数据后&#xff0c;服务端无响应的情况&#xff0c;如果使用轻量级应用服务器&#xff0c;大概率是服务器的端口因为防火墙未对公网IP开放…

《 Spring Boot整合多数据源:分库业务的标准做法》

&#x1f680; Spring Boot整合多数据源&#xff1a;分库业务的标准做法 文章目录&#x1f680; Spring Boot整合多数据源&#xff1a;分库业务的标准做法&#x1f50d; 一、为什么需要多数据源支持&#xff1f;&#x1f4a1; 典型业务场景⚙️ 二、多数据源集成方案对比&#…

前端ApplePay支付-H5全流程实战指南

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档前言近期公司开展关于苹果支付的相关业务&#xff0c;与之前不同的是&#xff0c;以前后台直接获取第三方Wallet封装好的接口获取支付地址&#xff0c;H5页面直接跳转使用Appl…

Flink窗口:解锁流计算的秘密武器

Flink 窗口初识在大数据的世界里&#xff0c;数据源源不断地产生&#xff0c;形成了所谓的 “无限数据流”。想象一下&#xff0c;网络流量监控中&#xff0c;每一秒都有海量的数据包在网络中穿梭&#xff0c;这些数据构成了一个无始无终的流。对于这样的无限数据流&#xff0c…

Java排序算法之<希尔排序>

目录 1、希尔排序介绍 1.1、定义 1.2、核心思想 2、希尔排序的流程 第 1 轮&#xff1a;gap 4 第 2 轮&#xff1a;gap 2 第 3 轮&#xff1a;gap 1 3、希尔排序的实现 4、时间复杂度分析 5、希尔排序的优缺点 6、适用场景 前言 希尔排序&#xff08;Shell Sort&…

c++加载qml文件

这里展示了c加载qml文件的三种方式以及qml文件中根节点的访问准备在创建工程的初期&#xff0c;遇到了一个问题&#xff0c;cmake文件以前都是系统自动生成的&#xff0c;不需要我做过多的操作修改&#xff0c;但是&#xff0c;加载qml的程序主函数是需要用到QGuiApplication&a…

007TG洞察:GPT-5前瞻与AI时代竞争力构建:技术挑战与落地路径

最近&#xff0c;GPT-5 即将发布的消息刷爆了科技圈&#xff0c;更让人期待的是&#xff0c;GPT-6 已经悄悄启动训练了&#xff0c;OpenAI 的奥特曼表示对未来1-2年的模型充满信心&#xff0c;预测AI将进化为能够发现新知识的“AI科学家”。面对日益强大的通用AI&#xff0c;企…

Windows下编译OpenVDB

本文记录在Windows下编译OpenVDB的流程。 零、环境 操作系统Windows 11VS Code1.92.1Git2.34.1MSYS2msys2-x86_64-20240507Visual StudioVisual Studio Community 2022CMake3.22.1 一、编译 1.1 下载 git clone https://github.com/AcademySoftwareFoundation/openvdb.git …

react 内置hooks 详细使用场景,使用案例

useState场景&#xff1a;组件中管理局部状态&#xff0c;如表单值、开关、计数器等。const [count, setCount] useState(0); return <button onClick{() > setCount(count 1)}>Click {count}</button>;useEffect 场景&#xff1a;组件挂载时执行副作用&#…

从0到1学Pandas(九):Pandas 高级数据结构与操作

目录一、探秘多级索引1.1 创建多级索引1.2 多级索引操作1.3 索引转换二、探索 Panel 与 xarray2.1 Panel 数据结构2.2 xarray 库2.3 高维数据操作三、时间序列高级应用3.1 时区处理3.2 时间序列重采样与频率转换3.3 时间序列分解与预测四、数据透视与重塑高级技巧4.1 复杂透视表…

C# 图像转换实战:Bitmap 转 BitmapSource 的 2 种方法

C# 图像转换实战:Bitmap 转 BitmapSource 的 2 种方法 引言 两种转换方法的完整实现 1. 基于GDI句柄的直接转换 (ToBitmapSourceFast) 2. 基于内存流的编码转换 (ToBitmapSourceSafe) 方法对比与选型指南 避坑指南 GDI句柄泄漏问题 图像显示不完整 多线程访问图像引发异常 不同…

Spring Boot 整合 Spring MVC:自动配置与扩展实践

Spring MVC 作为 Java Web 开发的核心框架&#xff0c;在传统 SSM 项目中需要大量 XML 配置&#xff08;如 DispatcherServlet、视图解析器等&#xff09;。而 Spring Boot 通过 "自动配置" 特性&#xff0c;简化了 Spring MVC 的整合过程&#xff0c;同时保留了灵活…