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