Statistics
| Branch: | Revision:

root / scout_avr / src / stepper.cpp @ 85dff67b

History | View | Annotate | Download (2.65 KB)

1 a07a0b55 Julian Binder
extern "C"
2
{
3
#include <avr/io.h>
4 85dff67b Julian Binder
#include <util/delay.h>
5 a07a0b55 Julian Binder
}
6
#include "stepper.h"
7
8
/*  Stepper Motor:
9
 *  Provides interface to stepper motor.
10
 *  Can set direction. Outputs pulse to stepper upon call of step func
11
 *  Also provides variable speed sweep
12
 */
13
14
struct step_t {
15
  unsigned int speed; // time between steps in ms for sweep. Mininum 40ms
16
  unsigned int sweep_us; //time between calls to sweep  
17
  unsigned int time;
18
  int pos; // position in rotation.
19
  int dir; // direction. -1 CCW. 1 CW. 0 OFF
20
  int ccw;
21
  int cw;
22
} volatile step;
23
24
25
func step_init(unsigned int call_us)
26
{
27
  /* set update time for sweep */
28
  step.sweep_us = call_us;
29
  
30 85dff67b Julian Binder
  /* init pos, time, and dir to 0 */
31 a07a0b55 Julian Binder
  step.pos = 0;
32
  step.time = 0;
33 85dff67b Julian Binder
  step.dir = 0;
34 a07a0b55 Julian Binder
35
  //set control pins as output
36
  DDRD |= ((1<<S_STEP) | (1<<S_DIR));
37
  DDRB |= ((1<<S_MS));
38
39
  //initiate to full steps
40
  PORTB &= (~(1<<S_MS));
41
 
42
  //initiate the step pin to be low. stepper steps on low to high
43
  PORTD &= (~(1<<S_STEP));
44
45
  //return function pointer to sweep to be called ever sweep_us uS. 
46
  return &(step_sweep);
47
}
48
49
/* set direction pin */
50
void step_dir(int dir)
51
{
52
  step.dir = dir;
53
  switch(dir)
54
  {
55
    case 1:
56
         PORTD |= (1<<S_DIR);
57
      break;
58
    case -1:
59
         PORTD &= (~(1<<S_DIR));
60
      break;
61
  }
62
}
63
64
void step_halfstep()
65
{
66 85dff67b Julian Binder
  if(step.dir==0) return; //do not step if not enabled
67 a07a0b55 Julian Binder
  PORTB |= (1<<S_MS); //enable microstepping
68 85dff67b Julian Binder
  __asm__ __volatile__(
69
    "nop\n\t"
70
    "nop\n\t"
71
    "nop\n\t"
72
    "nop\n\t"
73
  ::);//wait 250 ns for microstepping to enable
74 a07a0b55 Julian Binder
  PORTD |= (1<<S_STEP); //step once
75 85dff67b Julian Binder
  _delay_us(1); //conform with step timing
76 a07a0b55 Julian Binder
  PORTD &= (~(1<<S_STEP)); //bring the step bin back down
77
  PORTB &= (~(1<<S_MS)); //disable microstepping
78 85dff67b Julian Binder
  if(step.dir==1) step.pos++; //keep track of pos. 1/2 step so add/sub 1
79 a07a0b55 Julian Binder
  else step.pos--;
80
}
81
82
void step_fullstep()
83
{
84 85dff67b Julian Binder
  if(step.dir==0) return; //do not step if not enabled
85 a07a0b55 Julian Binder
  PORTD |= (1<<S_STEP); //step once 
86 85dff67b Julian Binder
  _delay_us(1); //conform with step timing
87 a07a0b55 Julian Binder
  PORTD &= (~(1<<S_STEP)); //bring the step bin back down
88 85dff67b Julian Binder
  if(step.dir==1) step.pos+=2; // full step so add/sub 2
89 a07a0b55 Julian Binder
  else step.pos-=2;
90
}
91
92
void step_flush()
93
{
94
  PORTD &= (~(1<<S_STEP)); //bring the step bin back down
95
}
96
97
/* tick every speed ms in sweep mode */
98
void step_sweep_speed(unsigned int speed)
99
{
100
  if(speed<40) step.speed = 40000;
101
  else step.speed = speed*1000;
102
}
103
104
105
//ccw must be less than 0 and cw must be greater than 0
106
void step_sweep_bounds(int ccw, int cw)
107
{
108
  step.ccw = ccw;
109
  step.cw = cw;
110
}
111
112
void step_sweep()
113
{
114 85dff67b Julian Binder
  step.time += step.sweep_us;
115
  if(step.time >= step.speed)
116 a07a0b55 Julian Binder
  {
117
    step_halfstep();
118 85dff67b Julian Binder
    if((step.dir == 1) && (step.cw <= step.pos)) step.dir=-1;
119
    else if((step.dir == -1) && (step.ccw >= step.pos)) step.dir=1;
120 a07a0b55 Julian Binder
  }
121
}