Project

General

Profile

Statistics
| Branch: | Revision:

root / scout_avr / src / stepper.cpp @ a07a0b55

History | View | Annotate | Download (2.52 KB)

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