mikrocontroller.net

Forum: Compiler & IDEs Display zeigt falsch an


Autor: saschisch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute!

Wir arbeiten mit dem ATmega 32 mit der Taktfrequenz von 3,6864 Mhz und
versuchen ein Display Powerdip Pc1602d a anzusteuern. Dazu haben wir
uns ein Testprogramm heruntergeladen.

Wir lassen folgendes im Main.c ausgeben:

LCD_Print(0,0,"Servas");
_delay_ms(5000);


das ist das C File dazu
/*
 Copyright:      Radig Ulrich  mailto: mail@ulrichradig.de
 Author:         Radig Ulrich
 Remarks:        
 known Problems: none
 Version:        28.05.2004
 Description:    Programm zur Ansteuerung eines Standart LCD
         (HD44870),(SED1278F) und kompatible
*/

#include <lcd.h>

//Prototypes
void Write_LCD (char,char);
char Read_LCD (char);
void LCD_Init (void);
void LCD_Clear (void);
void LCD_Print (char,char,char *Buffer,...);

void LCD_Init (void)
{  
  char tmp = Init_LCD_Zeilen;
  //Set Port Direction Register to Output for LCD Databus und LCD
Steuerbus
  LCD_Port_DDR = LCD_DataOutput+(1<<LCD_RS | 1<<LCD_RW | 1<<LCD_E);
  //Wait a short Time afer Power on
  for (int a=0;a<3000;a++)
    {
    
    }  
  Write_LCD (0x22,0);  //Init in 4 Bit Mode
  //Wait a short Time afer Power on
  for (int a=0;a<3000;a++)
    {
    for (int b=0;b<100;b++);
    }  
  Write_LCD (0x22,0);  //Init in 4 Bit Mode (Zur Sicherheit nochmal)  
  if (tmp == 1)
    {
    Write_LCD (0x20,0);  //1 Zeilen
    }
    else
    {
    Write_LCD (0x28,0);  //mehrere Zeilen
    }
  Write_LCD (0x0C,0);  //Display On
  Write_LCD (0x80,0);  //Set DD-Ram Adresse = 0
}

void Write_LCD (char Data,char CD)
{
  //Set Port Direction Register to Output for LCD Databus und LCD
Steuerbus
  LCD_Port_DDR = LCD_DataOutput+(1<<LCD_RS | 1<<LCD_RW | 1<<LCD_E);
  //Soll ins Seuer oder Datenregister geschrieben werden?
  if (CD == 0)
    {
    cbi(LCD_Port_Write,LCD_RS); //RS = 0 Steuerregister
    }
    else
    {
    sbi(LCD_Port_Write,LCD_RS); //RS = 1 Dataregister
    }
  //Schreibsignal setzen
  cbi(LCD_Port_Write,LCD_RW); //Zum Schreiben RW-Pin = Low
  //Schreiben der 1. 4Bit an das LCD Display
  LCD_Port_Write = (LCD_Port_Write&0xF0) + ((Data&0xF0)>>4); //Write
Nibbel MSB
  sbi(LCD_Port_Write,LCD_E);
  cbi(LCD_Port_Write,LCD_E);
  //Schreiben der 2. 4Bit an das LCD Display  
  LCD_Port_Write = (LCD_Port_Write&0xF0) + (Data&0x0F); //Write Nibbel
LSB
  sbi(LCD_Port_Write,LCD_E);
  cbi(LCD_Port_Write,LCD_E);
  
  
}

char Read_LCD (char CD)
{
  char Data;
  //Set Port Direction Register to Output for LCD Databus und LCD
Steuerbus
  LCD_Port_DDR = LCD_DataInput+(1<<LCD_RS | 1<<LCD_RW | 1<<LCD_E);
  //Lesesignal setzen
  sbi(LCD_Port_Write,LCD_RW); //Zum Lesen RW-Pin = High
  //Soll ins Seuer oder Datenregister geschrieben werden?
  if (CD == 0)
    {
    cbi(LCD_Port_Write,LCD_RS); //RS = 0 Steuerregister
    }
    else
    {
    sbi(LCD_Port_Write,LCD_RS); //RS = 1 Dataregister
    }
  sbi(LCD_Port_Write,LCD_E); //Daten stehen an wenn Enable = High
  for (int a=0;a<100;a++)   //Wartet ein bisschen bis daten anliegen
  {
  }
  Data = (LCD_Port_Read&0x0F)<<4; //Lesen des 1. Nibble (MSB)
  cbi(LCD_Port_Write,LCD_E);  
  
  sbi(LCD_Port_Write,LCD_E); //Daten stehen an wenn Enable = High
  for (int a=0;a<100;a++)   //Wartet ein bisschen bis daten anliegen
  {
  }  
  Data += (LCD_Port_Read&0x0F); //Lesen des 2. Nibble (LSB)
  cbi(LCD_Port_Write,LCD_E);  
return(Data);
}

void LCD_Print (char zeile,char spalte,char *Buffer,...)
{
  // Hilfsvariable zum Zählen der ausgegebenen Zeichen
  char nFieldWidth = 0;

  struct {
    char     fLeftJust:1;   // Feldausrichtung links oder rechts
    char     fNegative:1;   // Auszugebende Zahl ist negativ.
  } flags;

  #define SCRATCH 16
  unsigned char scratch[SCRATCH];
  unsigned char format_flag;
  unsigned int u_val=0, base=0;
  unsigned char *ptr;
  char     hexA = 'a';
  char *p;
  int   n;
  int nLen;
  va_list ap;
    
  va_start (ap, Buffer);  
  //Berechnet Adresse für die Zeile und schreibt sie ins DD-Ram
  if (zeile >= Init_LCD_Zeilen) //wurden mehr Zeilen angegeben als
Initialisiert
    {
    zeile = Init_LCD_Zeilen - 1;
    }
  zeile = 0x80/Init_LCD_Zeilen*zeile;
  zeile += spalte;
  if (zeile >= 0x80) //ist der Wert ausserhalb des DD-Ram Adresse
    {
    zeile = 0x7F;
    }
  zeile += 0x80;
  Write_LCD (zeile,0);
  
  while (*Buffer != 0)
    {
    if (*Buffer == '%')
      {
      *Buffer++;
      switch (format_flag = *Buffer++){
 
        case 'c':
           format_flag = va_arg(ap,int);
           Write_LCD (format_flag++,1);
           
        case 'i':
        case 'd':
        case 'u':
                base = 10;
                goto CONVERSION_LOOP;
        case 'o':
                base = 8;
                goto CONVERSION_LOOP;
        
        case 'X':
                hexA = 'A';
                // Weiter wie 'x'
        case 'x':
                base = 16;
         }

        CONVERSION_LOOP:
                u_val = va_arg (ap, int);
        n = u_val;
                flags.fNegative = 0;
                if (format_flag == 'd' || format_flag == 'i') {
                    // Negative Werte auswerten
                    if (((int) u_val) < 0) {
                        flags.fNegative = 1;
                        u_val = -u_val;
                    }
                }
                // Der Scratchpuffer wird von rechts nach links
aufgefüllt
                // beginnend mit dem niederwertigsten Digit.
                ptr = scratch + SCRATCH;
                *--ptr = 0;     // Abschliessendes NULL-Byte eintragen
                do 
        {
          char ch = u_val % base + '0';
                    if (ch > '9') ch += hexA - '9' - 1;
                    *--ptr = ch;
          u_val /= base;
                } while (u_val);
        
        if (n < base) *--ptr = '0';
                if (flags.fNegative) *--ptr = '-';
          // Länge bestimmen
          p = ptr;
          nLen = 0;
          while (*p++) nLen++;
        // Feld bei Bedarf links auffüllen
        if (!flags.fLeftJust) {
        for (n=nLen; n < nFieldWidth; n++) Write_LCD (' ',1);
        }
        // Pufferinhalt schreiben
        for (n=0; n < nLen; n++) Write_LCD (*ptr++,1);
        // Feld bei Bedarf rechts auffüllen
        if (flags.fLeftJust) {
        for (n=nLen; n < nFieldWidth; n++) Write_LCD (' ',1);
        }        
      }        
    Write_LCD (*Buffer++,1);
    }
  va_end(ap);
}

void LCD_Clear (void)
{
  Write_LCD (1,0); //Clear Display
  Write_LCD (0x80,0);  //Set DD-Ram Adresse = 0
}


Die Header DAtei zum festelgen der Ports und so
//LCD_D0 - LCD_D3 connect to GND
//Im 4Bit Mode LCD_D4-->PORTx.0 ........ LCD_D7-->PORTx.3
//LCD_RS --> PORTx.4 | LCD_RW --> PORTx.5 | LCD_E --> PORTx.6 |
PORTx.7-->NotConnect

#define Init_LCD_Zeilen      2     //Anzahl der Zeilen 1,2 oder 4

#define LCD_Port_DDR      DDRA  //Port an dem das Display angeschlossen
wurde
#define LCD_Port_Write      PORTA
#define LCD_Port_Read      PINA

#define LCD_RS          4     //Pin für RS
#define LCD_RW          5    //Pin für Read/Write
#define LCD_E          6     //Pin für Enable

#define LCD_DataOutput      0x0f
#define LCD_DataInput      0x00

#define BusyBit          7



Das Programm funktioniert soweit, dass wir am Display was sehen, aber
es gibt folgendes aus:

evs<--<--0_HxWWt0__Unterstrich

<-- ist ein Zeichen und ein Pfeil nach links
_ist ein Abstand am Display
Unterstrich ist ein Unterstrich am Display

Danke für eure Hilfe

MfG

saschisch

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.