mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik LCD diplay am AVR läuft nur jedes zweite Mal an


Autor: Christoph Roters (chroters)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe folgenden Quelltext in eine ATmega 2560 (8Mhz int osc) am 
STK600 geflashed.
Das Display zeigt den Ausgabetext aber nur nach jedem zweiten Reset oder 
nach nochmaligem Programmieren (was ja auch einen neuen Reset auslöst) 
an.
Auch wenn ich nach dem Programmieren das Board resete, muss ich es immer 
zweimal machen.

Das LCD ist ein LTN211R.

Hat jemand eine Idee, was da falsch ist?


Nette Grüsse

Christoph

#include    <avr/io.h>
#include    <stdio.h>
#include    <string.h>
#include    <util/delay.h>

//  ************************************************************//
//  **********  LCD display Vereinbarungen *********************//
//  ************************************************************//

/* sample: lcd_cmd(LCD_DISP_OFF); */
#define LCD_DISP_OFF             0x08   /* display off                            */
#define LCD_DISP_ON              0x0C   /* display on, cursor off                 */
#define LCD_DISP_ON_BLINK        0x0D   /* display on, cursor off, blink char     */
#define LCD_DISP_ON_CURSOR       0x0E   /* display on, cursor on                  */
#define LCD_DISP_ON_CURSOR_BLINK 0x0F   /* display on, cursor on, blink char      */
/* move cursor/shift display */
#define LCD_MOVE_CURSOR_LEFT     0x10   /* move cursor left  (decrement)          */
#define LCD_MOVE_CURSOR_RIGHT    0x14   /* move cursor right (increment)          */
#define LCD_MOVE_DISP_LEFT       0x18   /* shift display left                     */
#define LCD_MOVE_DISP_RIGHT      0x1C   /* shift display right                    */



// Zuordnung der LCD-Eingängen zu den Atmega-Ausgängen 
// Wenn die Zuordnung geändert werden soll, so muss der Quelltext in dieser Datei geändert werden.
// Insbesonder die Routine LCD_init muss angepasst werden!!!!
// siehe Quelltextkommentare
// RS = PG2
// E  = PG3
// D4 = PG4
// D5 = PG5
// D6 = PG6
// D7 = PG7


#define clr_d7  PORTA &= ~(1<<7)
#define set_d7  PORTA |= (1<<7)
#define clr_d6  PORTA &= ~(1<<6)
#define set_d6  PORTA |= (1<<6)
#define clr_d5  PORTA &= ~(1<<5)
#define set_d5  PORTA |= (1<<5)
#define clr_d4  PORTA &= ~(1<<4)
#define set_d4  PORTA |= (1<<4)


#define clr_e  PORTA &= ~(1<<3)
#define set_e  PORTA |= (1<<3)

#define clr_rs  PORTA &= ~(1<<2)
#define set_rs  PORTA |= (1<<2)

//  ************************************************************//
//  **********  LCD display Vereinbarungen      ****************//
//  ************Ende *******************************************//
//  ************************************************************//




// Variablen deklaration



// main  Hauptprogramm
int main(void)
{
   double messung;
   float ek0,ek1,ek2;
   float b0,b1,b2;
   double y0,y1;
   float Kpr,Kir,Kdr;
   float T;
   double mess_c;
   double ausgabe;
   char  lcd_txt[17];
   char  txt[8];
   int i;
   int j;
   
  
   //warten bist LCD-Controller gebootet
     _delay_ms(20);   
  
  
   
  lcd_init();
     _delay_ms(20);   



   lcd_cmd(LCD_DISP_ON);
      _delay_ms(20);   
  lcd_clear();
     _delay_ms(20);   
  
  lcd_txt[0] = 0;
  

  strcat(lcd_txt, "Test v0.1");
  lcd_write_s(lcd_txt);

 

   while (1)
   {
   
  


  //Endlosschleife für Hauptprogramm
   }
   
 
} 

//////////////////////////////////////////////////////////////////////////////
//    lcd_send(..) - sendet ein Byte an LCD im 4-Bit-Modus ohne Busy
//    nicht direkt aufrufen sondern lcd_cmd oder lcd_write nutzen
//---------------------------------------------------------------------------
void lcd_send(char data)
{
  
  // High-Teil senden
    char tmp=data;
    
  tmp = data & 0x80;    // bit7 von data isolieren durch And mit "1000 0000"
    clr_d7;            //Löschen von D7
  if ( tmp == 0x80 ) {
  set_d7;
  }
  
  tmp = data & 0x40;    // bit6 von data isolieren durch And mit "0100 0000"
    clr_d6;            //Löschen von D6 
  if ( tmp == 0x40 ) {
    set_d6;            //setzen von D6  
  }

  tmp = data & 0x20;    // bit5 von data isolieren durch And mit "0010 0000"
    clr_d5;              //Löschen von D5 
  if ( tmp == 0x20 ) {
    set_d5;            //setzen von D5  
  }

  tmp = data & 0x10;    // bit4 von data isolieren durch And mit "0001 0000"
    clr_d4;            //Löschen von D4 
  if ( tmp == 0x10 ) {
    set_d4;          //setzen von D4  
  }

  // Schreibsignal mit fallender Flanke an E  
  set_e;            //setzen von E  
  clr_e;            //Löschen von E 
    
  _delay_ms(20);
  
  tmp = data & 0x08;    // bit3 von data isolieren durch And mit "0000 1000"
    clr_d7;            //Löschen von D7
  if ( tmp == 0x08 ) {
    set_d7;          //Setzen von D7
  }
   
  tmp = data & 0x04;    // bit2 von data isolieren durch And mit "0000 1000"
      clr_d6;          //Löschen von D6
  if ( tmp == 0x04 ) {
  set_d6;            //Setzen von D6
  }

  tmp = data & 0x02;    // bit1 von data isolieren durch And mit "0000 0010"
      clr_d5;          //Löschen von D5
  if ( tmp == 0x02 ) {
    set_d5;          //setzen von D5 
  }

  tmp = data & 0x01;    // bit0 von data isolieren durch And mit "0000 0001"
      clr_d4;          //Löschen von D4 
  if ( tmp == 0x01 ) {
    set_d4;          //setzen von D4 
  }

    
  // Schreibsignal mit fallender Flanke an E  
  set_e;            //E = 1 
  clr_e;            //E = 0 

    // verarbeiten lassen
    _delay_ms(20);
}
//---------------------------------------------------------------------------
//    lcd_cmd(..) - sendet ein Kommando an LCD
//---------------------------------------------------------------------------
void lcd_cmd(char cmd)
{

    clr_rs;             // RS löschen = Kommando
  _delay_ms(20);
    lcd_send(cmd);        // senden
}
//---------------------------------------------------------------------------
//    lcd_write(..) - sendet ein Zeichen (Daten) an LCD
//---------------------------------------------------------------------------
void lcd_write(char text)
{
    set_rs;        // RS setzen = Daten
  _delay_ms(20);
    lcd_send(text);        // senden
}
//---------------------------------------------------------------------------
//    lcd_write_s(..) - sendet eine Zeichenkette an LCD
//    Die Zeichenkette muss mit 0x00 abgeschlossen sein
//---------------------------------------------------------------------------
void lcd_write_s(char * pText)

{

    while(pText[0]!=0)
    {
    lcd_write(pText[0]); // diese Zeile stehenlassen, auch für norrmale LCD-Displays
    pText++;       // diese Zeile muss stehenbleiben, auch für norrmale LCD-Displays
    }
}


//---------------------------------------------------------------------------
//    lcd_home(..) - Cursor auf Position 1,1
//---------------------------------------------------------------------------
void lcd_home(void)
{
    lcd_cmd(0x02);
    _delay_ms(20);            // warten
}
//---------------------------------------------------------------------------
//    lcd_clear(..) - löscht die Anzeige im LCD
//---------------------------------------------------------------------------
void lcd_clear(void)
{
    lcd_cmd(0x01);
    _delay_ms(20);            // warten
}
//---------------------------------------------------------------------------
//    lcd_on(..) - schaltet das LCD an
//---------------------------------------------------------------------------
void lcd_on(void)
{
    lcd_cmd(0x0C);
   _delay_ms(20);            // warten
}
//---------------------------------------------------------------------------
//    lcd_off(..) - schaltet das LCD aus
//---------------------------------------------------------------------------
void lcd_off(void)
{
    lcd_cmd(0x08);
   _delay_ms(20);            // warten
}
//---------------------------------------------------------------------------
//    lcd_goto(..) - setzt die Cursorposition
//---------------------------------------------------------------------------
void lcd_goto(int row, int col)
{
    row--;                // Null-basierend
    row&=0x01;            // sicherheitshalber
    row*=0x40;            // Zeile nach Bit 6 bringen
    col--;                // Null-basierend
    col&=0x0f;            // sicherheitshalber
    char tmp=row|col;
    tmp|=0x80;            // Cursor setzen
    lcd_cmd(tmp);        // senden
}

//---------------------------------------------------------------------------
//    lcd_init(..) - Schaltet die Ports und Initialisiert das LCD
//---------------------------------------------------------------------------
void lcd_init(void)
{
 // Portx = Ausgang
 DDRA=0xff;
 PORTA=0x00;    // Pullup-Widerstände 



    // warten bist LCD-Controller gebootet
//    _delay_ms(200);        
    
  // 4-BitModus einschalten
    // 
    
  // x |= (1 << Bitnummer);  // Hiermit wird ein Bit in x gesetzt
  // x &= ~(1 << Bitnummer); // Hiermit wird ein Bit in x geloescht 

  
  
  set_d5;    //D5 auf High am LCD


  clr_rs;     // RS löschen = Kommando
  
  // Schreibsignal mit fallender Flanke an E  
  set_e;            //E auf 1 
  clr_e;            //E auf 0 
    
  
  _delay_ms(20);            // Zeit zum Umschalten lassen
    
  
  // ab hier im 4-Bit-Modus
     lcd_cmd(0x28);        // Funktions-Set: 1 Zeile, 5x7 Matrix, 4 Bit
  
     lcd_off();
  lcd_cmd(0x06);        // Entry Mode
  lcd_on();
  lcd_clear();
}



//---------------------------------------------------------------------------
//    lcd_charDef(..) - initialisiert benutzerdefinierte Zeichen für das LCD
//---------------------------------------------------------------------------
void lcd_charDef(void)
{
    // 1. Kommando CGRAM + Adresse setzen
    // 2. Punktmatrix-Daten laden
    unsigned char charSet[64]={    
                                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,
                                0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,
                                0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,
                                0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,
                                0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,
                                0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
                                0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
                                0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
                              };
    int i=0;
    for (i=0;i<64;i++)
    {
        lcd_cmd(0x40+i);              // cmd 0x40 + Adr
        lcd_write(charSet[i]);        // Pixel
    }
}
//---------------------------------------------------------------------------


Autor: Anja (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du solltest dich genau an die Reset-Sequenz im Datenblatt des 
LCD-Controllers halten.
Falls der Brown-Out Reset im ATMEGA nicht aktiv ist ist zu bedenken daß 
das dort angegebene Timing erst ab einer Spannung von 4,5 V gilt. (der 
1. Delay ist entsprechend anzupassen daß ab 4,5V sicher 15 ms für das 
Display bis zum 1. Reset-Befehl zur Verfügung stehen)

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.