Forum: Compiler & IDEs Unnötige Warteprozedur?


von Valentin B. (nitnelav) Benutzerseite


Lesenswert?

In dem "Lehrheft LCD Programmierung" von myavr wird für fast jedes 
Beispiel die folgende Warteprozedur als benötigt angegeben:
1
#define F_CPU 3686400
2
#include <util/delay.h>
3
#include <avr/io.h>
4
//...
5
void wait_ms(int miliSec)
6
{
7
_delay_loop2(1*(F_CPU/(1000/4))*miliSec); //4 Zyklen Warteschleife
8
}
wäre folgendes nicht viel einfacher:
1
#define F_CPU 3686400
2
#include <util/delay.h>
3
#include <avr/io.h>
4
//...
5
//und dann an jeder betreffenden Stelle
6
//statt wait_ms(miliSec) 
7
_delay_ms(miliSec)
Ich verstehe nicht ganz den Sinn der oberen Anweisung.
Zuersteinmal könnte man die Zeile doch auf
1
 
2
_delay_loop2((F_CPU/250)*miliSec);//4 Zyklen Warteschleife
kürzen und warum noch eine Wartefunktion für Milisekunden 
implementieren?
Könnt ihr mir da helfen??
Der einzige Grund, warum ich mich noch einmal mit diesem wirren Quatsch 
beschäftige, ist, dass ich die Ausrüstung von myAVR noch da habe und 
jetzt mal als Testboard verwenden will.
Mit freundlichen Grüßen,
Valentin Buck

von Karl H. (kbuchegg)


Lesenswert?

Valentin Buck schrieb:

> wäre folgendes nicht viel einfacher:
>
1
> #define F_CPU 3686400
2
> #include <util/delay.h>
3
> #include <avr/io.h>
4
> //...
5
> //und dann an jeder betreffenden Stelle
6
> //statt wait_ms(miliSec)
7
> _delay_ms(miliSec)
8
>

Im Prinzip ja ... wenn es da nicht zwei Einschärnkung bei _delay_ms 
gäbe:
Zum einen muss der Optimizer zwingend eingeschaltet werden, ansonsten 
stimmen die Zeiten nicht.
Zum anderen darf als Argument an _delay_ms nur eine Konstante übergeben 
werden. Ansonsten stimmen die Zeiten wieder nicht.

Dem 2-ten Punkt könnte man durch
1
void _delay( int ms )
2
{
3
  int i;
4
  for( i = 0; i < ms; ++i )
5
    _delay_ms( 1 );
6
}
etwas entgegenwirken. Aber den ersten Punkt (Optimizer) wird man so 
nicht los.

> Ich verstehe nicht ganz den Sinn der oberen Anweisung.
> Zuersteinmal könnte man die Zeile doch auf
>
1
> _delay_loop2((F_CPU/250)*miliSec);//4 Zyklen Warteschleife
2
>
> kürzen

könnte man.
Aber dann würdest du fragen, wo eigentlich die 250 her kommen.

von Valentin B. (nitnelav) Benutzerseite


Lesenswert?

Ahh, OK.
Danke für die schnelle Antwort.
Ich glaube, im Tutorial HIER für die LCD-Ansteuerung in GCC bin ich 
deutlich besser aufgehoben.
Muss nur noch die Ports rausfinden, die benutzt werden.
Ich hab mir jetzt mal den Rest von dem Quatsch angesehen und habe 
herausgefunden, dass mit AVR-Studio und GCC da gar kein Durchkommen ist.
Zum Beispiel verwenden die extrem häufig die Funktion sbi(PORT,Bit) oder 
cbi(PORT,Bit). Problem dabei: Die gibts doch gar nicht in GCC???
Ich bin echt froh, dass wir hier ein so gutes Forum und so geniale 
Tutorials haben. Ohne Mikrocontroller.net wäre ich in 10 Jahren noch 
nicht fertig...
Mit freundlichen Grüßen,
Valentin Buck

von Karl H. (kbuchegg)


Lesenswert?

Valentin Buck schrieb:

> herausgefunden, dass mit AVR-Studio und GCC da gar kein Durchkommen ist.
> Zum Beispiel verwenden die extrem häufig die Funktion sbi(PORT,Bit) oder
> cbi(PORT,Bit). Problem dabei: Die gibts doch gar nicht in GCC???

Sind aber leicht zu machen
1
#define sbi(port,bit)   (port) |= (1<<(bit))
2
#define cbi(port,bit)   (port) &= ~(1<<(bit))

Zur Ehrenrettung: die Funktionen gab es früher einmal. Damals war 
anscheinend der Optimizer noch nicht soweit, dass er die obigen 
C-konformen Konstrukte in die AVR spezifischen Spezialanweisungen sbi 
und cbi umsetzen konnte. Daher hat man dem Compiler ein bischen unter 
die Arme gegriffen.

von Valentin B. (nitnelav) Benutzerseite


Lesenswert?

Danke!!! Jetzt wird mir vieles klarer.
Ich bräuchte da trotzdem noch ein wenig Hilfe:
In dem Tutorial steht in der lcd-routines.h
folgendes:
1
// DB4 bis DB7 des LCD sind mit PD0 bis PD3 des AVR verbunden
In dem myAVR-Heft steht aber PD4 bis PD7 sind mit DB4 bis DB7 verbunden.
Wo kann ich das ändern?
Mit freundlichen Grüßen,
Valentin Buck

von Oliver (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Sind aber leicht zu machen
> #define sbi(port,bit)   (port) |= (1<<(bit))
> #define cbi(port,bit)   (port) &= ~(1<<(bit))

Sind sogar noch leichter zu machen:
1
#include <compat/deprecated.h>

Oliver

von Karl H. (kbuchegg)


Lesenswert?

Valentin Buck schrieb:
> Danke!!! Jetzt wird mir vieles klarer.
> Ich bräuchte da trotzdem noch ein wenig Hilfe:
> In dem Tutorial steht in der lcd-routines.h
> folgendes:
1
> // DB4 bis DB7 des LCD sind mit PD0 bis PD3 des AVR verbunden
2
>
> In dem myAVR-Heft steht aber PD4 bis PD7 sind mit DB4 bis DB7 verbunden.
> Wo kann ich das ändern?


Die sind leider in den Tutorial Routinen fix vercodet und bis jetzt hat 
sich noch niemand gefunden, der das endlich mal behebt :-) (*)

Die Belegung wirkt sich in den Funktionen
lcd_data
lcd_command
aus. Die basieren auf dieser Zuordnung.
Ausserdem ist der Anfang der lcd_init auf diese Belegung angewiesen

(*) Wäre gar nicht so schwer, das zu beheben. Der Schlüssel ist eine 
neue Funktion
void lcd_nibble( uint8_t nibble );
die ein Nibble auf die entsprechenden Pins aufteilt und die von den 
genannten Stellen benutzt wird.

Wenn du drann bleibst, mach ich mal einen Vorschlag, den du testen 
kannst und den wir dann ins Tutorial übernehmen.



Edit:
Hab mich geirrt, hier gibt es schon eine entsprechende Erweiterung
http://www.mikrocontroller.net/articles/Erweiterte_LCD-Ansteuerung

von Valentin B. (nitnelav) Benutzerseite


Lesenswert?

Die Erweiterung ist ja super!!!
DANKE!!!
Es funktioniert!
Mit freundlichen Grüßen,
Valentin Buck

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.