Hallo!
Ich möchte gerne ein LCD an PortC des Mega 8 anschliessen.
Ich hab jetzt eine Routine für einen Mega32 gefunden und möchte diese
gerne verwenden.
Jetzt hab ich nur ein Problem.
Der Mega32 hat am PortC mehr anschlüsse. Und das sieht dann in der
Routine wie folgt aus:
// define pins of LCD port
#define LCD_PIN_RS 2
#define LCD_PIN_E 3
#define LCD_PIN_D4 4
#define LCD_PIN_D5 5
#define LCD_PIN_D6 6
#define LCD_PIN_D7 7
Beziehen sich die Zahlen hinten auf PortC2, PortC3, usw.??
Kann ich die Zahlen einfach nach meinen Bedürfnissen ändern und mit 0
anfangen?
Bin noch anfänger in der Materie.
Das hier hab ich im Netz gefunden:
#define LCD_CLEAR 0x01 // clear display 0b 0000 0001
#define LCD_HOME 0x02 // cursor home 0b 0000 0010
#define LCD_ON 0x0C // cursor invisible 0b 0000 1100
#define LCD_OFF 0x08 // display off 0b 0000 1000
#define POS_01 0x80 // line 1 - column 0 0b 1000 0000
#define POS_02 0xC0 // line 2 - column 0 0b 1100 0000
#define LCDPORT PORTC // define port with LCD attached
#define LCDDDR DDRC // and its data direction
// define pins of LCD port
#define LCD_PIN_RS 2
#define LCD_PIN_E 3
#define LCD_PIN_D4 4
#define LCD_PIN_D5 5
#define LCD_PIN_D6 6
#define LCD_PIN_D7 7
// DEFINITIONS
#define sbi(PORT, bit) (PORT|=(1<<bit)) // set bit
#define cbi(PORT, bit) (PORT&=~(1<<bit)) // claear bit
#define tbi(PORT, bit) (PORT^=(1<<bit)) // toggle bit
#define COMMAND 0
#define DATA 1
// Function: Toggle enable pin
void toggle_enable_pin(void)
{
sbi(LCDPORT, LCD_PIN_E);
cbi(LCDPORT, LCD_PIN_E);
}
// Send Byte to LCD Controller
void lcd_send(unsigned char type, unsigned char c)
{
unsigned char sic_c; // Backup for c
// send high nibble
sic_c = c; // save original c
sic_c &= ~0x0f; // set bit 0-3 == 0
if (type==DATA)
sic_c |= (1<<LCD_PIN_RS); // Data: RS = 1
LCDPORT = sic_c; // send high nibble
toggle_enable_pin();
// send low nibble
sic_c = c; // save original c
sic_c = sic_c<<4; // exchange nibbles
sic_c &= ~0x0f; // set bit 0-3 == 0
if (type==DATA)
sic_c |= (1<<LCD_PIN_RS); // Data: RS = 1
LCDPORT = sic_c; // send low nibble
toggle_enable_pin();
_delay_ms(5); // Wait for LCD controller
}
// set cursor to line x and column y
void lcd_set_cursor(uint8_t x, uint8_t y)
{
uint8_t i;
switch (x)
{
case 1: i=0x80+0x00+y; break; // 1. line
case 2: i=0x80+0x40+y; break; // 2. line
default: return; // invalid line
}
lcd_send(COMMAND, i);
}
// Display String on LCD
void lcd_write(char *t)
{
unsigned char i;
for (i=0;i<255;i++)
{
if (t[i]==0) // End of String -> EXIT
return;
else
lcd_send(DATA, t[i]);
}
}
// initializing LCD Controller see data sheet for details
void lcd_init()
{
// Set LCD port to Output
LCDPORT = 0x00;
LCDDDR = 0xFF;
_delay_ms(50); // wait for LCD
// 4-bit Modus config
sbi(LCDPORT, LCD_PIN_D5);
cbi(LCDPORT, LCD_PIN_D4);
// 4-Bit mode start
sbi(LCDPORT, LCD_PIN_E);
cbi(LCDPORT, LCD_PIN_E);
_delay_ms(5);
// 2 Lines, 4-Bit Mode
lcd_send(COMMAND, 0x28);
lcd_send(COMMAND, LCD_OFF);
lcd_send(COMMAND, LCD_CLEAR);
lcd_send(COMMAND, 0x06);
lcd_send(COMMAND, LCD_ON);
}
Sven schrieb:> Beziehen sich die Zahlen hinten auf PortC2, PortC3, usw.??
Nein, die beziehen sich nicht speziell auf PortC2 usw.
#define NAME VALUE
ist eine Compileranweisung. Über wo NAME steht wird der Compiler VALUE
eintragen. Das sind eigentlich Grundlagen C.
Michael schrieb:> ist eine Compileranweisung.
Eigentlich sind das Präprozessoranweisungen. Aber wir wollen ja mal
nicht klug scheißen ;)
Der NichtKluchScheißer
@Sven
>Beziehen sich die Zahlen hinten auf PortC2, PortC3, usw.??
Ja aber nur wenn:
>#define LCDPORT PORTC // define port with LCD attached>#define LCDDDR DDRC // and its data direction
definierst.
würdest #define LCDPORT PORTD // define port with LCD attached
#define LCDDDR DDRD // and its data direction
definieren würde alles auf PortD ausgegeben bzw. empfangen.
So kann man gezielt und schnell seinen Code anpassen.
Gruß
norad
Hi Sven,
zwingt Dich irgend etwas diese Pinaufteilung zu wählen? Wenn Du Dich zu
der Pinbelegung aus dem AVR-GCC Tutorial überreden lassen könntest, ist
das Programm gleich wesendlich einfacher.
AVR-GCC-Tutorial/LCD-Ansteuerung
Welchen Port Du wählst kann da auch eingestellt werden.
Definiere in der .h Datei halt: #define LCD_PORT PORTC
Axel
NichtKluchScheißer schrieb:> Eigentlich sind das Präprozessoranweisungen.
Und was sind bitte schön Präprozessoranweisungen?
NichtKluchScheißer schrieb:> Aber wir wollen ja mal> nicht klug scheißen ;)
Dann tu es auch nicht.
Axel Düsendieb schrieb:> zwingt Dich irgend etwas diese Pinaufteilung zu wählen? Wenn Du Dich zu> der Pinbelegung aus dem AVR-GCC Tutorial überreden lassen könntest, ist> das Programm gleich wesendlich einfacher.
Oftmals braucht man aber einige Sonderfunktionen, gerade bei den
kleineren Typen.
Daher ist es praktischer, wenn das LCD beliebige Pins benutzen kann:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=102296
Peter
Michael schrieb:> Und was sind bitte schön Präprozessoranweisungen?
Das sind Anweisungen die im Quellcode noch vor dem Compilieren durch das
Programm selber übersetzt werden. So in der Richtung kann man das glaube
ich erklären :D
Rene K. schrieb:> Das sind Anweisungen die im Quellcode noch vor dem Compilieren durch das> Programm selber übersetzt werden. So in der Richtung kann man das glaube> ich erklären :D
Sie werden vom Compiler übersetzt bevor dieser Maschinencode draus
macht. Deshalb ja das Prä ;)
Michael schrieb:> Rene K. schrieb:>> Das sind Anweisungen die im Quellcode noch vor dem Compilieren durch das>> Programm selber übersetzt werden. So in der Richtung kann man das glaube>> ich erklären :D>> Sie werden vom Compiler übersetzt bevor dieser Maschinencode draus> macht. Deshalb ja das Prä ;)
Ja so hab ich das auch gemeint, konnte das aber nicht wirklich
ausdrücken :D
Danke schonmal für die Antworten.
Zur Problematik:
Ich möchte gerne einen optischen Drehzahlmesser bauen.
Das Signal meiner Quelle soll an T1 angeschlossen werden, also PD5.
Aus diesem Grund möchte ich das LCD über PortC laufen lassen.
Das macht nicht wirklich viel aus.
Das problematische bei so gut wie allen LCD-Funktionen sind die 4
Datenleitungen. Wenn man die wirklich universell quer über den Prozessor
verstreuen will, muss man da die Datenausgabe anders programmieren. Die
Steuerleitungen hingegen sind kein Problem. Das kann man leicht so
programmieren, dass sie auf anderen Pins liegen. Von daher ist es auch
kein Problem, wenn die zb auf einem ganz anderen Port liegen.
Nicht falsch verstehen: Natürlich kann man die 4 Datenleitungen auch so
programmieren, dass man sie einzeln beliebig über den Prozessor
verteilen kann. Der Code wird nur etwas einfacher, wenn man von der
Annahme ausgehen kann, dass die 4 Datenleitungen nebeneinander liegen
und zb beim Bit0 bzw beim Bit4 beginnen.
Sven schrieb:> // define pins of LCD port>> #define LCD_PIN_RS 2> #define LCD_PIN_E 3> #define LCD_PIN_D4 4> #define LCD_PIN_D5 5> #define LCD_PIN_D6 6> #define LCD_PIN_D7 7
Von den 8 Anschlüssen des PortC im 32er werden doch nur 6 genutzt.
Und genauso viele hat doch der 8er an seinem PortC. Nur daß diese von
0 - 5 gehen.
also
#define LCD_PIN_RS 0
#define LCD_PIN_E 1
#define LCD_PIN_D4 2
#define LCD_PIN_D5 3
#define LCD_PIN_D6 4
#define LCD_PIN_D7 5
mfg.
Karl heinz Buchegger schrieb:> Der Code wird nur etwas einfacher, wenn man von der>> Annahme ausgehen kann, dass die 4 Datenleitungen nebeneinander liegen>> und zb beim Bit0 bzw beim Bit4 beginnen.
Das kann man natürlich auch noch berücksichtigen:
#define LCD_PIN_RS 4
#define LCD_PIN_E 5
#define LCD_PIN_D4 0
#define LCD_PIN_D5 1
#define LCD_PIN_D6 2
#define LCD_PIN_D7 3
mfg.
Hallo Sven,
könntest Du mal bitte angeben,
aus welcher Quelle diese Routine ist?
Die scheint mir nämlich bis aufs Bit
identisch aus einem Buch abkopiert zu sein.
Bin zwar kein Profi auf dem Gebiet aber
so etwas 1:1 zu veröffentlichen kann
urheberrechtliche Probleme nach sich ziehen!
Gruss,
Mr X
Karl heinz Buchegger schrieb:> Der Code wird nur etwas einfacher, wenn man von der> Annahme ausgehen kann, dass die 4 Datenleitungen nebeneinander liegen> und zb beim Bit0 bzw beim Bit4 beginnen.
Im Gegenteil, er ist deutlich schwerer zu verstehen mit der ganzen
Rummaskiererei.
Man spart vielleicht ein paar Bytes Flash ein.
Mit Bitbefehlen ist es dagegen einfach und lesbar:
Peter Dannegger schrieb:> Im Gegenteil, er ist deutlich schwerer zu verstehen mit der ganzen> Rummaskiererei.
Nun ja.
Sagen wir mal: Das ist Ansichtssache
Also kann ich jetzt diese Routine auch mit einem Mega8 nutzen ohne sie
abzuändern?
Versteh ich das richtig?
Ich weis nicht mehr wo ich die Routine gefunden hab, aber da ich keine
Probleme bekommen möchte, kann ich sie auch wieder hier raus holen.
Oder es sagt mir jemand aus welchem Buch sie womöglich ist, dann schreib
ich das als Quellenangabe dazu.
Sven schrieb:> Also kann ich jetzt diese Routine auch mit einem Mega8 nutzen ohne sie> abzuändern?> Versteh ich das richtig?
Wenn du mit der Pinbelegung hinkommst
Ansonsten: LCD Routinen gibt es wie Sand am Meer
Das Programm stammt wohl aus dem Buch
"AVR-Mikrocontroller in C programmieren"
über 30 Selbstbauprojekte mit ATtiny13, ATmega8, ATmega32"
des FRANZIS Verlags.
Dort wird übrigens auch, genau wie Du oben "zufällig"
erwähnst, ein optischer Drehzalmesser mit LCD und ATMega32
beschrieben.
Wär jetz schon ein komischer Zufall,
wenn Du das Buch nicht kennen würdest...
Weiss nicht, was der Verlag zu obigem "Zitat" sagen würde!
Sorry, aber das Buch sagt mir leider garnichts.
Ich habe im Netz nach "optischer Drehzahlmesser Mega 8" gesucht und bin
dabei auf verschiedene Seiten gelangt, wo unter anderem auch diese LCD
Routine drin war.
Da es aber anscheinend Probleme gibt mit Urheberrechtsverletzungen bitte
ich den Thread zu löschen und möchte mich für die Problematik
entschuldigen!!
Und danke für den Tip mit dem Buch, das scheint interessant zu sein und
ist es wohl wert zu bestellen.
Oder ist es für Anfänger nicht zu empfehlen?