1 | #include <avr/io.h>
|
2 | #include <util/delay.h>
|
3 |
|
4 | #define LCDPORT PORTD
|
5 | #define LCDPORT_DDR DDRD
|
6 | #define RS 0 //P0: RS. Wenn RS=0 ist dann Kommandos
|
7 | #define RW 1 //PD1: R/W=1 lesen. R/W=0 schreiben
|
8 | #define ENABLE 2 //PD2: Enable. Wenn Enable on ist, nimmt das Display Kommandos/Daten entgegen. Wenn off, dann verarbeitet es die Daten
|
9 |
|
10 | //DB4 bis DB7 des Displays sind an PD4 bis PD7 des ATmega328P angeschlossen
|
11 |
|
12 | void initDisplay(void);
|
13 | void checkBusy(void);
|
14 | void nopAbit(void);
|
15 | void sendCommand(unsigned char command);
|
16 | void sendCharacter(unsigned char character);
|
17 |
|
18 | int main(void)
|
19 | {
|
20 | LCDPORT_DDR |= 1<<ENABLE | 1<<RW | 1<<RS;
|
21 | initDisplay();
|
22 |
|
23 | //_delay_ms(2000);
|
24 |
|
25 | sendCharacter(0x4B); //K
|
26 |
|
27 | //_delay_ms(5000);
|
28 |
|
29 | //sendCommand(0b00000000);
|
30 | //sendCommand(0b00010000);
|
31 |
|
32 | while(1){}
|
33 | }
|
34 |
|
35 | void initDisplay()
|
36 | {
|
37 | //-------INIT ANFANG------
|
38 | _delay_ms(50); //Laut Datenblatt muss nach Anlegen der Spannung 40ms gewartet werden.
|
39 |
|
40 | sendCommand(0b00110000); //8-Bit Mode
|
41 | _delay_us(50);
|
42 |
|
43 | sendCommand(0b00100000); //4-Bit Mode
|
44 | sendCommand(0b10000000); //Zeilen: 2; Schrift: 5x8
|
45 | _delay_us(50);
|
46 |
|
47 | sendCommand(0b00100000); //4-Bit Mode
|
48 | sendCommand(0b10000000); //Zeilen: 2; Schrift: 5x8
|
49 | _delay_us(50);
|
50 |
|
51 | sendCommand(0b00000000);//Start: Display on/off
|
52 | sendCommand(0b11110000);//Display: on, Cursor: on, Cursor: blinkender Block
|
53 | _delay_us(50);
|
54 |
|
55 | sendCommand(0b00000000);//Start: Display clear
|
56 | sendCommand(0b00010000);//löscht Display und setzt Cursor auf Adresse 0
|
57 | _delay_ms(2);
|
58 |
|
59 | sendCommand(0b00000000);//Start: Entry mode set
|
60 | sendCommand(0b01100000);//Cursor: 1 nach rechts, Shift: aus
|
61 | _delay_ms(2);
|
62 | //------INIT ENDE------
|
63 |
|
64 | sendCommand(0b00100000);//Cursor: 1 nach rechts, Shift: aus
|
65 | _delay_ms(2);
|
66 | }
|
67 |
|
68 | void checkBusy()
|
69 | {
|
70 | LCDPORT_DDR = 0; //Die Display Pins, an denen der Controler angeschlossen ist werden auf 0V gesetzt
|
71 | LCDPORT |= (1<<RW);
|
72 | LCDPORT &= ~(1<<RS);
|
73 |
|
74 | while (LCDPORT >= 0x80) //0x80 bedeutet, dass das Display busy ist. Solange das der Fall ist, wird gewartet
|
75 | {
|
76 | nopAbit();
|
77 | }
|
78 | LCDPORT_DDR = 0xFF; //Die oberen Display Pins werden wieder eingeschaltet
|
79 | }
|
80 |
|
81 | void nopAbit()
|
82 | {
|
83 | LCDPORT |= (1<<ENABLE);//Wenn ENABLE on ist können Kommandos abgesetzt werden. Nur dann ist der Check busy moeglich.
|
84 | asm volatile ("nop");
|
85 | asm volatile ("nop");
|
86 | LCDPORT &= ~(1<<ENABLE);
|
87 | }
|
88 |
|
89 | void sendCommand(unsigned char command)
|
90 | {
|
91 | checkBusy();
|
92 | LCDPORT = command;
|
93 | LCDPORT &= ~ ((1<<RW)|(1<<RS));
|
94 | nopAbit();
|
95 | LCDPORT = 0;
|
96 | }
|
97 |
|
98 | void sendCharacter(unsigned char character)
|
99 | {
|
100 | checkBusy();
|
101 | LCDPORT = character;
|
102 | LCDPORT &= ~ (1<<RW);
|
103 | LCDPORT |= (1<<RS);
|
104 | nopAbit();
|
105 | LCDPORT = 0;
|
106 | }
|