mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Optimierung bei delay.h


Autor: marcel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nabend

Ich habe auch ein Problem bezueglich der Optimierung der Schleifen.
Habe nun gut ne Stunde gesucht, bis ich rausgefunden habe, dass meine 
Delayschleifen beim Initialisieren des LCD's vom Compiler wegoptimiert 
werden.

Nein, ich verwende keine eigene Schleifen sondern wie empfohlen die aus 
util/delay.h

Mit eingestellten -O0 funktioniert alles (auch wenn die delay.h wohl 
nicht absolut genau arbeitet) sobald ich jedoch auf -Os gehe, tut gar 
nix mehr.

Hat jemand eine Idee an was das problem liegen kann?

Im Einsatz sind:
AVR-Studio Version 4.14 und WinAVR 20090313

Autor: marcel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh!
Ich habe mich auf folgenden Beitrag bezogen
Beitrag "Warteschleife mit C - wird von WinAVR wegrationalisiert!"

Nur auf "neuer Beitrag" anstatt "Antworten" gedrueckt. War ein langer 
Arbeitstag ...

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bitte Quellcode posten?

Autor: Εrnst B✶ (ernst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
marcel schrieb:
> Mit eingestellten -O0 funktioniert alles (auch wenn die delay.h wohl
> nicht absolut genau arbeitet) sobald ich jedoch auf -Os gehe, tut gar
> nix mehr.

mit -O0 ist "nicht absolut genau" eine Untertreibung. Je nach Parameter 
liegt die Delay-Time damit um einen Faktor 1000 daneben.
nur mit Optimierung kommt eine richtige Delay-Zeit heraus.

Du hast nicht zufällig ms und µs in den Parametern verwechselt, und das 
Delay war mit -O0 nur rein zufällig "richtig"?

Autor: marcel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Prinzipiell der Code aus dem LCD AVR-GCC Tutorial

lcd.h:
#ifndef F_CPU
#define F_CPU 16000000UL     /* Quarz mit 16 Mhz */
#warning "F_CPU not defined. Define default Value 16Mhz"
#endif

//Default Port Definitions
#ifndef LCD_PORT
#define LCD_PORT  PORTA
#warning "LCD_PORT not defined. Define default Value Port A"
#endif

#ifndef LCD_DDR
#define LCD_DDR    DDRA
#warning "LCD_DDR not defined. Define default Value DDRA"
#endif

#ifndef PIN_RS
#define PIN_RS    4
#warning "PIN_RS not defined. Define default Value 4"
#endif

#ifndef PIN_E
#define PIN_E    5
#warning "PIN_E not defined. Define default Value 5"
#endif

//LCD Commands
#define LCD_CURSOR_HOME    2
#define LCD_CLEAR_DISPLAY  1

//LCD Functions
void lcd_enable(void);
void lcd_init(void);
void lcd_cmd(unsigned char);
void lcd_data(unsigned char);
void lcd_clear(void);
void lcd_home(void);

lcd.c:
#include <avr/io.h>
#include "lcd.h"
#include <util/delay.h>

void lcd_enable(void)
{
  LCD_PORT |= (1 << PIN_E);
  _delay_us(1);
  LCD_PORT &= ~(1 << PIN_E);
}

void lcd_init(void)
{
  LCD_DDR = (LCD_DDR | 0x0F | 1<<PIN_E | 1<<PIN_RS);

  _delay_ms(15);    //Wait for LCD Initialization

  //Initialize LCD
  LCD_PORT &= 0xF0;
  LCD_PORT |= 0x03;
  LCD_PORT &= ~(1<<PIN_RS);

  lcd_enable();
  _delay_ms(5);

  lcd_enable();
  _delay_ms(1);

  lcd_enable();
  _delay_ms(1);

  //4bit Mode
  LCD_PORT &= 0xF0;
  LCD_PORT |= 0x02;
  lcd_enable();
  _delay_ms(1);

  lcd_cmd(0x28);     //Config - 4bit, 2/4 Lines, 5x7 Font
  lcd_cmd(0x0C);    //Config - Display on, Cursor Off
  lcd_cmd(0x06);    //Config - LTR, scroll Display

  lcd_clear();
}

void lcd_cmd(unsigned char cmd)
{
  unsigned char tmp = cmd;

  LCD_PORT &= ~(1<<PIN_RS);

  tmp = tmp >> 4;
  tmp &= 0x0F;
  LCD_PORT &= 0xF0;
  LCD_PORT |= tmp;
  lcd_enable();

  cmd &= 0x0F;
  LCD_PORT &= 0xF0;
  LCD_PORT |= cmd;
  lcd_enable();

  _delay_us(42);
}

void lcd_data(unsigned char data)
{
  unsigned char tmp = data;
  LCD_PORT |= (1<<PIN_RS);

  tmp = tmp >> 4;
  tmp &= 0x0F;
  LCD_PORT &= 0xF0;
  LCD_PORT |= tmp;
  lcd_enable();

  data &= 0x0F;
  LCD_PORT &= 0xF0;
  LCD_PORT |= data;
  lcd_enable();

  _delay_us(42);
}

void lcd_clear(void)
{
   lcd_cmd(LCD_CURSOR_HOME);
   _delay_ms(5);
}
void lcd_home(void)
{
   lcd_cmd(LCD_CLEAR_DISPLAY);
   _delay_ms(5);
}

der Aufruf sieht folgendermassen aus (test.c):
#ifndef F_CPU
#define F_CPU     16000000UL     /* Quarz mit 16 Mhz */
#endif

#define LCD_PORT  PORTA
#define LCD_DDR    DDRA
#define PIN_E    PINA5
#define PIN_RS    PINA4

#include "lcd.h"
#include <avr/io.h>
#include <util/delay.h>

int main (void) {
  lcd_init();

  lcd_data('T');
  lcd_data('e');
  lcd_data('s');
  lcd_data('t');

  while(1) { }
  return 0;
}


Autor: Εrnst B✶ (ernst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und die Delay-Werte passen auch zu deinem LCD? Datenblatt?
Versuch einfach mal die Delay-werte alle zu verdoppeln, schau ob es dann 
geht. Dann kannst du dich immer noch an bessere Werte rantasten.
Oder (noch besser): Nimm eine LCD-Library mit Auswertung des 
LCD-Status-Bits, da gehts dann großteils ohne Warten.
Und schalte die Compiler-Warnings ein, und achte auf diese! Der Compiler 
spuckt die nicht zum Spaß aus...

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Oder (noch besser): Nimm eine LCD-Library mit Auswertung des
>LCD-Status-Bits, da gehts dann großteils ohne Warten.

Selten einen größeren Unsinn gelesen.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
holger schrieb:
>>Oder (noch besser): Nimm eine LCD-Library mit Auswertung des
>>LCD-Status-Bits, da gehts dann großteils ohne Warten.
>
> Selten einen größeren Unsinn gelesen.

Was stimmt denn daran nicht? Man kann das Bit auch pollen und die Daten 
aus einem Puffer rübersenden, dann braucht man nicht drauf warten.

Autor: marcel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab die Werte nun vervierfacht und es macht keinen Unterschied!

Wenn ich mir die hex file nehme und disassemble, seh ich ja, dass die 
schleifen komplett wegoptimiert wurden.
Der Programmablauf an sich passt, nur die Schleifen tauchen in der 
disassembly einfach nicht auf.

Autor: marcel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach ja ... ich vergas zu erwaehnen, dass der compiler keine warnings 
wirft, ausser dass meine eigenen Varriablen nicht definiert sind und 
daher auf die default werte gesetzt werden (da ich die ja aber auch 
selbst definiere passen die auch ;)

Autor: Εrnst B✶ (ernst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
marcel schrieb:

> Der Programmablauf an sich passt, nur die Schleifen tauchen in der
> disassembly einfach nicht auf.

Ups. Das sollte nun wirklich nicht passieren.
Schau mal nach nem WinAVR-Update, oder hol dir aktuelle util/delay.h und 
util/delay_basic.h - Dateien vom avr-libc server.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>>Oder (noch besser): Nimm eine LCD-Library mit Auswertung des
>>>LCD-Status-Bits, da gehts dann großteils ohne Warten.
>>
>> Selten einen größeren Unsinn gelesen.

>Was stimmt denn daran nicht? Man kann das Bit auch pollen und die Daten
>aus einem Puffer rübersenden, dann braucht man nicht drauf warten.

Das Statusbit kann man am Anfang der LCDInit gar nicht pollen.
Steht jedenfalls so in meinen Datenblättern zu LCDs.
Pollen des Statusbits bedeutet auch warten.

Autor: marcel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Problem hat sich soeben geloest...

Ich hab mir die Compiler Optionen nochmals genau angesehn und 
festgestellt, dass 16hz anstatt 16000000hz eingestellt waren

Jetzt gehts.

Wieso kann man sowas auch nicht in ner tauglichen Einheit abfragen

maaaan!
Danke an alle

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.