基于S3C2440和linux的多路步进电机驱动设计

来源:互联网 发布:网络精灵国语版 编辑:程序博客网 时间:2024/05/01 12:16
 

步进电机驱动程序:

#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/unistd.h>


#define DEVICE_NAME "myleds"

static unsigned long led_table [] = {
 
 S3C2410_GPB5,
 S3C2410_GPB6,
 S3C2410_GPB7,
 S3C2410_GPB8,
};

static unsigned int led_cfg_table [] = {
 
 S3C2410_GPB5_OUTP,
 S3C2410_GPB6_OUTP,
 S3C2410_GPB7_OUTP,
 S3C2410_GPB8_OUTP,
};

static int sbc2440_leds_ioctl(
 struct inode *inode,
 struct file *file,
 int cmd,
       long arg)
 //cmd正负表示电机转动方向,和转动度数;arg正负表示电机号,绝对值表示电机转动间隔
{
       int n,deg,dir,frq;
 int i;
 deg=cmd;
 frq=arg;
 if(cmd<0)
  {
                  dir=0;//dir为0表示电机反转,转动deg角度
     deg=-cmd;
  }
 else
  {
     dir=1;//dir为1表示电机正转,转动deg角度
     deg=cmd;
  }
 if(arg<0)
  {
     n=0;//n为0表示0号电机,每步间隔frq毫秒
     frq=-arg;
  }
 else
  
  {
     n=1;//n为0表示1号电机,每步间隔frq毫秒
     frq=arg;
  }
 printk("n=%d,deg=%d,dir=%d,frq=%d",n,deg,dir,frq);
 switch(n)
  {
    case 0://0号电机转动deg角度
     s3c2410_gpio_setpin(S3C2410_GPB5 , dir);
   for(i=0;i<deg;i++)
   
   s3c2410_gpio_setpin(S3C2410_GPB6,1);
   mdelay(frq/2);
   s3c2410_gpio_setpin(S3C2410_GPB6,0);
   mdelay(frq/2);
   }
   break;
    case 1:// 1号电机转动deg角度
     s3c2410_gpio_setpin(S3C2410_GPB7 , dir);
   for(i=0;i<deg;i++)
   
   s3c2410_gpio_setpin(S3C2410_GPB8,1);
   mdelay(frq/2);
   s3c2410_gpio_setpin(S3C2410_GPB8,0);
   mdelay(frq/2);
   }
   break;
    default:
     break;
  }
}

static struct file_operations dev_fops = {
 .owner THIS_MODULE,
 .ioctl sbc2440_leds_ioctl,
};

static struct miscdevice misc = {
 .minor = MISC_DYNAMIC_MINOR,
 .name = DEVICE_NAME,
 .fops = &dev_fops,
};

static int __init dev_init(void)
{
 int ret;

 int i;
 
 for (i = 0; i < 4; i++) {
  s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
  s3c2410_gpio_setpin(led_table[i], 0);
 }

 ret = misc_register(&misc);

 printk (DEVICE_NAME"\tinitialized\n");

 return ret;
}

static void __exit dev_exit(void)
{
 misc_deregister(&misc);
}

module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("JXBOYLJ BIT");

 

驱动测试程序:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>


int main(int argc, char **argv)
{
 int index,dir,deg,speed;
 
 int fd;
 if (argc != 5 || sscanf(argv[1], "%d", &index) != 1 || sscanf(argv[2],"%d", &dir) != 1 ||sscanf(argv[3], "%d", &deg) != 1 || sscanf(argv[4],"%d", &speed) != 1)
  {
  fprintf(stderr, "Usage: leds led_no 0|1\n");
  exit(1);
 }
 if(dir==0)  deg=-deg;
 printf("dir=%d,deg=%d\n",dir,deg);
 if(index==0) speed=-speed;
 printf("index=%d,speed=%d\n",index,speed);
 fd = open("/dev/myleds", 0);
 if (fd < 0) {
  fd = open("/dev/leds0", 0);
 }
 if (fd < 0) {
  perror("open device leds");
  exit(1);
 }
 ioctl(fd, deg, speed);
 close(fd);
 return 0;
}

原创粉丝点击