- Akku Tests und Balkonkraftwerk Speicher         
Ergebnis 1 bis 5 von 5

Thema: LCD - falsche ausgabe

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    14.03.2008
    Ort
    Oldenburg
    Beiträge
    84

    LCD - falsche ausgabe

    Anzeige

    Powerstation Test
    hi

    ich habe mal wieder ein problem - sry

    ich habe das display LCD-Modul HLM8070 von Pollin (M50530 Controller).
    Dank eurer Hilfe habe ich dazu auch einen code zum ansteuern gefunden.
    Nun habe ich alles verdrahtet und den Code getestet.

    Allerdings kommen komische Ausgaben auf dem Display...

    erst hatte ich "@\\\p P\\p"

    nun habe ich die Anzeigetexte geändert und er zeigt die ganze Zeit nur eine "0" an

    die Kontakte und die richtige verdrahtung habe ich geprüft.

    Ach ja, ich benutze einen Tiny2313 und steuere es über 4bit an.
    Beim compilieren bekamm ich folgende Warnungen (vielleicht haben die damit zu tun)
    Code:
    main.c:20: warning: pointer targets in passing argument 1 of 'LCD_write' differ in signedness
    main.c:22: warning: pointer targets in passing argument 1 of 'LCD_write' differ in signedness
    main.c:24: warning: pointer targets in passing argument 1 of 'LCD_write' differ in signedness
    der Code

    main.c
    Code:
    #include <avr/io.h>
    #include <lcd-m50530.h>
    
    
    // Hauptprogramm
    int main(void)
    {
    	// wait for power up
    	delay(250);
    
    	// LCD initialisieren
    	LCD_init();
    	// Modus des LCDs ändern
    	LCD_setEntryMode(LCD_CURSOR_ADDRESS_INC_WD | LCD_DISPLAY_START_ADDRESS_NO_CHANGE);
    	// Cursor einschalten
    	LCD_setDisplay(LCD_DISPLAY_ON | LCD_CURSOR_ON | LCD_CURSOR_BLINK | LCD_CHARACTER_BLINK);
    
    
    	// ein paar Zeichen ausgeben
    	LCD_write("Hallo Welt");
    	LCD_setCursorPos(2,5);
    	LCD_write("Test");
    	LCD_setCursorPos(4, 0);
    	LCD_write("test successful");
    
    	while (1)
    		;
    
    	return 0;
    }
    lcd-m50530.c
    Code:
    /***********************************************************
    
    	LCD-Routinen
    	für Samsung 2138a mit M50530-Controller
    	24 x 8 Zeichen
    
    	Copyright 2003-04 by Daniel Jelkmann
    
    
    	Zur Ansteuerung wird der 4Bit-Mode verwendet.
    	Neben den 4 Datenleitungen (Data0-3) werden 4 weitere
    	Steuerleitungen (Read/Write, Execute, OC1, OC2)
    	benötigt. Damit werden am AVR 8 Pins benötigt.
    
    	
    	Anschluss:
    	
    	Alle 8 LCD-Signale müssen an einem Port des AVR
    	angeschlossen werden. Gemäß folgender Tabelle müssen
    	die 4 Datenleitungen an den niederwertigsten Bits
    	anliegen. Die Reihenfolge der restlichen 4 Steuerleitungen
    	und der verwendete Port ist über die Konstanten im 
    	Quellcode festgelegt und muss ggf. angepasst werden.
    	Die restlichen LCD-Signale sind in folgender Tabelle
    	zu finden.
    
    		LCD	Beschreibung		Anschluss
    		-------------------------------------------------------------------------
    		Pin 01	Masse			Masse
    		Pin 02	Data0			nicht angeschlossen
    		Pin 03	Data1			nicht angeschlossen
    		Pin 04	Data2			nicht angeschlossen
    		Pin 05	Data3			nicht angeschlossen
    		Pin 06	Data4			AVR Port Bit 0
    		Pin 07	Data5			AVR Port Bit 1
    		Pin 08	Data6			AVR Port Bit 2
    		Pin 09	Data7			AVR Port Bit 3
    		Pin 10	EX (Execute)		AVR Port Bit 4*
    		Pin 11	R/W (Read/Write)	AVR Port Bit 5*
    		Pin 12	OC2				AVR Port Bit 7*
    		Pin 13	OC1				AVR Port Bit 6*
    		Pin 14	Kontrast-Regelung, ungefähr 8,2 Volt, am besten mittels Poti anschließen
    		Pin 15	Versorgungsspannung, +5 Volt
    		Pin 16	Masse			Masse
    
    
    	
    	* Die Reihenfolge dieser Leitungen kann über die
    	Konstanten im Quellcode angepasst werden.
    	
    	
    	Es wird keine Gewähr für die Vollständigkeit, Korrektheit,
    	Funktionsfähigkeit oder für sonstige Eigenschaften des
    	Codes übernommen. Haftung ausgeschlossen.
    	
    *************************************************************/
    
    
    #include <avr/io.h>
    //#include <avr/delay.h>
    #include <avr/pgmspace.h>
    
    #include "lcd-m50530.h"
    
    #include <stdlib.h>
    
    
    /*
    // wartet die angegebene Zeit in Millisekunden
    // F_MCU muss entsprechend gesetzt sein
    // (benötigt delay.h)
    void delay(const unsigned int ms)
    {
    	for (unsigned char i = ms; i > 0; --i)
    		// 4 cycles per loop * 250 = 1.000 cycles; 1.000 x F_MCU = 1 ms
    		_delay_loop_2(250*F_MCU);
    }*/
    
    
    // sendet den angelegten Befehl zum LCD
    // setzt kurzzeitig das EX-Signal und nimmt es anschließend wieder zurück
    void LCD_execute(void)
    {
    	delay_short();
    	// EX-Signal setzen
    	LCD_PORT |= (1 << LCD_EX_PIN);
    	delay_short();
    	// EX-Signal löschen
    	LCD_PORT &= ~(1 << LCD_EX_PIN);
    	delay_short();
    }
    
    
    // wartet solange bis das Busy-Flag nicht mehr gesetzt ist
    // und das LCD weitere Befehle entgegennimmt
    void LCD_waitReady(void)
    {
    	/*
    		READ BUSY FLAG & FUNCTION FLAGS (RB)
    		input:
    			OC1		0
    			OC2		0
    			RW		1
    		output:
    			DB7		busy-flag (1 = busy)
    	*/
    
    	// Datenleitungen auf Eingang schalten
    	// dazu die Bits der Datenleitungen auf 0 setzen
    	LCD_DDR &= 240;
    
    	// RB-Befehl senden
    	//LCD_PORT = (1 << LCD_OC1_PIN) | (1 << LCD_OC2_PIN) | (1 << LCD_RW_PIN);
    	LCD_PORT = 1 << LCD_RW_PIN;
    	
    	unsigned char flags = 0;
    	while (1)
    	{
    		do
    		{
    			delay_short();
    			// EX-Signal setzen
    			LCD_PORT |= (1 << LCD_EX_PIN);
    			delay_short();
    			// flags einlesen
    			flags = LCD_PIN;
    			// EX-Signal löschen
    			LCD_PORT &= ~(1 << LCD_EX_PIN);
    		} while (bit_is_set(flags, 3));
    		
    		if (flags & 6)
    			// bits 1 oder 2 gesetzt, also entweder sind wie im 8bit-mode oder wir haben gerade den zweiten Teil im 4bit-mode gelesen
    			break;
    	}
    		
    	
    /*	unsigned char busy;
    	do
    	{
    		delay_short();
    		LCD_execute();
    		// busy-Signal einlesen
    		busy = bit_is_set(LCD_PIN, 3);
    		LCD_execute();
    	} while (busy);
    */
    	
    	// alle Leitungen als Ausgänge schalten
    	LCD_DDR = 0xFF;
    }
    
    
    // überträgt das übergebene Byte an das LCD
    void LCD_sendByte(const unsigned char byte, unsigned char control)
    {
    	LCD_waitReady();
    	// die unteren 5 Bits im Control-Byte ausblenden
    	control &= 224;
    	// oberes Nibble übertragen
    	LCD_PORT = (byte >> 4) | control;
    	LCD_execute();
    	// unteres Nibble übertragen
    	LCD_PORT = (byte & 15) | control;
    	LCD_execute();
    }
    
    
    
    // löscht die Anzeige und setzt die Display + Cursor-Adresse auf 0,0
    void LCD_clear(void)
    {
    	/*
    		CLEAR DISPLAY, MOVE DISPLAY/CURSOR ADDRESS HOME
    		input:
    			OC1		0
    			OC2		0
    			RW		0
    			DB7-DB1	0
    			DB0		1
    	*/
    	LCD_sendByte(1, 0);	// DB0
    	delay(2);
    }
    
    
    // setzt 4-Bit-Mode und initialisiert das LCD
    // muss als erstes aufgerufen werden, bevor das LCD angesteuert werden kann
    void LCD_init(void)
    {
    	// alle Leitungen auf Ausgang schalten
    	LCD_DDR = 0xFF;
    
    	// auf 4-Bit-Mode umschalten
    	/*
    		SET FUNCTION MODE
    		input:
    			OC1		0
    			OC2		0
    			RW		0
    			DB7,DB6	1
    			DB5		I/O 8/4	(1 = 8 bit, 0 = 4 bit)
    			DB4		FONT 8/12 (1 = 5x8 fonts, 0 = 5x12 fonts)
    			DB3,DB2	DUTY
    			DB1,DB0	RAM
    	*/
    	LCD_sendByte(216, 0);	// DB7, DB6, DB4, DB3
    	LCD_clear();
    }
    
    
    // schreibt die übergebene Zeichenkette an die aktuelle Cursor-Position
    void LCD_write(const unsigned char * c)
    {
        while (*c) 
          LCD_writeChar(*c++);
    }
    
    
    // schreibt die übergebene Zeichenkette an die aktuelle Cursor-Position (für String im ROM)
    void LCD_write_P(const unsigned char * progmem_string)
    {
    	register unsigned char c;
    	while ((c = pgm_read_byte(progmem_string++)))
    		LCD_writeChar(c);
    }
    
    
    // setzt den Cursor an die angegebene Position (y = Zeile, x = Spalte)
    void LCD_setCursorPos(const unsigned char y, const unsigned char x)
    {
    	// Adresse aus x und y berechnen
    	// Adressen sind wie folgt: Zeile 0 = 0; Zeile 1 = 64; Zeile 2 = 128; Zeile 3 = 192; Zeile 4 = 0+24; Zeile 5 = 64+24; Zeile 6 = 128+24; Zeile 7 = 192+24
    	unsigned char address = x + ((y % 4) << 6);
    	if (y > 3)
    		address += 24;
    	LCD_sendByte(address, (1<<LCD_OC1_PIN) | (1<<LCD_OC2_PIN));
    }

    lcd-m50530.h
    Code:
    /***********************************************************
    
    	LCD-Routinen
    	für Samsung 2138a mit M50530-Controller
    	24 x 8 Zeichen
    
    	Copyright 2003 by Daniel Jelkmann
    
    
    	Zur Ansteuerung wird der 4Bit-Mode verwendet.
    	Neben den 4 Datenleitungen (Data0-3) werden 4 weitere
    	Steuerleitungen (Read/Write, Execute, OC1, OC2)
    	benötigt. Damit werden am AVR 8 Pins benötigt.
    
    	
    	Anschluss:
    	
    	Alle 8 LCD-Signale müssen an einem Port des AVR
    	angeschlossen werden. Gemäß folgender Tabelle müssen
    	die 4 Datenleitungen an den niederwertigsten Bits
    	anliegen. Die Reihenfolge der restlichen 4 Steuerleitungen
    	und der verwendete Port ist über die Konstanten im 
    	Quellcode festgelegt und muss ggf. angepasst werden.
    	Die restlichen LCD-Signale sind in folgender Tabelle
    	zu finden.
    
    		LCD	Beschreibung		Anschluss
    		-------------------------------------------------------------------------
    		Pin 01	Masse			Masse
    		Pin 02	Data0			nicht angeschlossen
    		Pin 03	Data1			nicht angeschlossen
    		Pin 04	Data2			nicht angeschlossen
    		Pin 05	Data3			nicht angeschlossen
    		Pin 06	Data4			AVR Port Bit 0
    		Pin 07	Data5			AVR Port Bit 1
    		Pin 08	Data6			AVR Port Bit 2
    		Pin 09	Data7			AVR Port Bit 3
    		Pin 10	EX (Execute)		AVR Port Bit 5*
    		Pin 11	R/W (Read/Write)	AVR Port Bit 4*
    		Pin 12	OC2				AVR Port Bit 7*
    		Pin 13	OC1				AVR Port Bit 6*
    		Pin 14	Kontrast-Regelung, ungefähr 8,2 Volt, am besten mittels Poti anschließen
    		Pin 15	Versorgungsspannung, +5 Volt
    		Pin 16	Masse			Masse
    
    
    	
    	* Die Reihenfolge dieser Leitungen kann über die
    	Konstanten im Quellcode angepasst werden.
    	
    	
    	Es wird keine Gewähr für die Vollständigkeit, Korrektheit,
    	Funktionsfähigkeit oder für sonstige Eigenschaften des
    	Codes übernommen. Haftung ausgeschlossen.
    	
    *************************************************************/
    
    #ifndef LCD_M50530_H
    #define LCD_M50530_H
    
    #include <util/delay.h>
    
    
    //#define F_MCU 				5		/* Takt-Frequenz in MHz */
    
    
    // wartet die angegebene Zeit in Millisekunden
    // XTAL_CPU muss entsprechend gesetzt sein
    // (benötigt delay.h)
    //extern void delay(unsigned int ms);
    #define delay(ms)		for (unsigned int i = ms; i > 0; --i)	\
    							_delay_loop_2(XTAL_CPU / 4000);
    //							_delay_loop_2(250*F_MCU);
    
    
    /****************************************************************
    Ggf. hier den Port anpassen, an dem das LCD angeschlossen ist! 
    ****************************************************************/
    // Data-Direction-Register, am dem das LCD angeschlossen ist
    #define LCD_DDR DDRB
    // Port-Register, am dem das LCD angeschlossen ist
    #define LCD_PORT PORTB
    // Pin-Register, am dem das LCD angeschlossen ist
    #define LCD_PIN PINB
    
    #define XTAL_CPU        5000000
    
    /*************************************************
    Ggf. hier die Bits der 4 Steuerleitungen anpassen!
    *************************************************/
    // Die Datenleitungen des LCDs müssen an den Pins 0-3 anliegen (Data0 auf Pin0, Data1 auf Pin1 usw.)
    // Die anderen 4 Steuerleitungen sind hier einzustellen!
    // Port-Pin, an dem der RW-Pin des LCDs liegt
    #define LCD_RW_PIN 4
    // Port-Pin, an dem der EX-Pin des LCDs liegt
    #define LCD_EX_PIN 5
    // Port-Pin, an dem der OC1-Pin des LCDs liegt
    #define LCD_OC1_PIN 6
    // Port-Pin, an dem der OC2-Pin des LCDs liegt
    #define LCD_OC2_PIN 7
    
    
    // ein paar Konstanten zur besseren Lesbarkeit des Quelltextes :-)
    #define LCD_DISPLAY_ON		16
    #define LCD_CURSOR_ON		8
    #define LCD_UNDERLINE		4
    #define LCD_CURSOR_BLINK	2
    #define LCD_CHARACTER_BLINK	1
    
    
    #define LCD_CURSOR_ADDRESS_NO_CHANGE	64
    #define LCD_CURSOR_ADDRESS_INC_RD		72
    #define LCD_CURSOR_ADDRESS_INC_WD		80
    #define LCD_CURSOR_ADDRESS_INC_RDWD		88
    #define LCD_CURSOR_ADDRESS_DEC_RD		104
    #define LCD_CURSOR_ADDRESS_DEC_WD		112
    #define LCD_CURSOR_ADDRESS_DEC_RDWD		120
    
    #define LCD_DISPLAY_START_ADDRESS_NO_CHANGE	64
    #define LCD_DISPLAY_START_ADDRESS_INC_RD	65
    #define LCD_DISPLAY_START_ADDRESS_INC_WD	66
    #define LCD_DISPLAY_START_ADDRESS_INC_RDWD	67
    #define LCD_DISPLAY_START_ADDRESS_DEC_RD	69
    #define LCD_DISPLAY_START_ADDRESS_DEC_WD	70
    #define LCD_DISPLAY_START_ADDRESS_DEC_RDWD	71
    
    
    #define LCD_SPECIAL_AE						(char)144	// Ä, dezimal 144, oktal 220
    #define LCD_SPECIAL_OE						(char)145	// Ö, dezimal 145, oktal 221
    #define LCD_SPECIAL_UE						(char)197	// Ü, dezimal 197, oktal 305
    #define LCD_SPECIAL_ae						(char)160	// ä, dezimal 160, oktal 240
    #define LCD_SPECIAL_oe						(char)161	// ö, dezimal 161, oktal 241
    #define LCD_SPECIAL_ue						(char)17	// ü, dezimal 17, oktal 21
    #define LCD_SPECIAL_ss						(char)163	// ß,  dezimal 163, oktal 243
    
    
    // wartet einen kurzen Moment, 4 cycles per loop * 8 = 32 cycles, macht bei 16 MHz 2 µs
    #define delay_short()	_delay_loop_2(8)
    
    
    // sendet den angelegten Befehl zum LCD
    // setzt kurzzeitig das EX-Signal und nimmt es anschließend wieder zurück
    extern void LCD_execute(void);
    
    
    // wartet solange bis das Busy-Flag nicht mehr gesetzt ist
    // und das LCD weitere Befehle entgegennimmt
    extern void LCD_waitReady(void);
    
    
    // überträgt das übergebene Byte an das LCD
    extern void LCD_sendByte(const unsigned char byte, unsigned char control);
    
    
    // setzt 4-Bit-Mode und initialisiert das LCD
    // muss als erstes aufgerufen werden, bevor das LCD angesteuert werden kann
    extern void LCD_init(void);
    
    // löscht die Anzeige und setzt die Display + Cursor-Adresse auf 0,0
    extern void LCD_clear(void);
    
    
    // setzt den Entry-Mode des LCDs, also die automatische Erhöhung der Adresse nach einem Lese- oder Schreibbefehl
    // man verwende die oben deklarierten Konstanten ;)
    #define LCD_setEntryMode(mode)			LCD_sendByte(mode, 0)
    
    
    // schreibt das übergebene Zeichen an die aktuelle Cursor-Position
    #define LCD_writeChar(c)				LCD_sendByte(c, 1 << LCD_OC2_PIN)
    
    
    // schreibt die übergebene Zeichenkette an die aktuelle Cursor-Position
    extern void LCD_write(const unsigned char * c);
    
    // schreibt die übergebene Zeichenkette an die aktuelle Cursor-Position (für String im ROM)
    extern void LCD_write_P(const unsigned char * progmem_string);
    
    
    // setzt den Display-Modus
    // man verwende die oben deklarierten Konstanten ;)
    #define LCD_setDisplay(mode)			LCD_sendByte(mode | 32, 0)
    
    
    // setzt den Cursor an die angegebene Adresse
    #define LCD_setCursorAddress(address)	LCD_sendByte(address, (1<<LCD_OC1_PIN) | (1<<LCD_OC2_PIN))
    
    
    // setzt den Cursor an die angegebene Position (y = Zeile, x = Spalte)
    extern void LCD_setCursorPos(const unsigned char y, const unsigned char x);
    
    #endif
    vielleicht findet ja jemand den Fehler
    den code habe ich übrigens von hier mikrocontroller.net
    Danke für eure Hilfe

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    23.06.2005
    Ort
    München
    Beiträge
    113
    Hier gibts einen alternativen Treiber für m50530 displays:

    https://www.roboternetz.de/phpBB2/download.php?id=14191

    Probiers damit mal. Im highlevel-Teil wirst du evtl. die Displaygröße ändern müssen, im *_config deine Pinzuordnung.

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    14.03.2008
    Ort
    Oldenburg
    Beiträge
    84
    okay, danke
    das werde ich gleich mal machen

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    14.03.2008
    Ort
    Oldenburg
    Beiträge
    84
    wie kann ich denn mehrere .c dateien im makefile angeben
    bei einer kann ich die ja einfach dahinter schreiben
    so:

    # List C source files here. (C dependencies are automatically generated.)
    SRC = $(TARGET).c display_m50530_highlevel.c

    das funktioniert

    aber bei insgesamt 3 dateien will er das nicht

    # List C source files here. (C dependencies are automatically generated.)
    SRC = $(TARGET).c display_m50530_highlevel.c display_m50530.c

    was muss ich tun?
    habe auch schon gegoogelt, aber nichts gefunden

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    14.03.2008
    Ort
    Oldenburg
    Beiträge
    84
    habe es jetzt so gemacht und die fehler scheinen ein anderes problem zu sein

    # List C source files here. (C dependencies are automatically generated.)
    SRC = $(TARGET).c
    SRC += display_m50530_highlevel.c display_m50530.c

Berechtigungen

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

12V Akku bauen