⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stepper.c

📁 linux下 步进电机驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright 1999 by Mark Whitis.  All rights Reserved *//* Must be compiled with -O for outb to be inlined, otherwise *//* link error *//* Usermode: gcc -g -O -o teststep teststep.c *//* LKM: *//*  gcc -O -DMODULE -D__KERNEL__ -o stepperout.o -c stepper.c *//*      ld -r -o stepper.o stepperout.o ring.o */#include "stepper.h"#ifdef __KERNEL__   #include <linux/kernel.h>   #include <linux/config.h>   #ifdef MODULE     #include <linux/module.h>     #include <linux/version.h>   #else     /* Since the linux kernel is infected with the GNU Copyleft virus */     /* this code should not be statically linked with the kernel. */     #error This device driver must be compiled as a loadable kernel module     #define MOD_INC_USE_COUNT     #define MOD_DEC_USE_COUNT   #endif   #include <linux/types.h>   #include <linux/fs.h>   #include <linux/mm.h>   #include <linux/errno.h>   #include <asm/segment.h>   #include <asm/io.h>   #include <linux/sched.h>   #include <linux/tqueue.h>#else   #include <unistd.h>   #include <stdlib.h>   /* including stdio will cause grief */   #include <stdio.h>   #include <asm/io.h>#endif#if 0   #include <stdarg.h>   #include <ctype.h>#endif#include <string.h>#ifdef __KERNEL__   #include "ring.h"   ring_buffer_t read_buffer;   ring_buffer_t write_buffer;   /* Parallel port interrupt to use for timing */   /*  0=use Linux 100hz jiffie timer */   static int irq = 0;   /* Major device # to request */   static int major = 31;   /* The device # we actually got */   static int stepper_major = 0;   struct wait_queue *read_wait = NULL ;    /* used to block user read if buffer underflow occurs */   struct wait_queue *write_wait = NULL;    /* used to block user write if buffer overflow occurs */#endifstatic int debug = 1;static int verbose_io=0;static int verbose_move=0;static int base=0x378;static int power_down_on_exit=1;/* The following set the delay between steps */#ifndef __KERNEL__   static int delay = 50000;     /* for usleep */   static int fastdelay = 0;   /* delay loop */#else   static int skipticks = 0;#endif/* the following value can be set to 0 to disable the *//* actual I/O operations.  This will allow experimenting *//* on a system which does not have a free parallel port */static int do_io = 1;#ifdef __KERNEL__   static int read_is_sleeping = 0;   static int write_is_sleeping = 0;   static int abort_read = 0;   static int abort_write = 0;   static int read_is_open = 0;   static int write_is_open = 0;   static int interrupts_are_enabled = 0;   static int autostart=1;#endifstatic int tick_counter=0;int xdest = 0;int xuser = 0;int xpos = 0;int ydest = 0;int yuser = 0;int ypos = 0;int zdest = 0;int zuser = 0;int zpos = 0;unsigned short word;void verbose_outb(int port, int value){   #ifndef __KERNEL__      if(verbose_io) printf("outb(%02X,%04X)\n",port,value);   #else      if(verbose_io) printk("outb(%02X,%04X)\n",port,value);   #endif   if(do_io) outb(port,value);}#ifdef __KERNEL__   void do_delay()   {      ;   }#else   void do_delay()   {      int i;      if(fastdelay>0) {	for(i=0;i<fastdelay;i++) {	   /* dummy operation so optimizer doesn't */	   /* eliminate loop */	   verbose_outb( (word&0x00FF),base+0);	}      } else {	 usleep(delay);      }   }#endifvoid report_status(){   char buf[128];   int rc;   int i;   int len;   sprintf(buf,"x=%d,y=%d,z=%d,word=%08X\n",xpos,ypos,zpos,word);   #ifdef __KERNEL__      len=strlen(buf);            for(i=0;i<len;i++) {         rc=ring_buffer_write(&read_buffer,&buf[i],1);      }      /* we need to wake up read function */      if(read_is_sleeping) {         if(debug>=5) printk("stepper: waking up read/n");         wake_up_interruptible(&read_wait);      }   #else      puts(buf);   #endif  }unsigned short x_steptable[8]=   {0x0001,0x0005,0x0004,0x0006,0x0002,0x000A,0x0008,0x0009};unsigned short y_steptable[8]=   {0x0010,0x0050,0x0040,0x0060,0x0020,0x00A0,0x0080,0x0090};unsigned short z_steptable[8]=   {0x0100,0x0500,0x0400,0x0600,0x0200,0x0A00,0x0800,0x0900};unsigned short flipbits = 0x0B00;unsigned short irq_enable_bit=0x1000;void move_one_step(){  /* This is a very simple multiaxis move routine */  /* The axis will not move in a coordinate fashion */  /* unless the angle is a multiple of 45 degrees */  if(xdest > xpos) {      xpos++;  } else if(xdest < xpos) {     xpos--;  }  if(ydest > ypos) {      ypos++;  } else if(ydest < ypos) {     ypos--;  }  if(zdest > zpos) {      zpos++;  } else if(zdest < zpos) {     zpos--;  }  word = x_steptable[xpos%8]       | y_steptable[ypos%8]       | z_steptable[zpos%8];  #ifdef __KERNEL__     if(interrupts_are_enabled) word |= irq_enable_bit;  #endif    /* Some of the signals are inverted */    word ^= flipbits;    /* output low byte to data register */  verbose_outb( (word & 0x00FF), base+0);  /* output high byte to control register */  verbose_outb( (word >> 8), base+2);  if(verbose_move) report_status();}void move_all(){   while( (xpos!=xdest) || (ypos!=ydest) || (zpos!=zdest) ) {      move_one_step();      do_delay();   }}void parse_one_char(char c){   static int value;   static int dest=' ';   static int negative=0;   #if 0      c = toupper(c);   #else      if( (c>'a') && (c<'z') ) { c = c - 'a' + 'A'; }   #endif   switch(c) {      case('X'):      case('Y'):      case('Z'):         dest=c;         break;      case('='):         break;      case('-'):         negative = !negative;         break;      case('+'):         negative = 0;      case('0'):      case('1'):      case('2'):      case('3'):      case('4'):      case('5'):      case('6'):      case('7'):      case('8'):      case('9'):         value *= 10;         value += (c-'0');         break;      case('?'):         report_status();      case('\r'):      case('\n'):      case(','):         if(negative) {            value = -value;         }	 if(dest=='X') {            xuser = value;         } else if(dest=='Y') {            yuser = value;         } else if(dest=='Z') {            zuser = value;         }         value = 0;         negative = 0;         if( (c=='\n')||(c=='\r') ){            xdest = xuser;            ydest = yuser;            zdest = zuser;            #ifdef __KERNEL__               if(debug>=3) {                  printk("xdest=%d ydest=%d zdest=%d\n",                     xdest,ydest,zdest);               }            #endif         }         break;   }}#ifdef __KERNEL__   static int stepper_lseek(struct inode *inode,       struct file *file, off_t offset, int orig)   {       /* Don't do anything, other than set offset to 0 */      return(file->f_pos=0);   }   static int stepper_read(struct inode *node,       struct file *file, char *buf, int count)   {      static char message[] = "hello, world\n";      static char *p = message;      int i;      int rc;      char xferbuf;      int bytes_transferred;      int newline_read;      newline_read=0;      if(!read_is_open) {	 printk("stepper: ERROR: stepper_read() called while "            "not open for reading\n");      }       bytes_transferred=0;      if(debug>2) printk("stepper_read(%08X,%08X,%08X,%d)\n",          node,file,buf,count);      if(rc=verify_area(VERIFY_WRITE, buf, count) < 0 ) {         printk("stepper_read(): verify area failed\n");         return(rc);      }      for(i=count; i>0; i--) {	 #if 0	    if(!*p) p=message;	    put_fs_byte(*p++,buf++);	 #else	    while(1) {	       rc=ring_buffer_read(&read_buffer,&xferbuf,1);	       if(debug>3) {                  printk(                     "stepper: ring_buffer_read returned %d\n",                      rc);               }	       if(rc==1) {		   bytes_transferred++;		   put_fs_byte(xferbuf,buf++);                   if(xferbuf=='\n') {                      printk("stepper_read(): newline\n");                      newline_read=1;                   }		   break;  /* read successful */	       }               read_is_sleeping=1;               if(debug>=3) printk("stepper: read sleeping\n");               interruptible_sleep_on(&read_wait);	       read_is_sleeping=0;	       if(abort_read) return(bytes_transferred);	    }                      /* we want read to return at the end */            /* of each line */            if(newline_read) break;	 #endif      }      if(write_is_sleeping) wake_up_interruptible(&write_wait);      if(debug>=3) {         printk("stepper_read(): bytes=%d\n", bytes_transferred);      }      return(bytes_transferred);   }   static int stepper_write(struct inode *inode,       struct file *file, const char *buf, int count)   {      int i;      int rc;      char xferbuf;      int bytes_transferred;      if(!write_is_open) {	 printk("stepper: ERROR: stepper_write() called"            " while not open for writing\n");      }      bytes_transferred=0;      if(rc=verify_area(VERIFY_READ, buf, count) < 0 ) {         return(rc);      }      for(i=count; i>0; i--) {	    xferbuf = get_fs_byte(buf++);	    while(1) { 	      rc=ring_buffer_write(&write_buffer,&xferbuf,1);	      if(rc==1) {		 bytes_transferred++;		 break;	      } 	       if(debug>10) printk("stepper: write sleeping\n");	       write_is_sleeping=1;	       interruptible_sleep_on(&write_wait);	       write_is_sleeping=0;	       if(abort_write) return(bytes_transferred);	    }       }      if(read_is_sleeping) wake_up_interruptible(&read_wait);      return(bytes_transferred);   }   void stepper_start()   {     /* do nothing at the moment */   }   void stepper_stop()   {     /* do nothing at the moment */   }   static int stepper_ioctl(struct inode *iNode,       struct file *filePtr, unsigned int cmd, unsigned long arg)   {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -