当前位置: 首页 > news >正文

从0开始学linux韦东山教程Linux驱动入门实验班(6)

  本人从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.lryc.cn/news/601749.html

相关文章:

  • c# everthing.exe 通信
  • Android基础(一) 运行HelloWorld
  • 【java】 IntelliJ IDEA高效编程设置指南
  • 大模型算法面试笔记——常用优化器SGD,Momentum,Adagrad,RMSProp,Adam
  • Java 代理机制详解:从静态代理到动态代理,彻底掌握代理模式的原理与实战
  • 雪花算法原理深度解析
  • 【0基础PS】PS工具详解--选择工具--快速选择工具
  • 【n8n教程笔记——工作流Workflow】文本课程(第一阶段)——5.4 计算预订订单数量和总金额 (Calculating booked orders)
  • 使用Python,OpenCV,K-Means聚类查找图像中最主要的颜色
  • Unity Catalog与Apache Iceberg如何重塑Data+AI时代的企业数据架构
  • 【LeetCode 热题 100】35. 搜索插入位置——二分查找(左闭右开)
  • 高格办公空间:以 “空间为基,服务为翼”,重塑办公场景生态
  • 【语义分割】记录2:yolo系列
  • libomxil-bellagio移植到OpenHarmony
  • java小白闯关记第一天(两个数相加)
  • Python-初学openCV——图像预处理(三)
  • XSS利用
  • Web-Machine-N7靶机攻略
  • 文件权限标记机制在知识安全共享中的应用实践
  • JavaEE初阶第十二期:解锁多线程,从 “单车道” 到 “高速公路” 的编程升级(十)
  • C++学习(线程相关)
  • 05 - spring security权限控制
  • Java Ai(day04)
  • [Linux入门] Linux 远程访问及控制全解析:从入门到实战
  • 【工具】python汇总发票(含源码)
  • InfluxDB 与 MQTT 协议集成实践(二)
  • Linux网络-------2.应⽤层⾃定义协议与序列化
  • 基于深度学习的图像分割:使用DeepLabv3实现高效分割
  • 【C语言网络编程】HTTP 客户端请求(基于 Socket 的完整实现)
  • 程序代码篇---python向http界面发送数据