- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Ergebnis 1 bis 2 von 2

Thema: Display gibt falsche WErte aus

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    20.09.2005
    Ort
    AUT
    Beiträge
    17

    Display gibt falsche WErte aus

    Anzeige

    E-Bike
    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
    Code:
    /*
     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
    Code:
    //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

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    30.12.2005
    Ort
    Tann / ZH
    Alter
    68
    Beiträge
    264
    Könntest Du dein gesamtes main() posten ?

    Also der _unterstrich ist normal (Cursor).
    Wenn Du den nicht haben willst musst Du den
    ausschalten...

    Guten Rutsch
    Ruedi

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests