PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : rn-lcd-adapter mit C



tomy321
14.11.2010, 15:06
Hallo Leute,

ich habe ein (glaube ich) eigentlich ganz einfach zu lösendes Problem. Ich besitze ein rn-Control und ein DIP-LCD (http://www.shop.robotikhardware.de/shop/catalog/product_info.php?cPath=66&products_id=80) mit einem LCD-Adapter (http://www.shop.robotikhardware.de/shop/catalog/product_info.php?products_id=152).
Bisher hatte ich das Display immer nur mit Bascom verwendet (was auch funktioniert hatte), dafür gab es auch ein schönes Beispiel auf der Website http://www.rn-wissen.de/index.php/LCD_an_RN-Control.
Aber wie verwende ich jetzt das Display unter C mit AVR-Studio?
In anderen Forenbeiträgen hatte ich gelesen, dass man die Bibliothek von Peter Fleury verwenden kann. Allerdings habe ich jetzt keine Ahnung wie ich die lcd.h hier anpassen muss...
Kann mir bitte jemand weiterhelfen? Ich bin ein ziemlicher Anfänger in Sachen µC.

Hubert.G
14.11.2010, 18:43
Ich weiss nicht genau wie ich dir da helfen kann.
Anzahl der Zeilen ändern
Anzahl der Zeichen je Zeile
Dann noch die Port und Pin der Daten- und Steuerleitungen
Mehr ist nicht zu machen.
Wenn du nicht zurecht kommst, noch mal genau fragen wo du steckst.

oberallgeier
14.11.2010, 19:41
Sorry für die Ergänzung: es muss noch der Controller definiert werden und der MCU-Takt. Ein Ausschnitt aus (m)einer lauffähigen lcdxy.h für ein 2x24-Display, einem KS0073 und einen 4-Bit-Anschluss (4-bittig, das ist mein Standard) lautet daher so:

/**
* @name Definitions for MCU Clock Frequency
* Adapt the MCU clock frequency in Hz to your target.
*/
#define XTAL 20000000 /**< clock frequency in Hz, used to calculate delay timer */


/**
* @name Definition for LCD controller type
* Use 0 for HD44780 controller, change to 1 for displays with KS0073 controller.
*/
#define LCD_CONTROLLER_KS0073 1 /**< Use 0 for HD44780 controller, 1 for KS0073 controller */

/**
* @name Definitions for Display Size
* Change these definitions to adapt setting to your display
*/
#define LCD_LINES 2 /**< number of visible lines of the display */
#define LCD_DISP_LENGTH 24 /**< visibles characters per line of the display */
//#define LCD_LINE_LENGTH 0x40 /**< internal line length of the display */
#define LCD_START_LINE1 0x00 /**< DDRAM address of first char of line 1 */
#define LCD_START_LINE2 0x40 /**< DDRAM address of first char of line 2 */
#define LCD_START_LINE3 0x14 /**< DDRAM address of first char of line 3 */
#define LCD_START_LINE4 0x54 /**< DDRAM address of first char of line 4 */
#define LCD_WRAP_LINES 0 /**< 0: no wrap, 1: wrap at end of visibile line */


#define LCD_IO_MODE 1 /**< 0: memory mapped mode, 1: IO port mode */
#if LCD_IO_MODE
/**
* @name Definitions for 4-bit IO mode
* Change LCD_PORT if you want to use a different port for the LCD pins.
*
* The four LCD data lines and the three control lines RS, RW, E can be on the
* same port or on different ports.
* Change LCD_RS_PORT, LCD_RW_PORT, LCD_E_PORT if you want the control lines on
* different ports.
*
* Normally the four data lines should be mapped to bit 0..3 on one port, but it
* is possible to connect these data lines in different order or even on different
* ports by adapting the LCD_DATAx_PORT and LCD_DATAx_PIN definitions.
*
*/
#define LCD_PORT PORTB /**< port for the LCD lines */
#define LCD_DATA0_PORT LCD_PORT /**< port for 4bit data bit 0 */
#define LCD_DATA1_PORT LCD_PORT /**< port for 4bit data bit 1 */
#define LCD_DATA2_PORT LCD_PORT /**< port for 4bit data bit 2 */
#define LCD_DATA3_PORT LCD_PORT /**< port for 4bit data bit 3 */
#define LCD_DATA0_PIN 4 /**< pin for 4bit data bit 0 */
#define LCD_DATA1_PIN 3 /**< pin for 4bit data bit 1 */
#define LCD_DATA2_PIN 2 /**< pin for 4bit data bit 2 */
#define LCD_DATA3_PIN 1 /**< pin for 4bit data bit 3 */
#define LCD_RS_PORT PORTC /**< port for RS line */
#define LCD_RS_PIN 2 /**< pin for RS line */
#define LCD_RW_PORT PORTC /**< port for RW line */
#define LCD_RW_PIN 1 /**< pin for RW line */
#define LCD_E_PORT PORTC /**< port for Enable line */
#define LCD_E_PIN 0 /**< pin for Enable line */
Änderungsbeispiel: Hast Du aus welchen Gründen auch immer, den LCD-Data1pin auf PORT D2, dann heisst diese Liste so:



#define LCD_PORT PORTB /**< port for the LCD lines */
#define LCD_DATA0_PORT LCD_PORT /**< port for 4bit data bit 0 */
#define LCD_DATA1_PORT PORTD /**< port for 4bit data bit 1 */
#define LCD_DATA2_PORT LCD_PORT /**< port for 4bit data bit 2 */
#define LCD_DATA3_PORT LCD_PORT /**< port for 4bit data bit 3 */
#define LCD_DATA0_PIN 4 /**< pin for 4bit data bit 0 */
#define LCD_DATA1_PIN 2 /**< pin for 4bit data bit 1 = PD2 !! */
#define LCD_DATA2_PIN 2 /**< pin for 4bit data bit 2 */
#define LCD_DATA3_PIN 1 /**< pin for 4bit data bit 3 */
#define LCD_RS_PORT PORTC /**< port for RS line */
#define LCD_RS_PIN 2 /**< pin for RS line */
#define LCD_RW_PORT PORTC /**< port for RW line */
#define LCD_RW_PIN 1 /**< pin for RW line */
#define LCD_E_PORT PORTC /**< port for Enable line */
#define LCD_E_PIN 0 /**< pin for Enable line */
Viel Erfolg

tomy321
22.01.2011, 12:47
Leider waren die letzten Wochen etwas stressig, so dass ich kaum zeit hatte, an meinem µC etwas weiter zu arbeiten.

Die Pins habe ich wie folgt angepasst:

#define LCD_PORT PORTC /**< port for the LCD lines */
#define LCD_DATA0_PORT LCD_PORT /**< port for 4bit data bit 0 */
#define LCD_DATA1_PORT LCD_PORT /**< port for 4bit data bit 1 */
#define LCD_DATA2_PORT LCD_PORT /**< port for 4bit data bit 2 */
#define LCD_DATA3_PORT LCD_PORT /**< port for 4bit data bit 3 */
#define LCD_DATA0_PIN 3 /**< pin for 4bit data bit 0 */
#define LCD_DATA1_PIN 2 /**< pin for 4bit data bit 1 */
#define LCD_DATA2_PIN 1 /**< pin for 4bit data bit 2 */
#define LCD_DATA3_PIN 0 /**< pin for 4bit data bit 3 */
#define LCD_RS_PORT LCD_PORT /**< port for RS line */
#define LCD_RS_PIN 7 /**< pin for RS line */
#define LCD_RW_PORT LCD_PORT /**< port for RW line */
#define LCD_RW_PIN 6 /**< pin for RW line */
#define LCD_E_PORT LCD_PORT /**< port for Enable line */
#define LCD_E_PIN 5 /**< pin for Enable line */

Die Definitionen für die Zeilen habe ich so belassen wie sie waren:

#define LCD_LINES 4 /**< number of visible lines of the display */
#define LCD_DISP_LENGTH 20 /**< visibles characters per line of the display */
#define LCD_LINE_LENGTH 0x40 /**< internal line length of the display */
#define LCD_START_LINE1 0x00 /**< DDRAM address of first char of line 1 */
#define LCD_START_LINE2 0x40 /**< DDRAM address of first char of line 2 */
#define LCD_START_LINE3 0x14 /**< DDRAM address of first char of line 3 */
#define LCD_START_LINE4 0x54 /**< DDRAM address of first char of line 4 */
#define LCD_WRAP_LINES 0 /**< 0: no wrap, 1: wrap at end of visibile line */




#define LCD_IO_MODE 1
#define LCD_CONTROLLER_KS0073 0


Allerdings funktioniert das Display jetzt nicht wie es soll:
Die erste Zeile funktioniert super
In der zweiten Zeile steht "Zeile3" (und das in der Mitte der Zeile und nicht am Beginn...)
Die dritte Zeile wird wieder richtig dargestellt, nur dass in dieser "Zeile2" steht.
In der letzten Zeile steht korrekt "Zeile4", aber wieder in der Mitte der Zeile, nicht am Beginn...

Hier noch kurz mein Quellcode:

#include <stdlib.h>
#include <avr/io.h>
#include <header.h>
#include <lcd.h>

int main(void)
{
Init();
lcd_init(LCD_DISP_ON);
lcd_clrscr();
lcd_puts("Zeile1\nZeile2\nZeile3\nZeile4");

return 0;
}

Hat jemand eine Ahnung, was der Fehler sein könnte. Muss ich noch etwas an den Zeilendefinitionen ändern (und wo finde ich diese Konstanten), oder liegt der Fehler wo anders?

tomy321
22.01.2011, 13:13
was mir gerade noch aifgefallen ist: die letzten 8 Zeichen der ersten Zeile erscheinen auf der zweiten Zeile als die ersten 8 Zeichen. Erst danach werdn die nächsten Zeichen angezeigt.

Wenn ich im Quellcode schreibe:

lcd_puts("123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");

dann zeigt das Display an:

123456789ABCDEFGHIJK
DEFGHIJKLMNOPQRSTUVWXYZ

Wie bereits oben erwähnt: falls in den letzten 8 Stellen der ersten zeile des Displays nichts steht, beginnt die 2. Zeile auch erst nach dem 8.Zeichen (die ersten 8 Zeichen sind dann Leerzeichen)

BMS
22.01.2011, 13:17
Hallo,
in dem Datenblatt von deinem Display (hier klicken (http://www.robotikhardware.de/download/eadip204_datenblatt.pdf)) auf Seite 3 (oben rechts) gibt es die Adressierungen der einzelnen Zeilen. Die solltest du übernehmen und bei LCD_START_LINE... eintragen. Dann sollte das funktionieren :)
Anstatt $ musst du 0x schreiben.

Grüße,
Bernhard

tomy321
22.01.2011, 13:47
Danke für die schnelle Hilfe, ich hab das jetzt wie im Datenblatt geschrieben angepasst:


#define LCD_LINES 4 /**< number of visible lines of the display */
#define LCD_DISP_LENGTH 20 /**< visibles characters per line of the display */
#define LCD_LINE_LENGTH 0x40 /**< internal line length of the display */
#define LCD_START_LINE1 0x00 /**< DDRAM address of first char of line 1 */
#define LCD_START_LINE2 0x20 /**< DDRAM address of first char of line 2 */
#define LCD_START_LINE3 0x40 /**< DDRAM address of first char of line 3 */
#define LCD_START_LINE4 0x60 /**< DDRAM address of first char of line 4 */
#define LCD_WRAP_LINES 0 /**< 0: no wrap, 1: wrap at end of visibile line */

Jetzt sehe ich allerdings nur noch die 1. Zeile mit dem korrekten Text "Zeile1".

Hubert.G
22.01.2011, 14:47
Die Startadressen der Zeilen kommen mir eigenartig vor. Sollten die nicht so sein
#define LCD_START_LINE1 0x00 /**< DDRAM address of first char of line 1 */
#define LCD_START_LINE2 0x40 /**< DDRAM address of first char of line 2 */
#define LCD_START_LINE3 0x14 /**< DDRAM address of first char of line 3 */
#define LCD_START_LINE4 0x54 /**< DDRAM address of first char of line 4 */

tomy321
22.01.2011, 14:57
Ja, dachte ich zuerst auch. Wenn ich die Startadressen so einstelle und im Quellcode die Anweisung schreibe:
lcd_puts("Zeile1\nZeile2\nZeile3\nZeile4");
erhalte ich als Ausgabe:

Zeile1
________Zeile3
Zeile2
________Zeile4
(je 8 Leerzeichen vor der 2. und 3. Zeile und diese beiden Zeilen sind vertauscht)

Im Datenblatt des LCD's steht:
Zeile1 : $00...$13
Zeile2 : $20...33
Zeile3 : $40...53
Zeile4 : $60...73

Wenn ich das jetzt (siehe letzter Post) einstelle, geht's aber noch weniger...

Hubert.G
22.01.2011, 15:18
Die Zeilen sind nicht vertauscht, das ist schon richtig so.
Du siehst ja bei den Start-Adressen das die der Zeile 2 höher ist als von Zeile 3.
#define LCD_START_LINE1 0x00 /**< DDRAM address of first char of line 1 */
#define LCD_START_LINE2 0x28 /**< DDRAM address of first char of line 2 */
#define LCD_START_LINE3 0x14 /**< DDRAM address of first char of line 3 */
#define LCD_START_LINE4 0x3c /**< DDRAM address of first char of line 4 */Probier es mal mit diesen Adressen.
Sonst positioniere den Text mal mit lcd_gotxy(0,0) usw.

tomy321
22.01.2011, 16:15
So, jetzt habe ich folgende Ausgabe:


Zeile3

Zeile4



Irgendwie ist das verwirrend...

Hubert.G
22.01.2011, 20:41
Hast du es schon mit der Positonierung über lcd_gotoxy(0,0) probiert, dann weist du zumindest das die Zeilenanfangsadressen stimmem.
Das mit dem \n habe ich noch nie probiert, kann daher nicht sagen ob es überhaupt funktioniert.

tomy321
22.01.2011, 20:49
ja, habe ich, genau das selbe Ergebnis: Zeilen 2 und 4 beginnen erst ab dem 9. Zeichen

Hubert.G
22.01.2011, 22:05
Was ist wenn du den Start der zweiten Zeile auf 0x20 setzt.

tomy321
23.01.2011, 10:48
Wow, jetzt funktioniert es. Ich habe einfach mal verschiedene Werte für die Zeilenstartadressen ausprobiert und auf KS0073 controller gestellt:


#define LCD_CONTROLLER_KS0073 1 /**< Use 0 for HD44780 controller, 1 for KS0073 controller */

/**
* @name Definitions for Display Size
* Change these definitions to adapt setting to your display
*/
#define LCD_LINES 4 /**< number of visible lines of the display */
#define LCD_DISP_LENGTH 20 /**< visibles characters per line of the display */
#define LCD_LINE_LENGTH 0x40 /**< internal line length of the display */
#define LCD_START_LINE1 0x00 /**< DDRAM address of first char of line 1 */
#define LCD_START_LINE2 0x15 /**< DDRAM address of first char of line 2 */
#define LCD_START_LINE3 0x40 /**< DDRAM address of first char of line 3 */
#define LCD_START_LINE4 0x55 /**< DDRAM address of first char of line 4 */
#define LCD_WRAP_LINES 0 /**< 0: no wrap, 1: wrap at end of visibile line */



Mir ist zwar immer noch unklar, wieso ich diese Adressen benutzen soll, und wo man diese findet (außer ausprobieren), aber es funktioniert ja jetzt :).

Nochmals Danke an alle für die Hilfe.

Grüße,
tomy

MarioK
07.03.2011, 20:14
Hallo zusammen,

ich habe versucht mit dem AVRSTUDIO den Source mit der geänderten LCD.H zu kompilieren aber ich bekomme immer wieder die Fehlermeldung


C:\Users\lastyle\Coding\AtmegaWinavr\lcdtest\lcdte st\default/../lcdtest.c:9: undefined reference to `lcd_init'
C:\Users\lastyle\Coding\AtmegaWinavr\lcdtest\lcdte st\default/../lcdtest.c:12: undefined reference to `lcd_clrscr'
C:\Users\lastyle\Coding\AtmegaWinavr\lcdtest\lcdte st\default/../lcdtest.c:15: undefined reference to `lcd_puts'

Warum schmeisst nder mir eine undefined reference zu meinen lcd kommandos raus obwohl ich die lcd.h als header mit angegeben habe und da die befehle auch definiert sind ?

Kann mir da jemand helfen ?

Gruß Mario

oberallgeier
09.03.2011, 23:48
Hi MarioK
... Warum schmeisst nder ... die lcd.h als header mit angegeben ...Vielleicht kann man besser helfen, wenn Du Deine Includes mit nennst? Die vom "main", lcdtest und so. Einfach zumindest als Schnippsel im Codefenster zeigen.

super-robman
25.08.2011, 14:36
Hallo,

ich habe ein ähnliches Problem mit dem DIP LCD. Ich habe es an den PortC vom RN-Mega2560 angeschlossen. Leider sind beim RN-Mega2560 alle Pins paarweise vertauscht, also nicht 01234567 sondern 10325476.
Deshalb auch die komischen einstellungen:
#define LCD_PORT PORTC /**< port for the LCD lines */
#define LCD_DATA0_PORT LCD_PORT /**< port for 4bit data bit 0 */
#define LCD_DATA1_PORT LCD_PORT /**< port for 4bit data bit 1 */
#define LCD_DATA2_PORT LCD_PORT /**< port for 4bit data bit 2 */
#define LCD_DATA3_PORT LCD_PORT /**< port for 4bit data bit 3 */
#define LCD_DATA0_PIN 2 /**< pin for 4bit data bit 0 */
#define LCD_DATA1_PIN 3 /**< pin for 4bit data bit 1 */
#define LCD_DATA2_PIN 0 /**< pin for 4bit data bit 2 */
#define LCD_DATA3_PIN 1 /**< pin for 4bit data bit 3 */
#define LCD_RS_PORT LCD_PORT /**< port for RS line */
#define LCD_RS_PIN 6 /**< pin for RS line */
#define LCD_RW_PORT LCD_PORT /**< port for RW line */
#define LCD_RW_PIN 7 /**< pin for RW line */
#define LCD_E_PORT LCD_PORT /**< port for Enable line */
#define LCD_E_PIN 4 /**< pin for Enable line */

#define XTAL 16000000 /**< clock frequency in Hz, used to calculate delay timer */

#define LCD_CONTROLLER_KS0073 1 /**< Use 0 for HD44780 controller, 1 for KS0073 controller */

#define LCD_LINES 4 /**< number of visible lines of the display */
#define LCD_DISP_LENGTH 20 /**< visibles characters per line of the display */
#define LCD_LINE_LENGTH 0x40 /**< internal line length of the display */
#define LCD_START_LINE1 0x00 /**< DDRAM address of first char of line 1 */
#define LCD_START_LINE2 0x15 /**< DDRAM address of first char of line 2 */
#define LCD_START_LINE3 0x40 /**< DDRAM address of first char of line 3 */
#define LCD_START_LINE4 0x55 /**< DDRAM address of first char of line 4 */
#define LCD_WRAP_LINES 0 /**< 0: no wrap, 1: wrap at end of visibile line */

#define LCD_IO_MODE 1 /**< 0: memory mapped mode, 1: IO port mode */

Ich habe alles so eingestellt wie ich es bei verschiedenen Beiträgen im Forum gefunden habe, aber das Display zeigt nur die Schwarzen Kästen an, keinen Text.

Im Programm hab ich nur:

#include <stdlib.h>
#include <avr/io.h>
#include "lcd.h"

int main(void)
{
lcd_init(LCD_DISP_ON_CURSOR_BLINK);
lcd_clrscr();
lcd_puts("Hello World.");

Was kann ich noch ändern?

Viele Grüße und Danke.

robert

Hubert.G
25.08.2011, 16:03
Wenn du nur schwarze Kästchen hast, dann hat das init nicht funktioniert.
Wo hast du diese Modul stecken das die Pins vertauscht sind, kontrollier das noch mal.

super-robman
25.08.2011, 17:10
Die Pins am RN-Mega2560 sind auf jeder Seite 50 Stück. Wenn ich ein Kabel anschließe sollten die Pins am Kabel von einer Seite zur anderen von Pin1 nach Pin50 durchnummerrierbar sein. Allerdings habe ich festgestellt, dass die Pins immer paarweise vertauscht sind. Das heißt Pin1 dann Pin0 dann Pin3 dann Pin2 und so weiter. Das kann ich leider nicht ändern (außer jeweil die Kabel paarweise verdrehen).

Übrigens, wenn ich:
lcd_init(LCD_DISP_ON_CURSOR_BLINK);
lcd_clrscr();
lcd_puts("Hello World.");

raus nehme bekomme ich keine 4 schwarzen Leisten, also muss die init zumindestens versuchen was zu machen. Oder die init geht, aber die Ausgabe nicht .... ich weiß auch nicht weiter.

Hubert.G
25.08.2011, 18:05
Wenn du vier schwarze Leisten bekommst, dann ist aber möglicherweise nur der Kontrast falsch eingestellt.

super-robman
25.08.2011, 18:38
Ja, der Kontrast war nicht richtig eingestellt. Uff, was man nicht alles beachten muss.