Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Schrittmotor-Controller mit ATtiny2313
- #define F_CPU 4000000UL // 4 MHz (fuer delay.h)
- // Benötigte Bibliotheken:
- #include <avr/io.h>
- #include <util/delay.h>
- #include <avr/interrupt.h>
- // BinaryNr.h ermöglicht eine bequeme Binärzahlen-Darstellung
- #include <BinaryNr.h>
- // Zuordnung der Eingänge zu den Portpins
- #define STEP PD2
- #define DEMOMODE PD3
- #define DIRECTION PD4
- #define ENABLE PD5
- // Die Ansteuerungstabelle wird im StepArray[] gespeichert
- #define STEP_ARRAY_LENGTH 4
- #define TIMER1DIVIDER 8 // Faktor zum Verlängern des Timer1-Taktes (130 ms)
- volatile uint8_t Timer1Counter = 0;
- volatile uint8_t StepArrayCounter = 0; // Zeiger auf Array
- volatile uint8_t StepArray[STEP_ARRAY_LENGTH] =
- {
- B00001010, B00000110, B00000101, B00001001
- };
- // Nicht vergessen - Fuses einstellen mit "AVR8 Burn-O-Mat"
- // Fuse-Bits: --- für internen Clock ---
- // efuse = FF
- // hfuse = DF
- // lfuse = E2 (4 MHz Grundtaktakt ohne Teilung)
- // -> Frequenz : 4.000.000 Hz
- // Timer1-Interrupt als STEP-Zeitgeber initialisieren
- void Init_Timer1(void)
- {
- // Timer 1 ist 16-Bit-Timer
- // CS12=0, CS11=1, CS10=0 => Vorteiler 8; -> 4.000.000 Hz : 8 = 500 000
- // Der Overflow-Interrupt wird aber erst ausgelöst,
- // wenn der Zähler die Zahl 65 536 (16 Bit) erreicht
- // Zeitintervall = 500 000 : 65 536 = 7,63 Hz (ca. alle 130 ms)
- // Damit lassen sich Frequenzen von ca. 1, 2 und 0,5 Hz. ableiten
- TCCR1B |= (0 << CS12) | (1 << CS11) | (0 << CS10); // Vorteiler 8
- // Enable timer 1 interrupt -> ohne die anderen Bits zu verändern
- TIMSK |= (1 << TOIE1);
- }
- void MakeStep(void)
- {
- // Jeder Aufruf der Routine bringt einen Step am Schrittmotor
- // Dabei werden die Schalter ENABLE und DIRECTION abgefragt
- // ENABLE auf HIGH geschaltet? Dann Motorspannungen an!
- if ( PIND & (1<<ENABLE) )
- {
- // Der Schalter DIRECTION wird abgefragt:
- if ( PIND & (1<<DIRECTION) )
- {
- // Linkslauf bei Taster DIRECTION = HIGH
- if (StepArrayCounter > 0)
- {
- StepArrayCounter--;
- PORTB = StepArray[StepArrayCounter];
- }
- else
- {
- StepArrayCounter = STEP_ARRAY_LENGTH-1; // -1 -> ARRAY zählt 0, 1, 2, 3
- PORTB = StepArray[StepArrayCounter];
- }
- }
- else
- {
- //Rechtslauf bei Taster DIRECTION = LOW
- PORTB = StepArray[StepArrayCounter];
- StepArrayCounter++;
- if (StepArrayCounter == STEP_ARRAY_LENGTH)
- {
- StepArrayCounter = 0;
- }
- }
- }
- else
- {
- PORTB = B00000000; // Alle Motorspannungen aus!
- }
- }
- ISR(TIMER1_OVF_vect)
- {
- // Bei eingeschaltetem Schalter DEMOMODE wird automatisch ein Takt von ca. 500 ms erzeugt,
- // indem der Takt des Timer1 von ca. 130 ms mit dem TIMER1DIVIDER multipliziert wird.
- // Ein Schritt am Schrittmotor wird nur erzeugt, wenn der Schalter DEMOMODE = HIGH ist.
- if (Timer1Counter < TIMER1DIVIDER)
- {
- Timer1Counter++;
- }
- else
- {
- // DEMOMODE auf HIGH geschaltet? Dann mache einen Step!
- if ( PIND & (1<<DEMOMODE) )
- {
- MakeStep();
- }
- Timer1Counter=0; // Zurücksetzen
- }
- }
- // Interrupt-Routine -> Verwendung des INT0 als STEP-Eingang
- ISR(INT0_vect)
- {
- // DEMOMODE auf LOW geschaltet? Dann mache einen Step!
- if ( PIND & (1<<DEMOMODE) )
- {
- }
- else
- {
- MakeStep();
- }
- }
- // Interrupt INT0 initialisieren
- void INT0_Init(void)
- {
- MCUCR = 1<<ISC01;// INT0 mit steigender Flanke
- GIMSK |= 1<<INT0; //Enable INTO in Global Interrupt Mask
- }
- int main(void)
- {
- // Port B Pin0, Pin1, Pin2, Pin3 auf Ausgang setzen
- DDRB |= (1 << PIN0) | (1 << PIN1) | (1 << PIN2) | (1 << PIN3);
- PORTB = B00000000; // Beim Start erst einmal auf Null setzen
- // Portpins als Eingänge setzen
- DDRD &= ~((1 << STEP) | (1 << DIRECTION) | (1 << ENABLE) | (1 << DEMOMODE));
- // Interrupt INT0 vorbereiten:
- INT0_Init();
- Init_Timer1();
- _delay_ms(500); // Warten bis alle Spannungen da sind
- sei(); //Enable Global Interrupt
- while (1)
- {
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement