- 12V Akku mit 280 Ah bauen         
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

    Praxistest und DIY Projekte
    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
    67
    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
  •  

12V Akku bauen