Forum: Mikrocontroller und Digitale Elektronik AVR Studio, Schleifenoptimierung 17,18


von Matze (Gast)


Lesenswert?

Hallo,

Ich versuche gerade im AVR-Studio C++ auf einem AtXmega eine schleife 
zur Verzögerung von ca 1us zu Programmieren.
Problem ist, dass wenn ich in
1
  for(int i=0;i<18;i++)
2
  {
3
    ;
4
  }
i bis 17 Zählen lasse, dies etwa 2,3us dauert.
setze ich
1
i<17
 so sind es nur noch 80ns.

Wenn man
1
for(int i=0;i<13;i++)
2
{
3
  for(int i=0;i<17;i++)
4
  {
5
    ;
6
  }
7
}
setzt bleiben es 80ns;

Hier scheint eine Potimierung am Werk zu sein, die Schleifen <18 einfach 
weglässt.
Wie wird sie abgeschaltet?
1
int readbit()
2
{
3
  PORTF.DIRSET=0x04;  //1 = setzen     --> Ausgang
4
  PORTF.OUTCLR=0x04;  //1 = Rücksetzen --> 0
5
  for(int i=0;i<18;i++)
6
  {
7
    ;
8
  }
9
  PORTF.OUTSET=0x04;  //1 = Setzen --> 1
10
  PORTF.DIRCLR=0x04;  //1 = Setzen --> Eingang
11
  if(PORTF.IN&0x04)
12
  {
13
    PORTF.DIRSET=0x04;  //1 = setzen     --> Ausgang
14
    PORTF.OUTSET=0x04;  //1 = Rücksetzen --> 0
15
    return(1);
16
  }
17
  else
18
  {
19
    PORTF.DIRSET=0x04;  //1 = setzen     --> Ausgang
20
    PORTF.OUTSET=0x04;  //1 = Rücksetzen --> 0
21
    return(0);
22
  }
23
}

von Falk B. (falk)


Lesenswert?

@ Matze (Gast)

>Ich versuche gerade im AVR-Studio C++ auf einem AtXmega eine schleife
>zur Verzögerung von ca 1us zu Programmieren.

Dann nutze besser die Funktion _delay_us();

Die funktioniert.

https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Warteschleifen_.28delay.h.29

von Peter II (Gast)


Lesenswert?

Matze schrieb:
> Wie wird sie abgeschaltet?

gar nicht, man verwenden einfach eine _delay_us ist ist froh das sich 
andere darüber den Kopf zerbrochen haben.

http://www.nongnu.org/avr-libc/user-manual/group__util__delay.html

von Matze (Gast)


Lesenswert?

Ich nutze nun die delay.h und habe sie so eingebunden:

    #include <util/delay.h>
    #define F_CPU 32000000UL  // 32 MHz
1
int readbit()
2
{
3
  PORTF.DIRSET=0x04;  //1 = setzen     --> Ausgang
4
  PORTF.OUTCLR=0x04;  //1 = Rücksetzen --> 0
5
  _delay_us(1);
6
  PORTF.OUTSET=0x04;  //1 = Setzen --> 1
7
  PORTF.DIRCLR=0x04;  //1 = Setzen --> Eingang
8
  if(PORTF.IN&0x04)
9
  {
10
    PORTF.DIRSET=0x04;  //1 = setzen     --> Ausgang
11
    PORTF.OUTSET=0x04;  //1 = Rücksetzen --> 0
12
    return(1);
13
  }
14
  else
15
  {
16
    PORTF.DIRSET=0x04;  //1 = setzen     --> Ausgang
17
    PORTF.OUTSET=0x04;  //1 = Rücksetzen --> 0
18
    return(0);
19
  }
20
}

Der Portpin wird jedoch nur für 80ns zurückgesetzt.
Wenn ich _delay_us(10) mache, sind es etwa 300ns.

von Matze (Gast)


Lesenswert?

Oh, wenn man den CPU-Takt vor dem Include definiert klappt es ;)
    #define F_CPU 32000000UL  // 32 MHz
    #include <util/delay.h>

Danke

von Peter D. (peda)


Lesenswert?

Matze schrieb:
> #include <util/delay.h>
>     #define F_CPU 32000000UL  // 32 MHz

Da solltest Du aber eine dicke Warnung vor den Latz geknallt bekommen.
Machs andersrum!

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.