PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] LCD: Pos = 40*y + x geht nur teilweise



-schumi-
04.04.2011, 15:54
Hallo zusammen,

da ich leider ausversehen meine Sourcecodes ins Nirvana geschickt habe und nur noch eine halbfertige Lib fürs LCD hatte, hab ich die jetzt erweitert um wieder eine neue zu haben
(Jetzt ist alles in der DropBox -> OS ausversehen drüberinstallieren geht nicht mehr^^)

Allerdings habe ich ein Problem mit der Positionierung des Coursors:
1. Zeile: Funktioniert
2. Zeile: kann nur an den Anfang springen

Ich berechne die Adresse mit Pos = y*40 + x, siehe meine LCD.c:


void LCD_POS (unsigned int line, unsigned int column)
{
LCD_COMMAND(0b10000000 + (line*40) + column);
}
Warum? Ich checks einfach nicht...

Schon mal Danke im voraus :-D
-schumi-

[EDIT]
Es ist ein HDD44780 LCD mit 2*16 Zeichen

-schumi-
04.04.2011, 16:18
ARGH! Natürlich findet man die Lösung immer erst wenn man schon gepostet hat :)

Lösung:

1laaaaaa


l = Zeilennummer (0 oder 1)
a = 6-Bit Spaltennummer

( http://www.mikrocontroller.net/articles/AVR-Tutorial:_LCD#Routinen_zur_LCD-Ansteuerung_im_4-Bit-Modus )

-> LCD.c

void LCD_POS (unsigned int line, unsigned int column)
{
if(line)
LCD_COMMAND(0b11000000 + column);
else
LCD_COMMAND(0b10000000 + column);
}Entschuldigung für diesen wohl sehr überflüssigen Thread^^

Naja, dafür gibts die hier als Entschädigung die Lib zum nachbasteln (währe dann soweit fertig)

LCD.c:

#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include "LCD.h"

void LCD_SETBYTE (char data)
{
LCD_PORT = LCD_PIN & ~(LCD_D0 | LCD_D1 | LCD_D2 | LCD_D3);
if( data & 1<<0 ) LCD_PORT = LCD_PIN | LCD_D0;
if( data & 1<<1 ) LCD_PORT = LCD_PIN | LCD_D1;
if( data & 1<<2 ) LCD_PORT = LCD_PIN | LCD_D2;
if( data & 1<<3 ) LCD_PORT = LCD_PIN | LCD_D3;
}

void LCD_ENABLE (void)
{
LCD_PORT = (LCD_PIN | LCD_EN);
_delay_us(1);
LCD_PORT = (LCD_PIN & ~LCD_EN);
}

void LCD_DATA (char data)
{
char data2 = data;
data = (data>>4);
data = (data & 0b00001111);
LCD_PORT = (LCD_PIN | LCD_RS) & ~(LCD_EN | LCD_D0 | LCD_D1 | LCD_D2 | LCD_D3);
LCD_SETBYTE (data);
LCD_ENABLE();
_delay_us(45);

data2 = (data2 & 0b00001111);
LCD_PORT = (LCD_PIN | LCD_RS) & ~(LCD_EN | LCD_D0 | LCD_D1 | LCD_D2 | LCD_D3);
LCD_SETBYTE (data2);
LCD_ENABLE();
_delay_ms(2);
}



void LCD_COMMAND (char command)
{
char command2 = command;
command = (command>>4);
command = (command & 0b00001111);
LCD_PORT = LCD_PIN & ~(LCD_RS | LCD_EN | LCD_D0 | LCD_D1 | LCD_D2 | LCD_D3);
LCD_SETBYTE (command);
LCD_ENABLE();
_delay_us(45);

command2 = (command2 & 0b00001111);
LCD_PORT = LCD_PIN & ~(LCD_RS | LCD_EN | LCD_D0 | LCD_D1 | LCD_D2 | LCD_D3);
LCD_SETBYTE (command2);
LCD_ENABLE();
_delay_ms(2);
}

void LCD_STRING(char *string)
{
while(*string)
{
LCD_DATA(*string++); // zeichen am LC-Display ausgeben
}
}

void LCD_CLEAR (void)
{
LCD_COMMAND(0b00000001);
}

void LCD_HOME (void)
{
LCD_COMMAND(0b00000010);
}

void LCD_POS (unsigned int line, unsigned int column)
{
if(line)
LCD_COMMAND(0b11000000 + column);
else
LCD_COMMAND(0b10000000 + column);
}

void LCD_INT (int number)
{
char string[16];
itoa(number,string, 10);
LCD_STRING(string);
}

void LCD_HEX (int number)
{
char string[16];
itoa(number,string, 16);
LCD_STRING(string);
}

void LCD_BIN (int number)
{
char string[16];
itoa(number,string, 2);
LCD_STRING(string);
}

void LCD_OCT (int number)
{
char string[16];
itoa(number,string, 8);
LCD_STRING(string);
}

void LCD_INIT (void)
{
LCD_DDR = LCD_DDR | LCD_RS | LCD_EN | LCD_D0 | LCD_D1 | LCD_D2 | LCD_D3;
for(int inittimes=0; inittimes<3; inittimes++)
{
LCD_PORT = LCD_PIN | LCD_RS | LCD_EN | LCD_D0 | LCD_D1 | LCD_D2 | LCD_D3;
LCD_PORT = LCD_PORT = LCD_PIN & ~(LCD_EN | LCD_RS);
_delay_ms(15);
LCD_SETBYTE (0x30);
LCD_ENABLE();
_delay_ms(5);
LCD_ENABLE();
_delay_us(100);
LCD_ENABLE();
_delay_us(100);
LCD_SETBYTE (0x20);
LCD_ENABLE();
_delay_us(100);
LCD_COMMAND(0x28);
LCD_COMMAND(0x08);
LCD_COMMAND(0x01);
LCD_COMMAND(0x06);
LCD_COMMAND(0x0C);
LCD_COMMAND(0b00000001);
}
}
LCD.h:

#ifndef _LCD_h_
#define _LCD_h_

void LCD_SETBYTE (char data);
void LCD_ENABLE (void);
void LCD_DATA (char data);
void LCD_COMMAND (char command);
void LCD_STRING(char *string);
void LCD_CLEAR (void);
void LCD_HOME (void);
void LCD_POS (unsigned int line, unsigned int column);
void LCD_INT (int number);
void LCD_HEX (int number);
void LCD_BIN (int number);
void LCD_OCT (int number);
void LCD_INIT (void);

#define LCD_DDR DDRA
#define LCD_PORT PORTA
#define LCD_PIN PINA
#define LCD_EN PIN 6
#define LCD_RS PIN 4
#define LCD_D0 PIN 0
#define LCD_D1 PIN 1
#define LCD_D2 PIN 2
#define LCD_D3 PIN 3

#define PIN 1<<

#endif


Und ein kleines Anwendungsbeispiel (Laufschrift in der ersten Zeile und Counter in der zweiten):


#include <avr/io.h>
#include <util/delay.h>
#include "LCD.h"

int main(void)
{
LCD_INIT();

char Zeichenstring[] = "LCD-Lib funzt! ";
char temp;
char schleife;
unsigned char counter=0;

while(1)
{
LCD_CLEAR();
LCD_POS(0, 0);
LCD_STRING(Zeichenstring);
LCD_POS(1, 5);
LCD_INT(counter++);

temp = Zeichenstring[0];
for(schleife=0; schleife<14; schleife++)
{
Zeichenstring[schleife] = Zeichenstring[schleife+1];
}
Zeichenstring[14] = temp;
_delay_ms(220);
}
return 0;
}

Gruß
-schumi-

BMS
04.04.2011, 16:21
Hi,
also ich hab in meiner Lib anstatt einer 40 eine 64 stehen, probier's mal ;)
Grüße, Bernhard

edit: zu langsam

-schumi-
04.04.2011, 16:26
edit: zu langsam
Trotzdem danke für die Antwort!

Hab mal mit 64 ausprobiert -> funzt

Was auch damit zusammenhängen könnte dass 0b01000000 zufälligerweise 64 ist wie mir gerade einfällt :-D

Gruß

radbruch
04.04.2011, 16:31
Was für ein erstaunlicher Zufall ;) Übrigends wäre 0x40 auch 64.

Und wie immer sehr verblüffend: Kaum macht man es richtig, funktioniert es auch. Danke für die hübsche Library.

Gruß

mic

miicchhii
20.04.2011, 17:22
Hey, also wenn ich die lib und da Programm verwenden will, wie mach ich das dann?
ich hab leider keine ahnung von dem ganzen,
hab schon herumprobiert und so,
aber ich schaffs nichtmal das beispielprogramm zu compilieren...

gibt es irgendwo eine einführung in das thema lcd displays oder so,
das ich einfach noch nicht gefunden habe?

danke schonmal

mfg michi

-schumi-
20.04.2011, 18:30
Hallo miicchii :-D

leider hab ich irgendwie deinen Beitrag völlig verpennt... Sry 8-[


Machen tust du das so:
- du hast eine main.c, dort steht dann dein normaler Code drin
- Du nimmst jeweils noch die LCD.c und die LCD.h und speicherst sie im selben Ordner wie die main.c
- in der main.c dann >> #include "LCD.h" << einfügen (wie man in dem Beispiel oben sehen kann)
- dann noch in der LCD.h den Teil hier an deine Hardware anpassen:


#define LCD_DDR DDRA
#define LCD_PORT PORTA
#define LCD_PIN PINA
#define LCD_EN PIN 6
#define LCD_RS PIN 4
#define LCD_D0 PIN 0
#define LCD_D1 PIN 1
#define LCD_D2 PIN 2
#define LCD_D3 PIN 3Zum kompilieren musst du noch das Makefile verändern:
ziemlich weit oben steht das hier:

SRC = $(TARGET).cdas änderst du in:

SRC = $(TARGET).c LCD.cGruß
schumi

miicchhii
23.04.2011, 11:20
Danke für die Antwort, hab eine Lösung auf anderem wege gefunden,
läuft jetzt im 8-bit Modus, wahrscheinlich probier ichs später mit nur 4,
wenn ich das mal ganz verstanden hab xD
Ich verwende übrigens AVR Studio also nichts mit makefiles selber schreiben^^

danke und lg miicchhii