Belegnar

Untitled

Aug 29th, 2013
184
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #define F_CPU 16000000L
  2.  
  3. #include <avr/io.h>
  4. #include <avr/interrupt.h>
  5. #include <util/delay.h>
  6.  
  7. #define nop() do { __asm__ __volatile__ ("nop"); } while (0)
  8.  
  9. // steppe port
  10. #define sport PORTB
  11. // externals
  12. #define cport PORTD
  13.  
  14. // pins
  15. #define enable_pin PB3
  16. #define step_pin PB1
  17. #define dir_pin PB2
  18. #define enable_b_pin PD4
  19. #define home_pin PD2
  20. #define error_pin PD3
  21.  
  22. // work cycle
  23. #define stop 0
  24. #define search_home 1
  25. #define duty_cycle 2
  26. #define move_in_home 3
  27.  
  28. volatile unsigned int current_state = 0;
  29. // forced home position
  30. volatile unsigned int force_at_home = 0;
  31. // duty cycle speed
  32. unsigned int step = 0x047D;
  33. // search home speed
  34. unsigned int step_home = 0x047D;
  35.  
  36. // steps per revolution
  37. unsigned int steps_per_rev = 800;
  38. // revolution length in mm
  39. unsigned int revolution_length = 25;
  40. // duty cycle length in mm
  41. unsigned int duty_length = 220;
  42. // duty cycle length in steps
  43. unsigned long int duty_steps = 0;
  44. // current position in steps
  45. volatile unsigned long int position = 0;
  46. // steps to make when home first reached
  47. unsigned int steps_in_home = 800;
  48.  
  49. // home state
  50. inline int at_home(void) {
  51.     if ((PIND & (1 << home_pin)) == 0) {
  52.         return force_at_home;
  53.     } else {
  54.         return 1;
  55.     }
  56. }
  57.  
  58. // enable button
  59. int enabled(void) {
  60.     if ((PIND & (1 << enable_b_pin)) == 0) {
  61.         return 1;
  62.     } else {
  63.         return 0;
  64.     }
  65. }
  66.  
  67. ISR(INT0_vect) {
  68.     _delay_ms(10);
  69.     if (current_state == search_home)
  70.         if (at_home()) {
  71.             current_state = move_in_home;
  72.             position = steps_in_home;
  73.             // move forward from home
  74.             sport |= (1 << dir_pin);
  75.         };
  76. }
  77.  
  78. ISR(INT1_vect) {
  79.     // active if level is high
  80.     if ((PIND & (1 << error_pin)) != 0) {
  81.         // this is error
  82.         // stop everything
  83.         TIMSK1 = 0;
  84.         TCCR1A = 0;
  85.         TCCR1B = 0;
  86.         OCR1AH = 0;
  87.         OCR1AL = 0;
  88.  
  89.         EIMSK = 0;
  90.         PCICR = 0;
  91.         PCMSK0 = 0;
  92.  
  93.         // turn off diode on arduino pin 13
  94.         PORTB &= ~(1 << PB5);
  95.     }
  96. }
  97.  
  98. // level change on enable button pin
  99. ISR(PCINT2_vect) {
  100.     _delay_ms(50);
  101.     if (enabled()) {
  102.         PORTB |= (1 << PB5);
  103.         // enable button pressed step enabled
  104.         PORTB |= (1 << enable_pin);
  105.         TCCR1B |= (1 << CS11);
  106.         if (at_home()) {
  107.             // duty cycle begin
  108.             OCR1A = step;
  109.             sport |= (1 << dir_pin);
  110.             current_state = duty_cycle;
  111.             position = duty_steps;
  112.             force_at_home = 0;
  113.         } else {
  114.             // go home
  115.             OCR1A = step_home;
  116.             sport &= ~(1 << dir_pin);
  117.             current_state = search_home;
  118.         };
  119.         TIMSK1 |= (1 << OCIE1A);
  120.     } else {
  121.         PORTB &= ~(1 << PB5);
  122.         // enable button released - step disabled
  123.         PORTB &= ~(1 << enable_pin);
  124.         TCCR1B &= ~(1 << CS11);
  125.         TIMSK1 &= ~(1 << OCIE1A);
  126.     };
  127. };
  128.  
  129. ISR(TIMER1_COMPA_vect) {
  130.     if (current_state == duty_cycle) {
  131.         position--;
  132.         if (position == 0) {
  133.             _delay_ms(10);
  134.             OCR1A = step_home;
  135.             sport &= ~(1 << dir_pin);
  136.             current_state = search_home;
  137.         }
  138.     }
  139.     else if (current_state == move_in_home) {
  140.         position--;
  141.         if (position == 0) {
  142.             // step disabled at home
  143.             PORTB &= ~(1 << enable_pin);
  144.             TCCR1B &= ~(1 << CS11);
  145.             TIMSK1 &= ~(1 << OCIE1A);
  146.             force_at_home = 1;
  147.         }
  148.     };
  149. }
  150.  
  151. int main(void) {
  152.     _delay_ms(500);
  153.     // step and dir pins - output
  154.     // enable, home and error pins - input
  155.     // activate pull-ups
  156.     PORTB = 0xFF;
  157.     PORTC = 0xFF;
  158.     PORTD = 0xFF;
  159.     DDRB = 0;
  160.     DDRC = 0;
  161.     DDRD = 0;
  162.     nop();
  163.     // step enable, step and dir to output
  164.     sport &= ~((1 << step_pin) | (1 << dir_pin) | (1 << enable_pin));
  165.     DDRB |= (1 << step_pin) | (1 << dir_pin) | (1 << enable_pin) | (1 << PB5);
  166.     nop();
  167.  
  168.     // step
  169.     // phase and frequency correct PWM and /8 divider
  170.     TCCR1A = (0 << COM1A1) | (1 << COM1A0) | (0 << WGM11) | (1 << WGM10);
  171.     TCCR1B = (1 << WGM13) | (0 << WGM12) | (0 << CS12) | (0 << CS11) | (0 << CS10);
  172.     // 125(0x7d) is 8kHz (raise + fall) == 4 kHz total frequency
  173.     OCR1A = step;
  174.     // step will be enabled on button pressed
  175.     TIMSK1 &= ~(1 << OCIE1A);
  176.    
  177.     // home switch on INT0
  178.     // interrupt on any logical change for int0/1: ISC00 = 1 ISC01 = 0 ISC10 = 1 ISC11 = 0
  179.     EICRA = (1 << ISC00) | (1 << ISC10);
  180.     EIMSK |= (1 << INT0);
  181.  
  182.     // error switch on INT1
  183.     EIMSK |= (1 << INT1);
  184.  
  185.     // enable button on PCINT0
  186.     PCICR |= (1 << PCIE2);
  187.     PCMSK2 |= (1 << PCINT20);
  188.  
  189.     duty_steps = (duty_length / revolution_length) * steps_per_rev * 2;
  190.  
  191.     sei();
  192.  
  193.     // diode on pb5 on
  194.     PORTB |= (1 << PB5);
  195.  
  196.     while(1)
  197.     {
  198.         nop();
  199.     }
  200.  
  201.     return 0;
  202. }
RAW Paste Data