Schrittmotor ansteuern über Timerinterrupt

Gast #2357529
Lesenswert?

Hallo,
ich steuere einen Schrittmotor über einen L297 und 2x L6203 an. Über 
einen Timerinterrupt (Timer0 eines ATmega2561) toggle ich den CLK-Pin 
des L297. Bei einem Prescaler von 64 funktioniert dies noch problemlos. 
Bei einem Prescaler von 8 auch, sofern ich nur bei jedem 8. Timeraufruf 
das Signal toggle (--> theoretisch wieder ein Prescaler von 8x8=64). 
Wenn ich allerdings den Prescaler auf 1 setze und das Signal nur jeden 
64. Aufruf toggle ruckelt der Schrittmotor und lauft nicht mehr ruhig. 
Außerdem steigt auch der Stromverbrauch von ca 0.65A auf 2.5A.

Kann sich jemand von euch das Phänomen erklären?
danke, cyberfoxx

PS:
so sieht die Interruppt-Routine aus:
1
ISR(TIMER0_OVF_vect)
2
  {
3
  cnt_t0++;
4
  if(cnt_t0>=64)
5
    {
6
    if(PORTC%2) PORTC&=0xFE; //auf PC0 befindet sich der CLK-Pin des L297
7
    else PORTC|=0x01;
8
    }
9
  }
Gast #2357564
Lesenswert?

ich verwende einen 16MHz Quarz aber ich bin mir nicht sicher ob ich 
schon alles richtig eingestellt habe (Hab bei den fuses CLKDIV8 
deaktiviert und "Ext. Crystal Osc.; Frequency 8.0- MHz; Start-up time: 
16K CK + 65 ms" eingestellt. Muss man sonst noch was machen?). Aber 
unabhängig von der Frequenz müsste F_CPU/1/64 gleich F_CPU/8/8 und 
F_CPU/64/1 sein.
Gast #2357983
Lesenswert?

Habe jetzt einmal versucht auf das wichtigste zu minimieren und jetzt 
ist 64 endlich 64, egal wie ich den Prescaler erzeuge. Werde nun die 
einzelnen Code-Teile wieder einzeln ergänzen und hoffen dass es dann 
läuft. Falls es wieder Probleme gibt melde ich mich wieder hier. Danke 
euch allen für eure schnelle Hilfe
Gast #2358111
Lesenswert?

So... Habe schon ein neues Problem an dem ich nun schon 2h hänge. Ich 
habe eine Rampe über die ich den Schrittmotor beschleunige. Wenn ich die 
Schaltung an die Versorgung anhänge läuft mir der Motor manchmal auf die 
Solldrehzahl an doch meistens Ruckelt er nur ein bischen, bleibt stehen 
und die Schaltung zieht um die 3A (über die Sens-Widerstände ist der 
Strom auf 1,5A/Windung begrenzt) und manchmal sogar 5A (max. Strom des 
Netzgerätes). Wenn man die Versorgungsspannung entfernt und neu 
anschließt und der Motor schafft seinen Start benötigt die Schaltung bei 
voller Drehzahl des Motors nur 0.15A. Weiß einer von euch woran das 
liegen könnte? Muss der Motor vor dem Start auf die Home-Position 
gebracht werden?

Ich verwende übrigens einen 23LM-C077-02V 
(http://www.mechapro.de/pdf/23LM-C077V.pdf) und einwen ATmega2561. Anbei 
ist auch noch der vollständige C-Code ;-) (Leider ein wenig 'Dirty' aber 
ich hoffe ihr kennt euch aus):
1
#include <util/delay.h> //(bei älteren Versionen avr/delay.h)
2
#include <stdbool.h>
3

4
#include "lcd-routines.h"
5
#include <avr/io.h>
6
#include <avr/interrupt.h>
7
#include <stdlib.h>  // for itoa() call
8
#include <stdio.h>  // for printf() call
9

10

11
//globale variablen
12
//=================
13
  //Timer interrupt
14
  volatile unsigned int cnt_t0=0;    //interrupt zähler für Timer0
15
  volatile unsigned int rampe=80;
16
  volatile unsigned int cnt_rampe=0;
17

18
ISR(TIMER0_OVF_vect)
19
  {  //Schrittmotor-Interrupt
20
  
21
  cnt_t0++;
22
  
23
  
24
  
25
  if(cnt_t0>=rampe)  
26
    {
27
    cnt_rampe++;
28
    if(cnt_rampe>=200 && rampe>18) 
29
      {
30
      rampe--;
31
      cnt_rampe=0;
32
      }
33

34
    cnt_t0=0;
35
    //Schrittmotor ansteuern
36
    //######################  
37
    if(PORTC%2)
38
      {
39
      PORTC&=0xFE;
40
      }
41
    else
42
      {
43
      PORTC|=0x01;
44
      }
45

46
    }  
47
  }
48

49
void init_timer(void)
50
  {
51
  cli();             //Interrupt generell sperren
52
  
53
  //Timer0 initialisieren
54
  //=====================
55
  cnt_t0 = 0;
56
  cnt_rampe=0;
57
  rampe=80;
58
  TCCR0B=(1<<CS00); //CS0: no Prescaler=256;
59
  TIMSK0|=(1<<TOIE0);           //Overflow Interrupt einschalten
60
    
61
  sei();               //Interrupt generell zulassen
62
  }
63
    
64
void init_io(void)
65
  {
66
  //Ein/ Ausgänge setzen
67
  //====================
68
  
69
  DDRA =0xFF;      //PortA als ausgang Setzen
70
  DDRD|=0x03;     //PD0 und PD1 als ausgang setzen
71
  DDRC=0x0F;       //PC0 - PC3 als ausgang setzen, PC4-PC7 als eingang
72
  
73
  DDRG|=0x02;    //PG1 als Ausgang definieren
74
  PORTG&=0xFD;  //PG1 0 setzen --> immer write
75
  }
76
  
77
void init_stepmotor(void)
78
  {
79
  //PC1...CW/~CCW...   0 --> im Uhrzeigersinn
80
  //PC2...HALF/~FULL...0 --> ganzer schritt
81
  //PC3...CTL...       1 --> für ABCD
82
  PORTC=0x08;
83
  }
84
  
85
int main(void)
86
  {
87
  init_timer();
88
  init_io();
89
  lcd_init();
90
  init_stepmotor();
91
  
92

93
  lcd_write2pos(0,2,"Motor           ");
94
  lcd_write2pos(0,3,"startet!!       ");
95
  
96
  while(1)
97
    {
98
    //  auf interrupt warten
99
    }
100
return 0;    //never reach this!
101
}
Gast #2359884
Lesenswert?

So gehts natürlich einfacher (kürzer). Habe noch nie die 
bitweise-XOR-Funktion verwendet deswegen kam ich auch gar nicht auf die 
Idee nach soetwas zu suchen. Vielen dank für diese Verschönerung aber 
das Problem löst dies leider noch nicht ;-)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren