Forum: Mikrocontroller und Digitale Elektronik Problem bei kleinem Versuch mit avr Atmega8


von Lukas K. (owarec)


Lesenswert?

Hallo Liebe Forengemeinde,

Ich habe ein kleines (Verständniss) Problem bei einem Kleinen Versuch 
mit dem Atmega8 in der Atmel Studio 7 Umgebung.


Ich möchte für mein Technikerprojekt 3 Schrittmotoren über den Atmega8 
ansteuern. Die Grundprinzipien zur Ansteuerung habe ich verstanden. Ich 
hab ein kleines Programm in C++ geschrieben womit ich einen der Motoren 
auch per Knopfdruck Links oder Rechts laufen lassen kann. Die Vorgabe 
ist leider dass das Programm in C geschrieben werden muss.

Und genau hier ist das Problem, ich möchte über eine For-Schleife den 
Motor eine bestimmte Zeit laufen lassen. Die Funktion der For-Schleife 
ist bekannt.

Da ich leider keinerlei Erfahrung mit der Deklaration der einzelnen 
Ports habe denke ich das ich hier einen Fehler gemacht habe.

Folgenden Code benutze ich zurzeit:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <stdint.h>
4
5
int main(void)
6
{
7
  
8
  int hoch;
9
  //int runter;
10
11
12
  //DDRD &= ~( (1<<PD2) | (1<<PD3) ); //PA0 und PA3 als Eingaenge 
13
    //PORTD |= (1<<PD2) | (1<<PD3);    //Interne Pull-Up fuer beide einschalten
14
  
15
  DDRB |= ( (1<<PB0) | (1<<PB1) | (1<<PB2) | (1<<PB3) ); // PORTB BIT 0..3 als Ausgang
16
17
   
18
    while (1) 
19
    {
20
21
  PORTB &= ~(1<<PB2); // Freigabe auf 0 Forcen
22
  PORTB |= (1<<PB1); // Zum Test nur Rechtslauf
23
24
  for (hoch=0;hoch<=5000;hoch++)
25
  {
26
    PORTB |= (1<<PB0);
27
    _delay_ms(1);
28
    PORTB &= ~(1<<PB0);
29
  }
30
31
32
  
33
34
35
    }
36
}

Als Motor benutze ich einen Schrittmotor mit 1.5A, 1,8° und 24VDC der 
Treiber ist ein TB6560 CNC Router 1 Axis 3A.

Ich hoffe das ihr mir bei meinem ,wahrscheinlich kleinem, Problem hlefen 
könnt.



Lg

Lukas

von Georg G. (df2au)


Lesenswert?

Lukas K. schrieb:
>     PORTB |= (1<<PB0);
>     _delay_ms(1);
>     PORTB &= ~(1<<PB0);
!!!   _delay_ms(1);          !!!

Wie lange wird der Port wohl auf LOW bleiben? Da fehlt wohl ein delay 
nach dem setzen auf LOW.

von Lukas K. (owarec)


Lesenswert?

Hallo,

vielen Dank erstmal für deine Antwort


Ich habe den Code in C++ (Natürlich nach C++ "Standart") genau so 
geschrieben ohne das zweit _delay_ms(1); und da funktioniert es 
wunderbar.

Ich bin mir nicht sicher ob ich alle Ports und Pins richtig zugewiesen 
habe und ansteuere.




Lg

Lukas

von Georg G. (df2au)


Lesenswert?

Ohne das zweite Delay hast du am Pin eine Impulsnadel von 100ns oder 
weniger.  Wenn dein Treiber und dein Motor das können... super.

von Dieter F. (Gast)


Lesenswert?

Scharf wäre schon mal, wenn Du "Edit -> Advanced -> Format Document" 
nutzen würdest.

Was genau funktioniert denn nicht - und wie sieht Dein Aufbau 
(Schaltplan) aus?

Ich vermute auch mal, dass der Motor ohne das 2. delay ein wenig 
verschnupft reagieren wird.

Hast Du im Projekt F_CPU definiert? Falls nicht solltest Du das im 
Programm unbedingt nachholen, da die delay-Funktion sonst nicht richtig 
funktionieren kann. Die delay-Funktion "nimmt" dann 1MHz an.

Oh, fast vergessen, der Motor wird sich permanent drehen, da die 
FOR-Schleife innerhalb der WHILE-Schleife immer wieder ausgeführt wird 
...

von Lukas K. (owarec)


Angehängte Dateien:

Lesenswert?

Also ich habe keine probleme ohne das zweite _delay. Liegt vielleicht 
auch daran das ich hier noch keine große erfahrung habe. Ich werde es 
mal mit dem zweiten _delay probieren. Danke dafür.

Die F_CPU wird am anfang wenn man was Projekt einrichtet doch definiert, 
oder nicht ?


Was nicht funktioniert -> das Komplette Programm.

Wenn ich es übersetze und brenne tut sich nichts.

Im Anhang der momentane Aufbau, leider mit Paint da ich kein geeignetes 
Programm habe.


Lg

Lukas

von Dieter F. (Gast)


Lesenswert?

Lukas K. schrieb:
> Wenn ich es übersetze und brenne tut sich nichts.

Und wie willst Du dann das beurteilen?

Lukas K. schrieb:
> Also ich habe keine probleme ohne das zweite _delay.

Lukas K. schrieb:
> Die F_CPU wird am anfang wenn man was Projekt einrichtet doch definiert,
> oder nicht ?

Wenn Du das nicht explizit machst - woher soll das Atmel-Studio denn 
wissen, welchen Takt Du am Prozessor anliegen hast?

Lass mal Freigabe unbeschaltet und lege "rechts" auf GND. Und baue das 
delay ein!

Hast Du den Schrittmotor korrekt angeschlossen?

von Lukas K. (owarec)


Lesenswert?

Ich habe jetzt nocheinmal F_CPU definiert, beim Compilieren sagt er mir 
jedoch "F_CPU" redefined.

Freigabe ist nun unbeschaltet und rechts liegt auf GND. das zweite 
_delay ist auch eingebaut. Der Erfolg bleibt leider aus.

von Amateur (Gast)


Lesenswert?

Ein Mikrokontroller ist nicht nur schneller als ein Motor sondern sehr 
viel schneller.

Aus diesem Grunde sollte die Schrittschleife folgendermaßen aussehen:
1) Setze Pin
2) Warte etwas
3) Lösche Pin
4) Warte etwas
5) Weiter bei 1) durch "for" oder Schleifenende

Das generierte Signal wird dadurch sehr symmetrisch. D. h. die 
"ein"-Zeit ist genauso lange wie die "aus"-Zeit.

In Deiner Schleife war die "ein"-Zeit normal - was auch immer das Heißt 
- und die "aus"-Zeit extrem kurz.

von Walter S. (avatar)


Lesenswert?

Lukas K. schrieb:
> Ich habe den Code in C++ (Natürlich nach C++ "Standart") genau so
> geschrieben ohne das zweit _delay_ms(1); und da funktioniert es
> wunderbar.

perfekt, dann nimm das funktionierende Programm als Vorlage

von Lukas K. (owarec)


Lesenswert?

So ich habe nun das C++ Programm was ja läuft als vorlage genutzt.

mein Code sieht jetzt folgendermaßen aus :
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <util/delay_basic.h>
4
5
6
int main(void)
7
{
8
  DDRB |= (1<<PINB0); // Pulse
9
  DDRB |= (1<<PINB1);// Rechts
10
  DDRB |= (1<<PINB2);// Freigabe
11
  DDRB |= (1<<PINB3);// Links
12
13
  DDRD &= ~(1<<PIND2); // Taster 1
14
  DDRD &= ~(1<<PIND3); // Taster 2
15
16
  PORTD |= (1<<PIND2); // Pull-Up Taster 1
17
  PORTD |= (1<<PIND3); // Pull-Up Taster 2
18
19
20
  PORTB &= ~(1<<PINB2); // Freigabe forcen
21
  
22
  if ( !(PIND & (1<<PIND2))) // Wenn Taster 1 gedrückt ist
23
  {
24
    PORTB &= ~(1<<PINB3); // Sperren Links
25
    PORTB |= (1<<PINB1); // Setzen Rechts
26
27
    PORTB |= (1<<PINB0); // Pulse-Ein
28
    _delay_ms(1);
29
    PORTB &= ~(1<<PINB0); // Pulse-Aus
30
    _delay_ms(1);
31
32
  }
33
  else
34
  {
35
    if ( !(PIND & (1<<PIND3))) // Wenn Taster 2 gedrückt ist
36
    {
37
      PORTB &= ~(1<<PINB1); // Sperre Rechts
38
      PORTB |= (1<<PINB3); // Setzen Links
39
40
      PORTB |= (1<<PINB0); // Pulse-Ein
41
      _delay_ms(1);
42
      PORTB &= ~(1<<PINB0); // Pulse-Aus
43
      _delay_ms(1);
44
    }
45
46
  }
47
48
49
50
51
}


Habe die Einschaltfunktion jetzt erstmal über die zwei Taster die 
onBoard sind gelöst.

Funktioniert leider immer noch nicht.

Habe ich eventuell einen Fehler bei der Zuweisung der Ports gemacht oder 
beim beschalten der Ausgänge ?

von Mitlesa (Gast)


Lesenswert?

Lukas K. schrieb:
> Funktioniert leider immer noch nicht.

Und wo ist deine for-Schleife geblieben? Du meinst die
kennt der Prozessor jetzt schon?

von Thomas E. (thomase)


Lesenswert?

Mitlesa schrieb:
> Und wo ist deine for-Schleife geblieben?

Die ist mit der while-Schleife durchgebrannt.

von Lukas K. (owarec)


Lesenswert?

Mitlesa schrieb:
> Und wo ist deine for-Schleife geblieben? Du meinst die
> kennt der Prozessor jetzt schon?


Die "Die Einschaltfunktion" habe ich jetzt erstmal über die zwei onBoard 
Taster gelöst.

Thomas E. schrieb:
> Die ist mit der while-Schleife durchgebrannt.

Die habe ich tatsächlich vergessen :/

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


Lesenswert?

Lukas K. schrieb:
> Freigabe ist nun unbeschaltet und rechts liegt auf GND. das zweite
> _delay ist auch eingebaut. Der Erfolg bleibt leider aus.

 Normalerweise steht da etwas anderes und nicht rechts bzw. Freigabe.

 Also:
===============================
 EN- und EN+   nicht verbinden.
 CW- und CLK-  auf GND.

 CW+           auf PB1.
 CLK+          auf PB0.

 S3            OFF.
 S4            ON.
===============================

 Delay nach "    PORTB &= ~(1<<PB0);" wie Georg G. schon schrieb.
 Und dann muss es klappen.

> Ich habe den Code in C++ (Natürlich nach C++ "Standart") genau so
> geschrieben ohne das zweit _delay_ms(1); und da funktioniert es
> wunderbar.

 Erstens glaube ich das nicht und zweitens ist es "Standard".

von Lukas K. (owarec)


Lesenswert?

Marc V. schrieb:
>  Delay nach "    PORTB &= ~(1<<PB0);" wie Georg G. schon schrieb.
>  Und dann muss es klappen.

Das Programm läuft, nach einfügen der while(1)Schleife hat es geklappt 
:).

Marc V. schrieb:
> Normalerweise steht da etwas anderes und nicht rechts bzw. Freigabe.

Selbstverständlich steht das nicht so da wie ich es geschrieben habe. 
Habe es aber so beschrieben das die Belegung eindeutig ist und nicht zu 
Missverständissen führt.

Marc V. schrieb:
> S3            OFF.
>  S4            ON.

Dadurch würde der Motor im 16tel Schritt laufen, S3 OFF und S4 OFF wären 
vollschritt.



Marc V. schrieb:
> Erstens glaube ich das nicht und zweitens ist es "Standard".

Ich kann dir gerne den Code zeigen und dazu ein Video machen :D ( Ist 
nicht böse gemeint, bitte nicht Falsch verstehen :) )

Also das programm läuft nun, sowohl mit Taster als auch mit 
For-Schleife, nun muss ich es nur noch hinbekommen das durch den 
Tastendruck die Schleife eigenständig durchläuft.

Vielen Dank an alle die mir hier geholfen haben.


Lg
Lukas

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.