arm a8 S5PV210步进电机驱动
最近利用arm板在做项目,第一次接触这玩意儿,感觉有点难。屋漏偏逢连夜雨,做项目要用到步进电机,板子带的文档上偏偏没有关于步进电机的驱动。真是苦煞个人。花费了一天一夜,终于写出了一个十分粗陋不堪的驱动,勉强可以用吧。(代码奉上)
驱动代码:
// stepping motor mouble
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <plat/gpio-cfg.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/div64.h>
#include <mach/gpio.h>
#include <mach/regs-gpio.h>
#define DEVICE_NAME "motor"
#define DEVICE_MAJOR 222
#define DEVICE_MINOR 0
static unsigned long motor_pin[]={
S5PV210_GPG2(0),
S5PV210_GPG2(1),
S5PV210_GPG2(2),
S5PV210_GPG2(3),
};
struct cdev *mycdev;
struct class *myclass;
dev_t devno;
//control the motor to roll
static int motor_ioctl(struct inode *inode, struct file *file, unsigned int cmd,unsigned long arg)
{
printk("I have been the ioctl,the cmd is %d\n",cmd);
switch(cmd){
case 1:
gpio_set_value(motor_pin[0],1);
gpio_set_value(motor_pin[1],0);
gpio_set_value(motor_pin[2],0);
gpio_set_value(motor_pin[3],0);
return 0;
case 2:
gpio_set_value(motor_pin[0],0);
gpio_set_value(motor_pin[1],0);
gpio_set_value(motor_pin[2],1);
gpio_set_value(motor_pin[3],0);
return 0;
case 3:
gpio_set_value(motor_pin[0],0);
gpio_set_value(motor_pin[1],1);
gpio_set_value(motor_pin[2],0);
gpio_set_value(motor_pin[3],0);
return 0;
case 4:
gpio_set_value(motor_pin[0],0);
gpio_set_value(motor_pin[1],0);
gpio_set_value(motor_pin[2],0);
gpio_set_value(motor_pin[3],1);
return 0;
case 5:
gpio_set_value(motor_pin[0],0);
gpio_set_value(motor_pin[1],0);
gpio_set_value(motor_pin[2],0);
gpio_set_value(motor_pin[3],1);
return 0;
case 6:
gpio_set_value(motor_pin[0],0);
gpio_set_value(motor_pin[1],1);
gpio_set_value(motor_pin[2],0);
gpio_set_value(motor_pin[3],0);
return 0;
case 7:
gpio_set_value(motor_pin[0],0);
gpio_set_value(motor_pin[1],0);
gpio_set_value(motor_pin[2],1);
gpio_set_value(motor_pin[3],0);
return 0;
case 8:
gpio_set_value(motor_pin[0],1);
gpio_set_value(motor_pin[1],0);
gpio_set_value(motor_pin[2],0);
gpio_set_value(motor_pin[3],0);
return 0;
}
return 0;
}
static struct file_operations motor_fops =
{
.owner = THIS_MODULE,
.ioctl = motor_ioctl,
};
static int __init motor_init(void)
{
int ret;
int err;
int i;
for(i=0;i<4;i++){
ret=gpio_request(motor_pin[i],"motor");
if(ret<0){
printk("motor_pin[%d] request error!\n",i);
}
gpio_direction_output(motor_pin[i],0);
}
devno = MKDEV(DEVICE_MAJOR, DEVICE_MINOR);//获取设备号
mycdev = cdev_alloc();//自动分配
cdev_init(mycdev, &motor_fops);//初始化字符设备
err = cdev_add(mycdev, devno, 1);
if (err != 0)
printk("s5pv210 motor device register failed!\n");
myclass = class_create(THIS_MODULE, "s5pv210-dc-motor");
if(IS_ERR(myclass)) {
printk("Err: failed in creating class.\n");
return -1;
}
device_create(myclass,NULL, MKDEV(DEVICE_MAJOR,DEVICE_MINOR), NULL, DEVICE_NAME);//自动创建设备文件节点
printk (DEVICE_NAME"\tdevice initialized\n");
printk(DEVICE_NAME " initialized\n");
return 0;
}
/*驱动程序卸载函数*/
static void __exit motor_exit(void)
{
int i;
for(i=0;i<4;i++){
gpio_free(motor_pin[i]);
}
cdev_del(mycdev);
device_destroy(myclass,devno);
class_destroy(myclass);
}
module_init(motor_init); //声明驱动程序入口
module_exit(motor_exit); //声明驱动程序出口
MODULE_AUTHOR("DU MU CHUN");
MODULE_DESCRIPTION("STEPPING MOTOR Driver");
MODULE_LICENSE("GPL");
Makefile:
obj-m :=motor.o //编译文件的名字
KERNELDIR := /usr/linux-2.6.35.7/ //内核所在的位置,内核至少编译过一次
PWD := $(shell pwd)
all:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -rf *.o *.ko *.mod.* *.symvers
.PHONY: all clean
测试程序:
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
char *DCV_NAME = "/dev/motor";
int main(){
int fd=-1;
int i=0,j=0,k=0;
int cmd=1;
if((fd=open("/dev/motor",0))==-1){
printf("motor open error\n");
return -1;
}
printf("now begin!\n");
while(i<10){
for(j=0;j<200;j++){//正转
ioctl(fd,1);
ioctl(fd,2);
ioctl(fd,3);
ioctl(fd,4);
}
for(j=0;j<200;j++){//反转
ioctl(fd,5);
ioctl(fd,6);
ioctl(fd,7);
ioctl(fd,8);
}
i++;
}
close(fd);
return 0;
}
——————-