www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik LCD AVR C ROUTINEN


Autor: Ingo Laabs (grobian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so...
nachdem der Port A nun blinkt habe ich an PortB (Tiny26) ein LCD Display 
angeschlossen. Ich betreibe (oder möchte) es im 4 Bit Modus und die 
Leitungen RS und E sind ebenfalls am Port B an geschlossen. Wie geht es 
nun weiter. Habe hier schon die Dateien lcd.c und lcd.h gefunden aber 
die beziehen sich ja wohl auf den Busbetrieb. Wo finde ich die 
entsprechenden Dateien die ich in mein Programm einbinden muß bzw. 
welche Änderungen
muß ich für meine Hardwareconfigurationen vornehmen??

Autor: Daniel R. (zerrome)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
was meinst du mit Busbetrieb?

Ich hab mir aus dem Tutorial die lcd.h und lcd.c so umgeschrieben,
dass man da die gewünschten Pins angeben kann, also frei wählen...
Brauchst du das oder was meinst du?

Autor: Ingo Laabs (grobian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich denke mal, das wird es sein. Mit Busbetrieb meine ich,dass das 
Display über einen Adressdekoder (z.B. 74ls138) selektiert wird.
Was muß ich in den Routinen ändern??

Autor: Daniel R. (zerrome)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich Poste einfach mal das was ich da geändert habe...
Is warscheinlich nicht optimal, läuft aber.

Das ist die lcd.c

//******************************************************************************** 
// sendet ein Datenbyte an das LCD
 
void lcd_data(unsigned char data8){   
 
     LCD_RSP |= (1<<LCD_RS);        // RS auf 1 setzen
   
  setPin();
  if(data8 & 128)LCD_D3P |=(1<<LCD_D3);  //hi nibbels  
  if(data8 & 64)LCD_D2P  |=(1<<LCD_D2);
  if(data8 & 32)LCD_D1P  |=(1<<LCD_D1);
  if(data8 & 16)LCD_D0P  |=(1<<LCD_D0);
  lcd_enable();
 
    setPin();
  if(data8 & 8)LCD_D3P |=(1<<LCD_D3);    //low nibbels
  if(data8 & 4)LCD_D2P |=(1<<LCD_D2);
  if(data8 & 2)LCD_D1P |=(1<<LCD_D1);
  if(data8 & 1)LCD_D0P |=(1<<LCD_D0);     
     lcd_enable();
   
    waitms(1);
}

//******************************************************************************** 
//rücksetzen der Daten pins

void setPin(void){

  LCD_D3P &= ~(1<<LCD_D3);  
  LCD_D2P &= ~(1<<LCD_D2);
  LCD_D1P &= ~(1<<LCD_D1);
  LCD_D0P &= ~(1<<LCD_D0);
}

//******************************************************************************** 
// sendet einen Befehl an das LCD
 
void lcd_command(unsigned char cmd8){

     LCD_RSP &= ~(1<<LCD_RS);        // RS auf 0 setzen
 
  setPin();
  if(cmd8 & 128)LCD_D3P |=(1<<LCD_D3);  //hi nibbels  
  if(cmd8 & 64)LCD_D2P  |=(1<<LCD_D2);
  if(cmd8 & 32)LCD_D1P  |=(1<<LCD_D1);
  if(cmd8 & 16)LCD_D0P  |=(1<<LCD_D0);
  lcd_enable();
 
    setPin();
  if(cmd8 & 8)LCD_D3P |=(1<<LCD_D3);    //low nibbels
  if(cmd8 & 4)LCD_D2P |=(1<<LCD_D2);
  if(cmd8 & 2)LCD_D1P |=(1<<LCD_D1);
  if(cmd8 & 1)LCD_D0P |=(1<<LCD_D0);     
     lcd_enable();
   
  waitms(1);
}
 
//********************************************************************************
// erzeugt den Enable-Puls

void lcd_enable(void)
{
   LCD_ENP |= (1<<LCD_EN);    // kurze Pause (?!?)   
   LCD_ENP &= ~(1<<LCD_EN);
}

//******************************************************************************** 
// Initialisierung: 
// Muss ganz am Anfang des Programms aufgerufen werden.
 
void lcd_init(void)
{
     LCD_RSDDR |= (1<<LCD_RS);   //initial der ports (ausgänge schalten)
     LCD_ENDDR |= (1<<LCD_EN);   
  LCD_D3DDR  |=(1<<LCD_D3);
  LCD_D2DDR  |=(1<<LCD_D2);
  LCD_D1DDR  |=(1<<LCD_D1);
  LCD_D0DDR  |=(1<<LCD_D0); 

   // muss 3mal hintereinander gesendet werden zur Initialisierung
 
    waitms(15);          //nach power on warten..

   setPin();
    LCD_D1P |=(1<<LCD_D1);
  LCD_D0P |=(1<<LCD_D0);     
     LCD_RSP &= ~(1<<LCD_RS);    // RS auf 0
     lcd_enable();         //1.
  waitms(5);

     lcd_enable();         //2.
     waitms(1);

     lcd_enable();        //3.
     waitms(1);
 
     
     setPin();          // 4 Bit Modus aktivieren      
     LCD_D2P |= (1<<LCD_D2);      
     lcd_enable();
     waitms(1);
     
     lcd_command(0x28);      // 4Bit / 2 Zeilen / 5x7 char größe
     
     lcd_command(0x0C);       // Display ein / Cursor aus / kein Blinken 
     
     lcd_command(0x06);      // inkrement / kein Scrollen
 
     lcd_clear();
}
 
//********************************************************************************
// Sendet den Befehl zur Löschung des Displays
 
void lcd_clear(void)
{
   lcd_command(CLEAR_DISPLAY);
   waitms(5);
}
 
//********************************************************************************
// Sendet den Befehl: Cursor Home
 
void lcd_home(void)
{
   lcd_command(CURSOR_HOME);
   waitms(5);
}

//******************************************************************************** 
// setzt den Cursor in Zeile y (1..2) Spalte x (0..15)
 
void set_cursor(uint8_t x, uint8_t y)
{
  uint8_t tmp=0;
 
  switch (y) {
    case 1: tmp=0x80+0x00+x; break;    // 1. Zeile
    case 2: tmp=0x80+0x40+x; break;    // 2. Zeile
  }
  lcd_command(tmp);
}

//******************************************************************************** 
// Schreibt einen String auf das LCD
 
void lcd_string(char *data)
{
    while(*data) {
        lcd_data(*data);
        data++;
    }
}

und das die lcd.h


void lcd_data(unsigned char temp1);        //einzelnes Zeichen
void lcd_string(char *data);          //string ausgeben
void lcd_command(unsigned char temp1);          //komando an lcd
void lcd_enable(void);              //leachen der daten
void lcd_init(void);              //initialisierung
void lcd_home(void);              //cursor at home
void lcd_clear(void);              //bildschirm löschen
void set_cursor(uint8_t x, uint8_t y);            //cursor positionieren
void setPin(void);                //alle 4 Daten pins auf 0 setzen
 
// Hier die verwendete Taktfrequenz in Hz eintragen, wichtig!
 
#define F_CPU 8000000UL
 
// LCD Befehle
 
#define CLEAR_DISPLAY 0x01
#define CURSOR_HOME   0x02

//******************************************************** 
// Pinbelegung für das LCD, an verwendete Pins anpassen !!

#define LCD_RSDDR    DDRC    //rs und en ,ddr ,port ,pin
#define LCD_ENDDR    DDRB 

#define LCD_RSP      PORTC    
#define LCD_ENP      PORTB

#define LCD_RS       PC2
#define LCD_EN       PB2

//********************************************************
#define LCD_D0DDR    DDRB    //4 daten ,pins ,ddr ,port
#define LCD_D1DDR    DDRC
#define LCD_D2DDR    DDRB
#define LCD_D3DDR    DDRB

#define LCD_D0P      PORTB
#define LCD_D1P      PORTC
#define LCD_D2P      PORTB
#define LCD_D3P      PORTB

#define LCD_D0       PB1
#define LCD_D1       PC3
#define LCD_D2       PB5
#define LCD_D3       PB0

//********************************************************
#include "D:\avr\AVR\cprogs\libs\lcd\lcd.c"


Autor: Ingo Laabs (grobian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich bin was c betrifft hier absoluter neuling, von daher mal die frage:

ich habe wie folgt angeschlossen:
1  Vss  GND
2  Vcc  5V
3  Vee  GND
4  RS  PB4 am AVR
5  RW  GND
6  E  PB5 am AVR
7  DB0  nicht angeschlossen
8  DB1  nicht angeschlossen
9  DB2  nicht angeschlossen
10  DB3  nicht angeschlossen
11  DB4  PB0 am AVR
12  DB5  PB1 am AVR
13  DB6  PB2 am AVR
14  DB7  PB3 am AVR


wo muß ich ändern??

Autor: Daniel R. (zerrome)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also erstmal in der lcd.h

Als Beispiel:

#define LCD_RSDDR    DDRB
#define LCD_ENDDR    DDRB

#define LCD_RSP      PORTB
#define LCD_ENP      PORTB

#define LCD_RS       PB4
#define LCD_EN       PB5

für die beiden Ports RS und EN

LCD_D0 wäre bei dir dann PB0 und so weiter...

Wichtig ist das der eigentliche Port z.B. LCD_RS und die beiden 
dazugehörigen anderen defines übereinstimmen (LCD_RSP und LCD_RSDDR).

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da du die lcd Routinen hier aus dem gcc Tutorial benutzt.
In der lcd.h gibt es einen Abschnitt
// Pinbelegung für das LCD, an verwendete Pins anpassen
#define LCD_PORT      PORTD
#define LCD_DDR       DDRD
#define LCD_RS        PD4
#define LCD_EN        PD5

dort trägst du die Pinbelegung ein.
Dein LCD hängt am Port B. Also wird das wohl heissen
#define LCD_PORT      PORTB
mit dem Port einher geht das Data Direction Register
#define LCD_DDR       DDRB

Die Datenleitungen sind beim Tutorial Code fix auf Bit 0 bis
Bit4. Das passt mit deiner Belegung überein.

Deine RS Leitung hängt am Pin PB4. Also schreibst du das auch so rein
#define LCD_RS        PB4

und deine Enable-Leitung vom LCD geht auf Pin PB5
#define LCD_EN        PB5

Ist doch nicht so schwer, oder?

Autor: Ingo Laabs (grobian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
na ja dafür,dass ich erst seit zwei Tagen dabei bin und es immerhin 
schon blinkt und läuft...geht doch oder??

Autor: Ingo Laabs (grobian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ähhhhhh......wo finde ich die Dateien lcd.h und lcd.c ??

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ingo Laabs wrote:
> Ähhhhhh......wo finde ich die Dateien lcd.h und lcd.c ??

Dazu müsste man erst mal wissen, welche do dir aus dem
Netz geholt hast. Die sind nicht beim Compiler dabei.

LCD Routinen gibt es wie Sand am Meer.
zb hier 
http://www.mikrocontroller.net/articles/AVR-GCC-Tu...
oder auch hier 
Beitrag "Re: LCD AVR C ROUTINEN"
oder diese hier http://homepage.hispeed.ch/peterfleury/avr-software.html

Autor: Ingo Laabs (grobian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
habe noch keine aus dem Netz gezogen..suche sie noch..s.o.

Autor: Ingo Laabs (grobian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So nun läuft mein LCD, habe jetzt nur ein Problem mit der Zeile 
set_cursor.
Ich bekomme den cursor nur in die 2. Zeile mit der Anweisung 
set_cursor(0,2). obwohl der Syntax doch eigentlich Zeile y(1..2) und 
Spalte x(0..15)
ist. Was ist hier falsch??

#define F_CPU 800000UL
#include <avr/io.h>
#include <util/delay.h>
#include <lcd.h>
#include <lcd.c>

int main(void)


lcd_init();

set_cursor(1,0);
lcd_string("ZEILE 1         ");

set_cursor(0,2);
lcd_string("ZEILE 2         ");

Autor: fubu1000 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich nehme mal an du benutzt die lcd-routinen von mikrocontroller.net !
Du musst dir die Quellcodes schon mal anschauen, dann ist dir auch klar 
warum du nur mit 2 in die 2.Zeile kommst.
Der erstes aufruf ist übrigens falsch mit setcursor(1,0). Der 
funktioniert nur weil du vorher lcd_init() gemacht hast, der den Cursor 
schon auf Anfang setzt.

da steht nämlich .....

void set_cursor(unsigned char x, unsigned char y)
{
  unsigned char command;

    switch (y)
  {
      case 1:    command=0x80+0x00+x; break;    // 1. Zeile
      case 2:     command=0x80+0x40+x; break;    // 2. Zeile
}

das bedeutet also mit setcursor(0,1) -> 1.Zeile , 1.Zeichen und
setcursor (0,2) -> 2.Zeile , 1.Zeichen.

GRUSS

Autor: Ingo Laabs (grobian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gibt es da noch weitere kommandos, was kann ich noch bei lcd_init() 
einsetzen??

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier
http://www.mikrocontroller.net/articles/AVR-Tutori...
findest du eine Übersicht über die Befehle, die so ein LCD
normalerweise versteht.

Autor: Ingo Laabs (grobian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die sind mir bekannt.Ich meinte die kommandos von C aus ..sowie 
set_cursor
Ich kann doch mit sicherheit von c aus auch scrollen oder den cursor 
blinken lassen. sowas meint ich

Autor: Daniel R. (zerrome)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Controller versteht gewisse Kommandos,

nachzulesen im Datenblatt oder hier :

http://www.mikrocontroller.net/articles/HD44780

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ingo Laabs wrote:
> Die sind mir bekannt.Ich meinte die kommandos von C aus ..sowie
> set_cursor
> Ich kann doch mit sicherheit von c aus auch scrollen oder den cursor
> blinken lassen. sowas meint ich

Du hast die Kommandoübersicht.
Was hindert dich daran, dir diese Funktionen selber zu schreiben?
Immerhin bist du auf dem Weg Programmierer zu werden. Gewöhn dich
schon mal daran, dass das auch heisst: Sich selbst Werkzeuge
zu basteln.
"Malen nach Zahlen" war gestern. Heute entwirfst du selbst deine
Motive und mischt auch die Farben selbst.

Autor: Daniel R. (zerrome)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Als Tipp :

Die Funktion lcd_command() kann schon Kommandos senden...

Musst jetzt noch ermitteln welchen Hex wert dein Kommando hat :)

Autor: Ingo Laabs (grobian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bin dabei. Habe die Ansteuerung schon in Assembler mal geschrieben nur 
fehlt mir noch in C die gewisse Erfahrung da ich mich jetzt als 
Umsteiger betrachte. Denke aber mal ich bekomme das hin. In Assembler 
hat auch alles geklappt. Ist nur alles ein wenig gewöhnungsbedürftig in 
C..trotzdem DANKE :-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.