??本人從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