Forum: Mikrocontroller und Digitale Elektronik ATmega 1284P EA DIP122 LCD Steuerung


von Marcel (Gast)


Lesenswert?

Hallo Technikbegeisterte!

Wie der Titel schon sagt, versuche ich mit besagtem µController das EA 
DIP122 Display anzusteuern.

Problem dabei ist allerdings, dass jegliche Befehle zur Ausschaltung des 
Displays(Oder zumindest der Beleuchtung führen).

So führt z.B bereits der Enable Befehl zur Abschaltung.
Egal, welchen Befehl des Datenblatts ich sende, es passiert immer das 
gleiche.

Zunächst einmal die Verdrahtung.

Der RW Pin des Displays liegt dauerhaft auf GND, da ich keine Daten 
lesen möchte, weil das Display nur etwa alle fünf Sekunden aktualisiert 
werden soll und eine Busy Abfrage so unnötig ist.

Pin AO, also Daten oder Command liegt auf PB0

Die beiden Displayhälften liegen auf PB1 und PB2.

Der tatsächliche Datenbus, also D0-D7 liegt in gleicher Reihenfolge auf 
PortD.

Display ist an etwa 4.8V angeschlossen, Backlight etwa bei 4.1V.

Konstrastspannung ist bisher weggelassen worden, weil ich erstmal 
überhaupt testen wollte, was so möglich ist.

Reset Pin ist dauerhaft auf +5V, da ich keinen Reset brauche.


Nun zum Code Teil.
1
main.c:
2
3
#include "GlobalData.h"
4
#include "LCDAPI.h"
5
#include <avr/io.h>
6
#include <util/delay.h>
7
#include <stdio.h>
8
#include <stdlib.h>
9
10
int main(void)
11
{
12
  DDRC |= (1 << PC0);
13
  DDRC |= (1 << PC1);
14
  
15
  Init();
16
  _delay_ms(500);
17
//Sets the Display side to use
18
  SetDisplay(0);
19
//Enables the Display
20
  EnableDisplay();
21
//Set Ram column and line
22
  SetPixelGridPos(0,0);
23
//Send Byte to address
24
  SendByte(0xFF);
25
26
  while(1)
27
  {
28
  }
29
  return 0;
30
}
31
32
-------------
33
GlobalData.h:
34
35
#ifndef GLOBALDATA
36
#define  GLOBALDATA
37
#define F_CPU 8000000UL      // 8MHz Clock
38
#endif
39
---------
40
LCDAPI.c:
41
#include "GlobalData.h"
42
#include <util/delay.h>
43
#include <avr/io.h>
44
#include "LCDConfig.h"
45
#include "LCDAPI.h"
46
47
char side=0;
48
49
void Init(void)
50
{
51
  //Enable  CMD Pins
52
  DDRB |= (1 << PB0);
53
  DDRB |= (1 << PB1);
54
  DDRB |= (1 << PB2);
55
  
56
  //Set whole port to 1 because whole 8 bit width is needed
57
  DDRD = 0xFF;
58
  //Set Ports to default state
59
  CMD_PORT     = 0;
60
  LCD_DATA_BUS = 0;
61
}
62
63
void EnableDisplay(void)
64
{
65
  if(side==0)
66
  {
67
    CMD_PORT |= (1<<LEFT_DISPLAY);
68
    CMD_PORT |= (0<< RIGHT_DISPLAY);
69
  }
70
  if(side==1)
71
  {
72
    CMD_PORT |= (0<<LEFT_DISPLAY);
73
    CMD_PORT |= (1<< RIGHT_DISPLAY);
74
  }
75
  Command(DISPLAY_ON);  
76
}
77
78
char GetDisplay(void)
79
{
80
  return side;
81
}
82
83
void SetDisplay(char s)
84
{
85
  side=s;
86
}
87
88
void Command(uint8_t cmd)
89
{
90
  if(side==0)
91
  {
92
    CMD_PORT |= (1<<LEFT_DISPLAY);
93
    CMD_PORT |= (0<< RIGHT_DISPLAY);
94
  }
95
  if(side==1)
96
  {
97
    CMD_PORT |= (0<<LEFT_DISPLAY);
98
    CMD_PORT |= (1<< RIGHT_DISPLAY);
99
  }
100
  PORTC |= (1<<PC1);
101
  CMD_PORT |= (0<<C_D_PORT);
102
  LCD_DATA_BUS = cmd;
103
  _delay_us(COMMAND_DELAY_US);
104
  CMD_PORT |= (0<<LEFT_DISPLAY|0<<RIGHT_DISPLAY);
105
  LCD_DATA_BUS = 0x00;
106
  PORTC |= (0<<PC1);
107
}
108
109
void Data(uint8_t data)
110
{
111
  if(side==0)
112
  {
113
    CMD_PORT |= (1<<LEFT_DISPLAY);
114
    CMD_PORT |= (0<< RIGHT_DISPLAY);
115
  }
116
  if(side==1)
117
  {
118
    CMD_PORT |= (0<<LEFT_DISPLAY);
119
    CMD_PORT |= (1<< RIGHT_DISPLAY);
120
  }
121
  PORTC |= (1<<PC0);
122
  CMD_PORT |= (1<<C_D_PORT);
123
  LCD_DATA_BUS = data;
124
  _delay_us(DATA_DELAY_US);
125
  CMD_PORT |= (0<<LEFT_DISPLAY|0<<RIGHT_DISPLAY);
126
  //LCD_DATA_BUS = 0x00;
127
  PORTC |= (0<<PC1);
128
}
129
130
void ClearDisplay()
131
{
132
  int x=0;
133
  int y=0;
134
  for (x=0;x<8;x++)
135
  {
136
    for(y=0;y<32;y++)
137
    {
138
      SetPixelGridPos(y,x);
139
      Data(0);
140
    }
141
  }
142
}
143
144
//Set the line at which the ram will be written to MAX 31
145
void SetDisplayLine(uint8_t line)
146
{
147
  if(line>31)
148
  {
149
    line=0;
150
  }
151
  //Combine fixed command bits with line data
152
  uint8_t maskedCommand = (line & 0xDF);
153
  Command(maskedCommand);
154
}
155
//Set Column MAX 61 will be rounded to next %8 value
156
void SetDisplayColumn(uint8_t col)
157
{
158
  if(col>61)
159
  {
160
    col=0;
161
  }
162
  uint8_t maskedCommand = (col & 0x7F);
163
  Command(maskedCommand);
164
}
165
//Sets the Grid Address of 8x8 grid
166
void SetPixelGridPos(uint8_t line ,uint8_t col)
167
{
168
  SetDisplayLine(line);
169
  SetDisplayColumStep(col);
170
}
171
172
//Sets the next %8 step,0:0 8:1 15:2 etc..
173
void SetDisplayColumStep(uint8_t colStep)
174
{
175
  if(colStep>8)
176
  colStep=0;
177
  
178
  SetDisplayColumn(colStep*8);
179
}
180
//Sends byte to current pos
181
void SendByte(uint8_t data)
182
{
183
  Data(data);
184
}

Die API Header Datei lasse ich mal weg, da nichts außer die 
Deklarationen drin sind.

Wie ihr seht, ist der Code noch recht rudimentär und es fehlen einige 
Funktionen.
Ich bin mir ziemlich sicher, dass er einige Fehler hat, allerdings muss 
man fairerweise sagen, dass dies meine ersten Gehversuche mit C auf AVR 
sind.
Zuvor habe ich jahrelang C# und PHP benutzt, zudem drei Jahre C++ im 
Fachabi, Programmierung an sich ist also das geringste Übel.
Der Code in seiner hier vorliegenden Form ist mein erster Versuch das 
Datenblatt in Code umzuwandeln, vor allem die genauen Abläufe machen mir 
noch etwas Probleme.

Weiterhin habe ich bereits einige Foren durchsucht, dort wird aber immer 
auf diverse APIs verlinkt, was ich nicht möchte.


Vielen Dank für die Hilfe im Voraus!




Datenblatt des Displays
http://cdn-reichelt.de/documents/datenblatt/A500/LCD122DIP%23EAS.pdf

Datenblatt SED1520
https://www.lcd-module.de/eng/pdf/zubehoer/s_1520.pdf

von Marcel (Gast)


Lesenswert?

Als Anmerkung:
PortC ist nur zum Debuggen, dort befindet sich eine Rote und grüne LED 
für Daten bzw. Befehl.

von Marcel (Gast)


Lesenswert?

Ich sehe gerade, dass ich die Config Datei vergessen habe!
1
#ifndef LCD_DATA
2
#define LCD_DATA
3
4
//COMMAND PORTS
5
#define CMD_PORT PORTB
6
#define C_D_PORT PB0 //LOW CMD HIGH DATA A0
7
#define LEFT_DISPLAY PB1 //RD E1
8
#define RIGHT_DISPLAY PB2 //RD E2
9
10
//DATA PORT
11
#define LCD_DATA_BUS PORTD
12
13
//COMMANDS
14
15
#define DISPLAY_ON 0xAF
16
17
18
19
//Delays
20
#define DATA_DELAY_US 150
21
#define COMMAND_DELAY_US 50
22
23
#define EXECUTION_DELAY_MS 25
24
25
#endif

von Karl M. (Gast)


Lesenswert?

Hallo,

Ups, diese Anweisung löscht keine Bits!
1
CMD_PORT |= (0<< RIGHT_DISPLAY);
steht hier auch nur beispielhaft.

von Karl M. (Gast)


Lesenswert?

Zum Stil:

ich würde es über eine select case Anweisung lösen:
1
if(side==0)
2
  {
3
    CMD_PORT |= (1<<LEFT_DISPLAY);
4
    CMD_PORT |= (0<< RIGHT_DISPLAY);
5
  }
6
  if(side==1)
7
  {
8
    CMD_PORT |= (0<<LEFT_DISPLAY);
9
    CMD_PORT |= (1<< RIGHT_DISPLAY);
10
  }
oder zumindest noch eine ELSE vor dem zweiten IF einfügen.

von Marcel (Gast)


Lesenswert?

Karl M. schrieb:
> Hallo,
>
> Ups, diese Anweisung löscht keine Bits!CMD_PORT |= (0<< RIGHT_DISPLAY);
> steht hier auch nur beispielhaft.

Was macht sie denn dann o.O

von Ralf (Gast)


Lesenswert?

Marcel schrieb:
> Was macht sie denn dann o.O

Das, was dasteht. CMD_PORT wird mit einer um RIGHT_DISPLAY nach links 
geschobener 0 verodert.

von Michael R. (mr-action)


Lesenswert?

Ralf schrieb:
> Marcel schrieb:
>> Was macht sie denn dann o.O
>
> Das, was dasteht. CMD_PORT wird mit einer um RIGHT_DISPLAY nach links
> geschobener 0 verodert.


oder kurz: Nichts...

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.