Hallo Leute!
Ich bin neu hier im Forum und sitze seit ein paar Tagen an einem Problem
mit dem ich nicht weiter komme.
In Sachen Elektronik habe ich wenig Erfahrung, aber C/C++ ist mir nicht
völlig fremd.
Ziel ist es, ein LCD mit KS0066 kompatiblen Treiber im 4bit Modus mit
einem Atmel Atmega8 anzusteuern. Der Betrieb im 8bit Modus ist mir
bereits gelungen, aber warum die 4Pins opfern, wenns auch ohne geht.
Zur Hardware:
μC: Wie oben erwähnt, Atmel Atmega8-16PU
LCD: ANAG VISION AV1624 (Datenblatt hier:
http://www.produktinfo.conrad.com/datenblaetter/175000-199999/183342-da-01-ml-LCD_Modul_16x2_Zeichen_de_en.pdf)
Konfiguration: Die Pins E, RS und RW werden von PortC, Pins 5, 3 und 4
angesteuert. Die Datenleitungen 7, 6, 5, 4 liegen in gleicher
Reihenfolge an den Pins 7, 6, 5, 4 des PortD. Ich habe keine
Veränderungen zum 8bit Betrieb vorgenommen. Außer die überflüssigen
Datenleitungen zu entfernen.
Ich gehe davon aus, dass von der Hardware-Seite her alles in Ordnung
ist, da es ja im 8bit Modus schon funktionierte.
Zur Software:
IDE: Atmel Studio 6.1
C-Code: Siehe unten.
In der "lcd_init()"-Methode habe ich versucht das
Initialisierungsprotokoll aus dem Datenblatt (Seite 4, Figure 2)
umzusetzen. Leider finde ich meinen Fehler / meine Fehler nicht.
Vielleicht hat jemand einen Lösungsvorschlag?
Mir ist klar, dass ich einfach schon vorhandenen Code verwenden könnte.
(Sicher der leichte Weg.)Ich möchte es aber selbst umsetzten.
Vielen Dank für Eure Hilfe!
Grüße.
1 | #include <avr/io.h>
|
2 | #include <util/delay.h>
|
3 |
|
4 | #define LCD_Control PORTC
|
5 | #define LCD_DDR_Control DDRC
|
6 | #define LCD_Enable 5
|
7 | #define LCD_ReadWrite 4
|
8 | #define LCD_RegisterSelect 3
|
9 |
|
10 | #define LCD_Data PORTD
|
11 | #define LCD_DDR_Data DDRD
|
12 |
|
13 | /*
|
14 | * send enable signal
|
15 | */
|
16 | void LCD_EnableSignal(){
|
17 | LCD_Control |= 1<<LCD_Enable;
|
18 | asm volatile ("nop");
|
19 | asm volatile ("nop");
|
20 | LCD_Control &= ~1<<LCD_Enable;
|
21 | }
|
22 |
|
23 | /*
|
24 | * enable / disable command mode
|
25 | */
|
26 | void LCD_EnableCommandMode(){
|
27 | LCD_Control &= ~(1<<LCD_RegisterSelect);
|
28 | }
|
29 | void LCD_DisableCommandMode(){
|
30 | LCD_Control |= 1<<LCD_RegisterSelect;
|
31 | }
|
32 |
|
33 | /*
|
34 | * enable / disable writemode
|
35 | */
|
36 | void LCD_EnableWriteMode(){
|
37 | LCD_Control &= ~ (1<<LCD_ReadWrite);
|
38 | }
|
39 | void LCD_DisableWriteMode(){
|
40 | LCD_Control |= (1<<LCD_ReadWrite);
|
41 | }
|
42 |
|
43 | /*
|
44 | * check busy flag
|
45 | */
|
46 | void LCD_CheckBusy(){
|
47 | LCD_DDR_Data = 0x00; // make dataport input
|
48 | LCD_DisableWriteMode();
|
49 | LCD_EnableCommandMode();
|
50 |
|
51 | while (LCD_Data >= 0x80)
|
52 | {
|
53 | LCD_EnableSignal();
|
54 | }
|
55 | LCD_DDR_Data = 0xFF; // make dataport output
|
56 | }
|
57 |
|
58 | void lcd_init(void){
|
59 |
|
60 | /* set output pins */
|
61 | LCD_DDR_Control |= 1<<LCD_Enable | 1<<LCD_ReadWrite | 1<<LCD_RegisterSelect;
|
62 | LCD_DDR_Data = 0xFF;
|
63 |
|
64 | /* send 3 times reset command */
|
65 | LCD_Data = 0x30;
|
66 | LCD_EnableSignal();
|
67 | _delay_ms(10);
|
68 | LCD_EnableSignal();
|
69 | _delay_ms(10);
|
70 | LCD_EnableSignal();
|
71 | _delay_ms(10);
|
72 |
|
73 | /* enable 4bit mode */
|
74 | LCD_Data = 0x20;
|
75 | LCD_EnableSignal();
|
76 | _delay_ms(10);
|
77 |
|
78 | /* function set */
|
79 | LCD_EnableSignal();
|
80 | //_delay_ms(1);
|
81 | LCD_Data = 0x00;
|
82 | LCD_EnableSignal();
|
83 | //_delay_ms(1);
|
84 |
|
85 | /* display off */
|
86 | LCD_EnableSignal();
|
87 | //_delay_ms(1);
|
88 | LCD_Data = 0x80;
|
89 | LCD_EnableSignal();
|
90 | //_delay_ms(1);
|
91 |
|
92 | /* display clear */
|
93 | LCD_Data = 0x00;
|
94 | LCD_EnableSignal();
|
95 | //_delay_ms(1);
|
96 | LCD_Data = 0x10;
|
97 | LCD_EnableSignal();
|
98 | //_delay_ms(1);
|
99 |
|
100 | /* entry mode */
|
101 | LCD_Data = 0x00;
|
102 | LCD_EnableSignal();
|
103 | //_delay_ms(1);
|
104 | LCD_Data = 0x60;
|
105 | LCD_EnableSignal();
|
106 | //_delay_ms(1);
|
107 |
|
108 | /* initialization finished */
|
109 |
|
110 | }
|
111 |
|
112 | int main(void)
|
113 | {
|
114 | _delay_ms(100);
|
115 | lcd_init(); // init LCD in 4bit mode
|
116 |
|
117 | /* print character 0x88 on LCD to verify correct init */
|
118 | LCD_Data = 0x88;
|
119 | LCD_DisableCommandMode();
|
120 | LCD_CheckBusy();
|
121 | LCD_EnableSignal();
|
122 | LCD_CheckBusy();
|
123 | LCD_EnableSignal();
|
124 | while(1);
|
125 | }
|