Forum: Mikrocontroller und Digitale Elektronik ATmegaSTepper und Timer1


von orgsi1990 (Gast)


Lesenswert?

Hallo,

ich habe ein kleines Problem bin zurzeit dabei einen 3d drucker zu bauen 
und wollte einen stepper dazu nehmen.

Nur leider habe ich das Problem das

1. Es unsauberer läuft als wenn ich jeden pin einzeln anschalte mit 
einem delay dazwischen.

2.Es sobald eine endlage kommt der motor zurück dreht aber dann doch 
wieder in die andere richtung fährt und das verändern der data garnicht 
realisiert also in int0 und int1.

Bin etwas am verzweifeln und etwas ratlos.
1
#define F_CPU 1000000UL
2
#include <util/delay.h>
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
6
void vor (int data);
7
void back (int data);
8
void int0(void);
9
void int1(void);
10
void timer (int Laufzeit);
11
void timer_stop(void);
12
13
int speed=250,endvorn=0,endhinten=0;      //Prescaler ist auf 1024 und speed=250
14
volatile int data=100,timer_zaehler,iMerker=1;  //daten 100 mal
15
16
17
static uint8_t Werte[] ={0b00001000,
18
  0b00001100,
19
  0b00000100,
20
  0b00000110,
21
  0b00000010,
22
  0b00000011,
23
0b00000001};
24
25
int main()
26
{
27
  
28
  int0();    //Sensoren intialisierung
29
  int1();
30
  DDRC= 0x0f;
31
  
32
  while(1)
33
  {
34
    
35
    if((data>0)&(endhinten==0)&(endhinten==0))
36
    {vor(data);}
37
    if((data<0)&(endhinten==0)&(endhinten==0))
38
    {back(data);}
39
    
40
    if (endhinten==1)
41
    {
42
      data=0;
43
      endhinten=0;
44
    }
45
    if (endvorn==1)
46
    {
47
      data=0;
48
      endvorn=0;
49
    }
50
  }
51
}
52
53
void vor (int data)
54
{
55
  int i=0;
56
  
57
  for (i=0;i<data;i++)
58
  {  PORTC = Werte[timer_zaehler];
59
    timer_zaehler=timer_zaehler+1;
60
    if( timer_zaehler == 7 )
61
    {timer_zaehler = 0;}
62
    timer (speed);
63
    if (endvorn==1)break;
64
    
65
  }
66
  
67
}
68
void back (int data)
69
{
70
  int i=0;
71
  
72
  for (i=0;i>data;i--)
73
  {
74
    if( timer_zaehler == 0 )
75
    {timer_zaehler = 7;}
76
    PORTC = Werte[timer_zaehler];
77
    timer_zaehler=timer_zaehler-1;
78
    timer (speed);
79
    if (endhinten==1)break;
80
    
81
  }
82
  
83
}
84
void int0(void)
85
{
86
  PORTD|=0x04;    //PD2(INT0)
87
  GICR|=(1<<INT0);  //aktivieren des int0
88
  MCUCR|=(1<<ISC01);  //jede fallende
89
  sei();
90
}
91
void int1(void)
92
{
93
  PORTD|=0x08;    //PD3(INT1)
94
  GICR|=(1<<INT1);  //aktivieren des int1
95
  MCUCR|=(1<<ISC10);  //jede fallende
96
  sei();
97
}
98
99
void timer (int Laufzeit)
100
{
101
  iMerker=1;
102
  OCR1A=Laufzeit;              //Compare register 24 für 3.135ms
103
  TCCR1B=(1<<CS10)|(1<<CS12)|(1<<WGM12);  //Prescaler 1024 wegen cs12 cs10 für 64 cs11/cs10
104
  //Timer stop cs12/cs11/cs10 alle 0
105
  TIMSK |= (1<<OCIE1A);          //COMPARE A
106
  sei();
107
  while (iMerker){};            //solang merker warten und dann beenden
108
  timer_stop();
109
}
110
void timer_stop(void)
111
{
112
  TCCR1B&=~(1<<CS10)&(~(1<<CS11))&(~(1<<CS12));//Timer Stop
113
}
114
ISR(INT0_vect)
115
{  data=20;
116
  vor(data);
117
  endvorn=1;
118
}
119
ISR(INT1_vect)
120
{
121
  data=-20;
122
  back(data);
123
  endhinten=1;
124
}
125
ISR(TIMER1_COMPA_vect)
126
{
127
  iMerker=0;
128
}

Danke für eure mühen ich glaube ich stehe einfach etwas auf dem schlauch 
gerade. Wichtig wäre mir eben warum er nicht abbricht und immer weiter 
läuft.

von spess53 (Gast)


Lesenswert?

Hi

>static uint8_t Werte[] =
> {0b00001000,
>  0b00001100,
>  0b00000100,
>  0b00000110,
>  0b00000010,
>  0b00000011,
>  0b00000001};

Das sind nur 7 Werte. Bei Halbschritt sind es aber 8 Werte.

MfG Spess

von Thomas E. (thomase)


Lesenswert?

In deinem Programm sind ein paar Knoten drin, die es etwas schwierig 
machen, den Ablauf zu verstehen. Neben dem, was Spess schon anmerkte, 
aber das ist wohl eher das kleinere Problem, hast du da einen ganz 
dicken Hund eingebaut.

orgsi1990 schrieb:
> ISR(INT0_vect)
> {  data=20;
>   vor(data);
>   endvorn=1;
> }

Du darfst vor(data) nicht in der ISR ausführen. Denn diese Funktion ruft 
wiederum den Timer auf, der letztlich darauf wartet, dass ein Interrupt, 
nämlich sein eigener, kommt. Der kann aber nicht in seine ISR gehen, 
weil das Ganze sich alles in einer ISR, nämlich INTx abspielt und alle 
weiteren Interrupts bis zu deren Ende gesperrt sind. Die Katze beisst 
sich also in den Schwanz. Das gilt für back genauso.

Setze in den INT-ISRs jeweils ein Flag und starte die vor und back in 
main. Dann kommt auch dein Timer-Interrupt.
Das mit dem Timer ist allerdings völlig daneben. Das ist nichts anderes 
als ein obskures Delay. Aber lass das erstmal so stehen und bring das 
mit dem achten Wert und vor allem mit den Aufrufen in Ordnung.

mfg.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

orgsi1990 schrieb:
> ich habe ein kleines Problem bin zurzeit dabei einen 3d drucker zu bauen
> und wollte einen stepper dazu nehmen.

 Erst waren es angeblich LEDs, daran bist du gescheitert, jetzt ist es
 gleich ein 3D Drucker mit Stepper und das soll klappen ?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.