mikrocontroller.net

Forum: Compiler & IDEs LCD-Initialisierung


Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich hab Probleme mit der Initialisierung meines LCD. Ich benutze den
8535 mit 8MHz.
Ich denke es liegt an den Pausen, die man einlegen muss, weil ich mit
den Verzögerungsschleifen auch noch nicht so recht klarkomme.
Vielleicht könnt ihr euch den Qullcode mal angucken und mir
weiterhelfen. Danke

#include <lcd.h>



#define LCD_BLANK()        {lcd_send_command(1);delay_ms(2);}

#define DISPLAY_ON()     {lcd_send_command(12);}

#define DISPLAY_OFF()     {lcd_send_command(8 v);}

#define nop() asm volatile ("nop")


typedef unsigned char byte;


// Hier befinden sich die Eigenschaften der LCD-Anzeige für die
Initialisierung
byte LCD_INIT_STRING[] = {0x28, 0x0C, 0x01, 0x06};
// 44 = FunktionSet 44 = 0010 1000 = 2C
// 0, 12 = Display an
// 0, 1  = clear Display
// 0, 6 = Entry mode set

//Wartearray für Initialisierung
byte wait[] = {,,};
//5ms, 110us, 110us


int main(void)
{




  //Portbelegung
  //PortA Taster
  outp(0x00, DDRA);

  //PortB LEDs
  outp(0xff, DDRB);
  outp(0x00, PORTB);



  lcd_init();                // Initialisierung der LCD-Anzeige



  lcd_putc(1, "Ein Test");



  for(;;)
  {



      {
        outp(0xf0, PORTB);

      }


  }
}




void lcd_send_nibble( byte n )
{


        outp(n<<4, PORTC);

  sbi(PORTC, 2);  //Enable = 1
           nop();
        cbi(PORTC, 2);  //Enable =0

}

void lcd_send_byte( byte address, byte n )
{
  if(address)
     sbi(PORTC,0);  //RS = 1 ->Daten schreiben
   else
     cbi(PORTC,0);  //RS = 0 ->Kommando senden

      cbi(PORTC, 1);  //RW = 0
   //   sbi(PORTC, 2);  //E = 1

  wait_busy();
      lcd_send_nibble(n >> 4);
  wait_busy();
      lcd_send_nibble(n & 0x0f);

}

byte lcd_init()
{
    byte i;

    outp(0xff, DDRC);

   //RS, RW auf 0,E auf 0
    cbi(PORTC, 0);               // siehe 4-Bit Initialisierung
(LCD-Datenblatt)
   // cbi(PORTC, 1);
    cbi(PORTC, 2);


  //Länger als 15ms warten
  long_delay();  // 16 ms Pause

    for(i=0;i<3;i++)
    {
       lcd_send_nibble(3);
       if(i==0 || i == 1)
           long_delay(wait[i]);

       else
          delay(wait[i]);

    }


  lcd_send_nibble(2);
  delay();

    for(i=0; i <= 3; i++)
    {
       lcd_send_command(LCD_INIT_STRING[i]);

    }


}



void lcd_gotoxy( byte x, byte y)
{
   byte address;

   if (y==1)  address=0;  //
   else if (y==2) address=0x40;
   else address=0;

   address += x-1;

   lcd_send_command(0x80|address); //mmmmmh, ob das stimmt?
}



void lcd_putc( byte Zeile, char f)
{
//  lcd_gotoxy(1, Zeile);
  lcd_send_data(f);
}


void lcd_send_command(byte cmd)
{
  lcd_send_byte(0, cmd);
}

void lcd_send_data(byte data)
{
  lcd_send_byte(1, data);
}


void wait_busy()
{
      register byte data;

  cbi(PORTC,0);  //RS = 0
      sbi(PORTC, 1);  //  RW = 1
   //   sbi(PORTC, 2);  //E = 1 (HIGH)
      outp(0x0f, DDRC);  //BIT 7-4 als Input

  do
  {
    sbi(PORTC, 2);  //Enable = 1
    nop();
         data = inp(PINC);
          cbi(PORTC, 2);  //Enable = 0

  }while(data & 0x80);

  //Standards Wiederherstellen
  outp(0xff, DDRC); //Port C wieder Ausgang
  cbi(PORTC,1);  //RW wieder 0

}





void delay(unsigned char n)            //Wie kann ich hier die
                                       //verstrichene Zeit errechnen?
{
  while(n--);
}

void long_delay(unsigned char loop)
{
  unsigned char warten, i;
  for(i=loop; i>0; i--)
  {
    warten = 1000;
    while(warten--);
  }
}






/* 16-bit count, 4 cycles/loop */
/*void delay_loop_2(unsigned int __count)
{
  asm volatile (
    "1: sbiw %0,1" "\n\t"
    "brne 1b"
    : "=w" (__count)
    : "0" (__count)
  );
}


//  1 Mikrosekunde,      stimmt die Berchnung
// 1us sollten doch 8 Cycles sein, oder? bei 8MHz
void delay_us(unsigned int count)
{
  delay_loop_2( 2 * count);
}


//  1 Millisekunde
void delay_ms(unsigned int count)
{
  delay_us(1000 * count);
}


*/

Autor: Werner Hoch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

Ich hab nicht den gesamten Quelltext gelesen:

aber:

wait[] ist undefiniert.

mfg
werner

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab das undefiniert gelassen, so wie jede andere delay-schleife
auch, weil ich nicht weiß welchen Wert ich da benutzten soll.
Am Ende von dem Quelltext sind zwei unterschiedliche Arten von
Delayloops, die aber beide nicht richtig funktionieren, wobei
zzumindest die, die ich auskommentiert habe, richtig funktionieren
sollte.

mfg
  Daniel

Autor: Werner Hoch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Deine eigenen delay-Funktion gehen nicht, weil der Compiler die
Zählschleifen wegoptimierten kann.
Aus:
  warten=1000;
  while(warten--);
wird dann:
  warten -=1000;

Ich verwende z.Zt diese Warteschleifen:

void
lcd_delay_5ms() {
  uint16_t i;
  /* t = i * loop / UC_CLOCK
     i = t / loop * UC_CLOCK
     the fastest way the compiler can do that loop takes 5 clocks:
     2 clocks for decrementing, 1 for nop, 2 clocks to branch.
     take care that i does not exceed max(uint16_t) */
  for (i=UC_CLOCK*0.005/5; i; i--)
    asm volatile("nop\n\t"::);   /* required to prevent compiler
optimisation */
}

inline void
lcd_delay_50us() {
  uint8_t i;
  /* t = i * loop / UC_CLOCK
     i = t / loop * UC_CLOCK
     the fastest way the compiler can do that loop takes 4 clocks:
     1 clocks for decrementing, 1 for nop, 2 clocks to branch.
     take care that i does not exceed max(uint8_t) */
  for (i=UC_CLOCK*50e-6/4; i; i--)
    asm volatile("nop\n\t"::);   /* required to prevent compiler
optimisation */
}

meine Init-Routine sieht so aus:
void lcd_init() {
  uint8_t i;

  LCD_DATA_PORT &= ~LCD_DATA_MASK; /* clear the data pins */
  LCD_DATA_DDR |= LCD_DATA_MASK;   /* define the data pins as output */
  LCD_ENABLE_PORT &= ~_BV(LCD_ENABLE_PIN);  /* clear enable pin */
  LCD_ENABLE_DDR |= _BV(LCD_ENABLE_PIN);  /* and define as output */
  LCD_RS_PORT &= ~_BV(LCD_RS_PIN);  /* clear RS pin */
  LCD_RS_DDR |= _BV(LCD_RS_PIN);  /* and define as output */

  for (i=50; i; i--)    /* 250ms power up wait */
    lcd_delay_5ms();

  LCD_DATA_PORT |= 0x03;   /* put the LCD into 8-bit mode, send 3-times
*/
  lcd_enable();
  lcd_delay_5ms();         /* 1 */
  lcd_enable();
  lcd_delay_5ms();         /* 2 */
  lcd_enable();
  lcd_delay_5ms();         /* 3 */

  LCD_DATA_PORT &= ~LCD_DATA_MASK;   /* delete the data port pins */
  LCD_DATA_PORT |= 0x02;   /* put lcd into 4-bit mode */
  lcd_enable();
  lcd_delay_5ms();

  /* function set (bit 7-5 */
  /* 4-bit mode (bit4), 2-lines (bit3), 7*5 dots (bit2), xx bit1-0 */
  lcd_command(0x28);

  /* entry mode set (bit7-2)
     cursor move direction increase (bit1=1), display is not shifted
(bit0=0) */
  lcd_command(0x06);

  /* display mode set (bit7-3)
     display on (bit2=1), cursor on (bit1=1), blinking off (bit0=0) */
  lcd_command(0x0E);
}


mfg
werner

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank, das mit dem wegoptimieren hab ich mir schon fast gedacht.
ich werd dann mal deine Schleifen ausprobieren.
Nochmal Danke!

Daniel

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.