document.write('
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. // Schrittmotor-Controller mit ATtiny2313
  2.    
  3. #define F_CPU 4000000UL      // 4 MHz (fuer delay.h)
  4.    
  5. // Benötigte Bibliotheken:
  6. #include <avr/io.h>
  7. #include <util/delay.h>
  8. #include <avr/interrupt.h>
  9. // BinaryNr.h ermöglicht eine bequeme Binärzahlen-Darstellung
  10. #include <BinaryNr.h>
  11.    
  12. // Zuordnung der Eingänge zu den Portpins
  13. #define STEP PD2
  14. #define DEMOMODE PD3
  15. #define DIRECTION PD4
  16. #define ENABLE PD5
  17.    
  18. // Die Ansteuerungstabelle wird im StepArray[] gespeichert
  19. #define STEP_ARRAY_LENGTH 4
  20. #define TIMER1DIVIDER 8 // Faktor zum Verlängern des Timer1-Taktes (130 ms)
  21.    
  22. volatile uint8_t Timer1Counter = 0;
  23.    
  24. volatile uint8_t StepArrayCounter = 0; // Zeiger auf Array
  25. volatile uint8_t StepArray[STEP_ARRAY_LENGTH] =
  26.     {
  27.         B00001010, B00000110, B00000101, B00001001
  28.     };
  29.    
  30. // Nicht vergessen - Fuses einstellen mit "AVR8 Burn-O-Mat"
  31. // Fuse-Bits: --- für internen Clock ---
  32. // efuse = FF
  33. // hfuse = DF    
  34. // lfuse = E2 (4 MHz Grundtaktakt ohne Teilung)                                
  35. // -> Frequenz : 4.000.000 Hz
  36.    
  37.    
  38. // Timer1-Interrupt als STEP-Zeitgeber initialisieren
  39.     void Init_Timer1(void)
  40.         {
  41.           // Timer 1 ist 16-Bit-Timer
  42.            // CS12=0, CS11=1, CS10=0 => Vorteiler 8;  -> 4.000.000 Hz : 8  = 500 000  
  43.           // Der Overflow-Interrupt wird aber erst ausgelöst,
  44.           // wenn der Zähler die Zahl 65 536 (16 Bit) erreicht
  45.           // Zeitintervall = 500 000 : 65 536 = 7,63 Hz (ca. alle 130 ms)
  46.           // Damit lassen sich Frequenzen von ca. 1, 2 und 0,5 Hz. ableiten
  47.           TCCR1B |= (0 << CS12) | (1 << CS11) | (0 << CS10); // Vorteiler 8
  48.           // Enable timer 1 interrupt -> ohne die anderen Bits zu verändern
  49.           TIMSK |= (1 << TOIE1);
  50.         }
  51.        
  52.     void MakeStep(void)
  53.         {
  54.         // Jeder Aufruf der Routine bringt einen Step am Schrittmotor
  55.         // Dabei werden die Schalter ENABLE und DIRECTION abgefragt
  56.        
  57.         // ENABLE auf HIGH geschaltet? Dann Motorspannungen an!
  58.                 if ( PIND & (1<<ENABLE) )
  59.                     {
  60.                         // Der Schalter DIRECTION wird abgefragt:
  61.                         if ( PIND & (1<<DIRECTION) )
  62.                         {
  63.                             // Linkslauf bei Taster DIRECTION = HIGH
  64.                             if (StepArrayCounter > 0)
  65.                             {
  66.                                 StepArrayCounter--;
  67.                                 PORTB = StepArray[StepArrayCounter];
  68.                             }
  69.                             else
  70.                             {
  71.                                 StepArrayCounter = STEP_ARRAY_LENGTH-1; // -1 -> ARRAY zählt 0, 1, 2, 3
  72.                                 PORTB = StepArray[StepArrayCounter];
  73.                             }
  74.                            
  75.                         }
  76.                         else
  77.                         {
  78.                             //Rechtslauf bei Taster DIRECTION = LOW
  79.                             PORTB = StepArray[StepArrayCounter];
  80.                             StepArrayCounter++;
  81.                             if (StepArrayCounter == STEP_ARRAY_LENGTH)
  82.                             {
  83.                                 StepArrayCounter = 0;
  84.                             }
  85.                         }
  86.                     }
  87.                     else
  88.                     {
  89.                         PORTB = B00000000; // Alle Motorspannungen aus!
  90.                     }  
  91.         }
  92.        
  93.     ISR(TIMER1_OVF_vect)
  94.         {
  95.             // Bei eingeschaltetem Schalter DEMOMODE wird automatisch ein Takt von ca. 500 ms erzeugt,
  96.             // indem der Takt des Timer1 von ca. 130 ms mit dem TIMER1DIVIDER multipliziert wird.
  97.             // Ein Schritt am Schrittmotor wird nur erzeugt, wenn der Schalter DEMOMODE = HIGH ist.
  98.             if (Timer1Counter < TIMER1DIVIDER)
  99.                 {
  100.                 Timer1Counter++;
  101.                 }
  102.             else
  103.                 {
  104.                 // DEMOMODE auf HIGH geschaltet? Dann mache einen Step!
  105.                 if ( PIND & (1<<DEMOMODE) )
  106.                     {
  107.                         MakeStep();
  108.                     }
  109.  
  110.                 Timer1Counter=0; // Zurücksetzen
  111.                 }
  112.            
  113.         }
  114.        
  115.     // Interrupt-Routine -> Verwendung des INT0 als STEP-Eingang
  116.     ISR(INT0_vect)
  117.         {
  118.             // DEMOMODE auf LOW geschaltet? Dann mache einen Step!
  119.                 if ( PIND & (1<<DEMOMODE) )
  120.                     {
  121.                    
  122.                     }
  123.                     else
  124.                     {
  125.                         MakeStep();
  126.                     }
  127.            
  128.         }
  129.    
  130.     // Interrupt INT0 initialisieren
  131.     void INT0_Init(void)
  132.         {
  133.         MCUCR = 1<<ISC01;// INT0 mit steigender Flanke
  134.         GIMSK |= 1<<INT0; //Enable INTO in Global Interrupt Mask
  135.         }
  136.    
  137.     int main(void)
  138.     {
  139.     // Port B Pin0, Pin1, Pin2, Pin3 auf Ausgang setzen
  140.     DDRB |= (1 << PIN0) | (1 << PIN1) | (1 << PIN2) | (1 << PIN3);
  141.     PORTB = B00000000; // Beim Start erst einmal auf Null setzen
  142.    
  143.     // Portpins als Eingänge setzen
  144.     DDRD &= ~((1 << STEP) | (1 << DIRECTION) | (1 << ENABLE) | (1 << DEMOMODE));
  145.    
  146.     // Interrupt INT0 vorbereiten:
  147.     INT0_Init();
  148.     Init_Timer1();
  149.    
  150.     _delay_ms(500); // Warten bis alle Spannungen da sind
  151.    
  152.     sei(); //Enable Global Interrupt
  153.      
  154.         while (1)
  155.         {
  156.            
  157.         }
  158.        
  159.     return 0;
  160.      
  161.     }
');