Forum: Mikrocontroller und Digitale Elektronik Atmega 32 , 4bit -LCD Ansteuerung


von Lisa K. (lisa80)


Angehängte Dateien:

Lesenswert?

Hallo
habe folgendes Problem. Wäre super nett, Dankbar wenn mir jemand bei der
Initialisierung eines LCD-Displays (HD44780-typ) helfen könnnte. Habe 
schon ein Code dafür geschrieben. Aber die Initialisierung schlägt immer 
wieder fehl.Benutze den ICCAVR von Imagecraft.

DANKE.

Lisa

von Marc S. (eurofighter) Benutzerseite


Lesenswert?

1. du includierst eine macros.h, was steht drin ? (wenns eine 
vorgefertigte ist, die ich nicht kenne einfach überlesen)

2. nimm anstelle deines schleifendelays lieber _delay_us(_) aus 
<utils/delay.>. Damit bist auf der sicheren Seite das der Compiler nix 
wegoptmimert.

Ansonnsten schau dir einfach mal diese Routinen an, funktionieren schon 
ne lange Weile bei mir in ner Alarmanlage im Dauerbetrieb (auf nem 
Mega32 mit 16 Mhz):

einmal die .h :
1
// Version 1.0 (c) 2007 by Marc Seiffert [€uro]
2
3
#include <stdint.h>
4
#include <avr/io.h>
5
#include <util/delay.h>
6
#include <stdbool.h>
7
8
// Basisroutinen
9
void lcd_enable(void);
10
void lcd_data(uint8_t temp1);
11
void lcd_command(uint8_t temp1);
12
void lcd_init(void);
13
void lcd_clear(void);
14
void lcd_home(void);
15
16
// Steuerroutinen
17
void lcd_setcursor(uint8_t x, uint8_t y);

und die .c :
1
// Version 1.0 (c) 2007 by Marc Seiffert [€uro]
2
3
#include "LCD4.h"
4
 
5
#define DELAY_US() _delay_us(40);
6
#define NOP  __asm__ __volatile__("nop"::)
7
8
#define PORT_LCD      PORTB
9
#define LCD_RS        7
10
#define LCD_RW        6
11
#define LCD_EN        5
12
13
void lcd_data(unsigned char temp1)
14
{
15
  unsigned char temp2 = temp1;
16
  temp1 = temp1 >> 4;
17
  temp1 = temp1 & 0x0F;
18
  TCCR0 = 0x00;
19
  PORT_LCD &= 0xF0;
20
  PORT_LCD |= temp1 | (1<<LCD_RS);
21
  lcd_enable();
22
  temp2 = temp2 & 0x0F;
23
  PORT_LCD &= 0xF0;
24
  PORT_LCD |= temp2 | (1<<LCD_RS);
25
  lcd_enable();
26
  TCCR0 = 0b01101001;
27
  PORT_LCD &= 0b11101111;
28
  DELAY_US();
29
}
30
 
31
void lcd_command(unsigned char temp1)
32
{
33
  unsigned char temp2 = temp1;
34
  TCCR0 = 0x00;
35
  PORT_LCD &= 0b01111111;
36
  temp1 = temp1 >> 4;
37
  temp1 = temp1 & 0x0F;
38
  PORT_LCD &= 0xF0;
39
  PORT_LCD |= temp1;
40
  lcd_enable();
41
  temp2 = temp2 & 0x0F;
42
  PORT_LCD &= 0xF0;
43
  PORT_LCD |= temp2;
44
  lcd_enable();
45
  TCCR0 = 0b01101001;
46
  PORT_LCD &= 0b11101111;
47
  DELAY_US();
48
}
49
50
void lcd_enable(void){
51
  PORT_LCD |= (1<<LCD_EN);
52
  NOP;NOP;NOP;
53
  PORT_LCD &= ~(1<<LCD_EN);
54
}
55
 
56
57
void lcd_init(void)
58
{
59
  unsigned char temp3 = 50;
60
  while(temp3 != 0){_delay_ms(5);temp3 = temp3 - 1;}
61
  PORT_LCD |= 0x03;   lcd_enable();
62
  PORT_LCD |= 0x03;   lcd_enable();
63
  PORT_LCD |= 0x03;   lcd_enable();
64
  PORT_LCD |= 0x02;
65
  lcd_enable();
66
  _delay_ms(5);
67
  lcd_command(0x28);      
68
  lcd_command(0x0C);      
69
  lcd_command(0x04);
70
}
71
 
72
void lcd_clear(void)
73
{
74
  lcd_command(0x01);
75
  _delay_ms(5);}
76
77
void lcd_home(void)
78
{
79
  lcd_command(0x02);
80
  _delay_ms(5);
81
}
82
83
void lcd_setcursor(uint8_t x, uint8_t y)
84
{
85
  uint8_t temp = 128 + x;
86
  if(y==1){temp+=0x40;};
87
  if(y==2){temp+=0x14;};
88
  if(y==3){temp+=0x54;};
89
  lcd_command(temp);
90
}

ajo, die HG-Bel liegt noch als PWM auf dem port, aber das ist ja an den 
betreffenden stellen ersichtlich, die sind für dich nicht relavant

Gruß,

Marc

von Karl H. (kbuchegg)


Lesenswert?

3 Dinge

* Da du am PORTC ausgibst:
  Du hast doch das JTAG Interface abgeschaltet?

*
  void LCD4_WR4bits(unsigned char c)
  {
    LCD_E_SET;
    RSRW_CLR;
    WASTE;
    PORTC |= c;
    WASTE;
    LCD_E_CLR;
    wait(1000);
  }

  Leg erst die Daten an den Ausgang und schalte dann den E-Pin
  einmal 1, warten, E Pin wieder auf 0

  Auf die Art bist du unabhängig davon, wann genau der Chip
  die Daten übernimmt.

* Wieso heist die Funktion eingentlich LCD4_WR4bits wenn
  du manchmal offensichtlich 5 Bits ausgewertet haben willst?

  Wie zb hier:
    LCD4_WR4bits( 0x18);            // Function Set 8bit  0x03
    wait(500);

  Disclaimer: Mir ist schon klar, dass du auf diese Art
  ein zusätzliches Bit einschummeln willst, welches die
  Kommando / Datenumschaltung erledigt (sprich den RS Pin
  ansteuert). Oder ist es der RW Pin?
  Du solltest dir IMHO trotzdem überlegen, ob das so schlau ist.
  Schlieslich verschleiert es dann doch eine ganze Menge.
  2 getrennte Funktionen für Daten und Kommandos kosten nicht
  unbedingt den Speicherplatz und sind für den Aufrufer um einiges
  klarer als solche Tricksereien.
  Man kann sich auch selbst austricksen.

von Karl H. (kbuchegg)


Lesenswert?

Jetzt seh ichs erst:
Warum hast du schon wieder in die Codesammlung gepostet?

Codesammlung = Sammlung von Code, welcher funktioniert

von Lisa K. (lisa80)


Angehängte Dateien:

Lesenswert?

Karl heinz Buchegger wrote:
> Jetzt seh ichs erst:
> Warum hast du schon wieder in die Codesammlung gepostet?
>
> Codesammlung = Sammlung von Code, *welcher funktioniert*

Das ist Richtig, ich habe in die Codesammlung schon reingeschaut. Bin 
aber nicht so fit wie einge hier im Forum, deshalb ist es sehr schwer, 
was für profis banal ist, zu verstehen und für meinen Fall anzuwenden.

Um zu deinem Post zurückzukommen,

- JTag Interface abgeschatet ?:
Nein, habe nicht abgeschaltet, wüsste erstmal nicht wie es geht.


Ich habe eine vorgefertigte Platine die festverlötet ist, wie hier auch 
das LCD Display. Die Beschaltung ist wie folt:

PORT C Bits     :  C1  C2  C3  C4
LCD Datenleitung:  D7  D6  D5  D4

PORT C7 : RS
PORT C6 : RW
PORT C5 : E


Die Header-Datei makros.h ist für den LCD - Teil nicht wichtig. Könnte 
auch genausogut raus. Enthalten einige asm Befehle.

von Falk B. (falk)


Lesenswert?

@ Lisa Klein (lisa80)

>- JTag Interface abgeschatet ?:
>Nein, habe nicht abgeschaltet, wüsste erstmal nicht wie es geht.

Über die AVR Fuses.

>Ich habe eine vorgefertigte Platine die festverlötet ist, wie hier auch
>das LCD Display. Die Beschaltung ist wie folt:

>PORT C Bits     :  C1  C2  C3  C4
>LCD Datenleitung:  D7  D6  D5  D4

>PORT C7 : RS
>PORT C6 : RW
>PORT C5 : E

Na das ist doch wie gemacht für das Tutorial.

Einfach die Pins anpassen und gut.

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#LCD-Ansteuerung

MfG
Falk

von Lisa K. (lisa80)


Angehängte Dateien:

Lesenswert?

Marc Seiffert wrote:
> 1. du includierst eine macros.h, was steht drin ? (wenns eine
> vorgefertigte ist, die ich nicht kenne einfach überlesen)
>
> 2. nimm anstelle deines schleifendelays lieber _delay_us(_) aus
> <utils/delay.>. Damit bist auf der sicheren Seite das der Compiler nix
> wegoptmimert.

Hallo Marc,

Danke für deine Nachricht.

Die Header Datei makros.h enthält für den LCD-Teil nichts wichtiges. Es 
sind lediglich einige asm Befehle enthalten. Die habe ich hier 
angehängt.

Wie kann ich die "_delay_us(__)" aus ...
Die Ordner gibt es bei mir nicht. Handelt es sich hierbei um den selben
cross - compiler ? Ich habe den von Image Craft: ICCAVR V7.14.

Gruss

von Karl H. (kbuchegg)


Lesenswert?

Lisa Klein wrote:
> Karl heinz Buchegger wrote:
>> Jetzt seh ichs erst:
>> Warum hast du schon wieder in die Codesammlung gepostet?
>>
>> Codesammlung = Sammlung von Code, *welcher funktioniert*
>
> Das ist Richtig, ich habe in die Codesammlung schon reingeschaut. Bin
> aber nicht so fit wie einge hier im Forum, deshalb ist es sehr schwer,
> was für profis banal ist, zu verstehen und für meinen Fall anzuwenden.
>

Du meinst, es ist zu schwer für dich, das richtige Forum herauszusuchen
in welches deine Frage hineinpasst?

> - JTag Interface abgeschatet ?:
> Nein, habe nicht abgeschaltet, wüsste erstmal nicht wie es geht.

Hat Falk schon beantwortet: Es gibt ein Fusebit, mit dem man
JTAG abschalten kann.

> Ich habe eine vorgefertigte Platine die festverlötet ist, wie hier auch
> das LCD Display. Die Beschaltung ist wie folt:
>
> PORT C Bits     :  C1  C2  C3  C4
> LCD Datenleitung:  D7  D6  D5  D4

Bist du dir da ganz sicher? Man kann das zwar so verschalten, aber
die Programmierung wird um einiges einfacher, wenn man das so
verschaltet:

PORT C Bits     :  C1  C2  C3  C4
LCD Datenleitung:  D4  D5  D6  D7

Dann muss man ein Nibble nicht in sich spiegeln, bevor es
ausgegeben wird.

von Lisa K. (lisa80)


Lesenswert?

Karl heinz Buchegger wrote:
> Lisa Klein wrote:
>> Karl heinz Buchegger wrote:
>>> Jetzt seh ichs erst:
>>> Warum hast du schon wieder in die Codesammlung gepostet?
>>>
>>> Codesammlung = Sammlung von Code, *welcher funktioniert*
>>
>> Das ist Richtig, ich habe in die Codesammlung schon reingeschaut. Bin
>> aber nicht so fit wie einge hier im Forum, deshalb ist es sehr schwer,
>> was für profis banal ist, zu verstehen und für meinen Fall anzuwenden.
>>
>
> Du meinst, es ist zu schwer für dich, das richtige Forum herauszusuchen
> in welches deine Frage hineinpasst?

Ich hatte die Frage ganz anders verstanden. Wie Du als Moderator weisst, 
bin  ich erst seit einpar Tagen neuer Mitglied. Und Codesammlung hat 
sich auf anhieb  nicht schlecht angehört. Allerdings habe ich vom 
Webmaster folgendes E-Mail erhalten.

E-MAIL:
Ihr Beitrag im Forum "Codesammlung" wurde gelöscht.

Betreff: LCD Initialisierung
Datum: 04.02.2008 22:10
Text des gelöschten Beitrags:
==============================================
......

Dann habe ich einen neuen Beitrag erstellt und....

Du hast mir die Frage gestellt.

>>> Warum hast du schon wieder in die Codesammlung gepostet?

:-( habe gedacht die möchten wohl nicht dass ich hier poste bis ich 
folgendes gelesen habe:

> Du meinst, es ist zu schwer für dich, das richtige Forum herauszusuchen
> in welches deine Frage hineinpasst?

>>> Codesammlung = Sammlung von Code, *welcher funktioniert*

Codesammlung = Code Sammlung . So hatte ich es damals interpretiert.


>> Ich habe eine vorgefertigte Platine die festverlötet ist, wie hier auch
>> das LCD Display. Die Beschaltung ist wie folt:
>>
>> PORT C Bits     :  C1  C2  C3  C4
>> LCD Datenleitung:  D7  D6  D5  D4
>
> Bist du dir da ganz sicher? Man kann das zwar so verschalten, aber
> die Programmierung wird um einiges einfacher, wenn man das so
> verschaltet:

Ich bin mir 100%-tig sicher. Habe die beschaltung mehrmals leitung für 
leitung überprüft. Aber wie bereits erwähnt, ist die Platine fest 
verlötet.

> Dann muss man ein Nibble nicht in sich spiegeln, bevor es
> ausgegeben wird.

Das ganze wird dadurch für den Anfänger nicht leichter.
Es ist ja noch ein bit vom höheren nibble im spiel.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.