1 | #define DATAPORT PORTC
|
2 | #define DATADDR DDRC
|
3 | #define DATAPIN PINC
|
4 | #define CTRLPORT PORTB
|
5 | #define CTRLDDR DDRB
|
6 | #define RS 0
|
7 | #define RW 1
|
8 | #define E 2
|
9 | #define CS 3
|
10 | #define F_CPU 12000000
|
11 |
|
12 | #include <incl/delay.h>
|
13 | #include <util/delay.h>
|
14 | #include <stdint.h>
|
15 | #include <avr/io.h>
|
16 |
|
17 | void lcd_enable(void){
|
18 | // Erzeugt eine fallende Flanke am Enable-Pin
|
19 |
|
20 | CTRLPORT |= (1<<E);
|
21 | _delay_us(2);
|
22 | CTRLPORT &= ~(1<<E);
|
23 | _delay_us(2);
|
24 | }
|
25 |
|
26 | void lcd_busy(void) {
|
27 | // Wartet bis der Controller wieder Daten verarbeiten kann
|
28 |
|
29 | unsigned char tmp;
|
30 |
|
31 | DATAPORT = 0x00; // Datenport wird gelöscht
|
32 | DATADDR = 0x00; // Datenport wird als Eingang deklariert
|
33 |
|
34 | CTRLPORT |= (1<<RW); // R/W auf logisch 1 -> R
|
35 | CTRLPORT |= (1<<RS); // RS auf logisch 1 -> aktiv
|
36 |
|
37 | do{
|
38 | CTRLPORT |= (1<<E); // Steigende Flanke am Enable-Pin
|
39 | _delay_us(2);
|
40 | tmp = DATAPIN; // Datenport wird eingelesen
|
41 | CTRLPORT &= ~(1<<E); // Fallende Flanke am Enable-Pin
|
42 | _delay_us(2);
|
43 | }while(tmp & (1<<7)); // Schleife bis Busy Flag logisch 0 wird
|
44 |
|
45 | DATADDR = 0xff; // Datenport wird wieder als Ausgang deklariert
|
46 | }
|
47 |
|
48 | void lcd_writecommand(uint8_t command) {
|
49 | // Kommandobyte -> HD61830
|
50 |
|
51 | lcd_busy();
|
52 | CTRLPORT &= ~(1<<RW); // R/W auf logisch 0 -> W
|
53 | CTRLPORT |= (1<<RS); // RS auf logisch 1 -> aktiv
|
54 | DATAPORT = command; // übergebenes Kommandobyte wird ausgegeben
|
55 | lcd_enable();
|
56 | }
|
57 |
|
58 | void lcd_writedata(uint8_t data) {
|
59 | // Datenbyte -> HD61830
|
60 |
|
61 | lcd_busy();
|
62 | CTRLPORT &= ~(1<<RW); // R/W auf logisch 0 -> W
|
63 | CTRLPORT &= ~(1<<RS); // RS auf logisch 0 -> inaktiv
|
64 | DATAPORT = data; // übergebenes Datenbyte wird ausgegeben
|
65 | lcd_enable();
|
66 | }
|
67 |
|
68 | void lcd_send(uint8_t command, uint8_t data) {
|
69 | // Kombination aus Kommando- und Datenbyte
|
70 |
|
71 | lcd_writecommand(command);
|
72 | lcd_writedata(data);
|
73 | }
|
74 |
|
75 | void lcd_init(unsigned char modus){
|
76 | // Initialisiert das Display
|
77 |
|
78 | DATADDR = 0xff; // Datenport wird als Ausgang deklariert
|
79 | CTRLDDR|= (1<<RW)|(1<<RS)|(1<<E)|(1<<CS); // Kommandoport wird als Ausgang deklariert
|
80 |
|
81 | CTRLPORT &= ~(1<<CS); // CS auf logisch 0 -> aktiv
|
82 |
|
83 | if(modus == 'c'){
|
84 | // Charaktermodus
|
85 |
|
86 | lcd_send(0x00, 0x30); // Mode Control
|
87 | lcd_send(0x01, 0x75); // Set Character Pitch
|
88 | lcd_send(0x02, 0x27); // Set Number of Characters
|
89 | lcd_send(0x03, 0x0A); // Set Number of Time Divisions
|
90 | lcd_send(0x04, 0x07); // Set Cursor Position
|
91 | }
|
92 | else{
|
93 | // Grafikmodus
|
94 |
|
95 | lcd_send(0x00, 0x32); // Mode Control
|
96 | lcd_send(0x01, 0x07); // number of bits of 1-byte display data to be displayed
|
97 | lcd_send(0x02, 0x1d); // number of horizontal bytes
|
98 | lcd_send(0x03, 0x0A); // Set Number of Time Divisions
|
99 | }
|
100 |
|
101 | lcd_send(0x08, 0x00); // Set Display Start Low Order Address
|
102 | lcd_send(0x09, 0x00); // Set Display Start High Order Address
|
103 |
|
104 |
|
105 | }
|
106 |
|
107 | void lcd_clear(unsigned char modus){
|
108 | // Löscht das Display
|
109 |
|
110 | lcd_gotoxy(modus, 0, 0); // Cursor an den Anfang setzen
|
111 |
|
112 | if(modus == 'c'){
|
113 | // Charaktermodus
|
114 |
|
115 | for(uint16_t i=0; i<320; i++) // Alle Chars durchlaufen und löschen
|
116 | lcd_send(0x0c, 0x20);
|
117 | }
|
118 | else{
|
119 | // Grafikmodus
|
120 |
|
121 | for(uint16_t i=0; i<1920; i++) // Alle Bytes durchlaufen und löschen
|
122 | lcd_send(0x0c, 0x00);
|
123 | }
|
124 |
|
125 | lcd_gotoxy(modus, 0, 0); // Cursor an den Anfang setzen
|
126 | }
|
127 |
|
128 | void lcd_gotoxy(unsigned char modus, uint8_t x, uint8_t y){
|
129 | // Setzt den Cursor an eine bestimmte Position
|
130 |
|
131 | uint16_t adress;
|
132 |
|
133 | if(modus == 'c'){
|
134 | // Charaktermodus
|
135 |
|
136 | adress = (y * 40) + x;
|
137 | }
|
138 | else{
|
139 | // Grafikmodus
|
140 |
|
141 | adress = (y * 30) + x;
|
142 | }
|
143 |
|
144 | lcd_send(0x0a, (uint8_t)(adress)); // Set Cursor Address (Low Order)
|
145 | lcd_send(0x0b, (uint8_t)(adress >> 8)); // Set Cursor Address (High Order)
|
146 | }
|
147 |
|
148 | void lcd_setdot(uint8_t x, uint8_t y){
|
149 | // Setzt ein Pixel an einer bestimmte Position
|
150 |
|
151 | lcd_gotoxy('g', (x >> 3), y);
|
152 | lcd_send(0x0f, (x & 0x07));
|
153 | }
|
154 |
|
155 | void lcd_cleardot(uint8_t x, uint8_t y){
|
156 | // Löscht ein Pixel an einer bestimmte Position
|
157 |
|
158 | lcd_gotoxy('g', (x >> 3), y);
|
159 | lcd_send(0x0e, (x & 0x07));
|
160 | }
|
161 |
|
162 | void lcd_puts(char *string){
|
163 | #define lcd_putc(c) lcd_send(0x0c,c)
|
164 | uint8_t i=0;
|
165 | char c = string[0];
|
166 |
|
167 | while(c != 0) {
|
168 | /* if(c == '\n')
|
169 | lcd_newline(font.height, startx);
|
170 | else*/
|
171 | lcd_putc(c);
|
172 | c = string[++i];
|
173 | }
|
174 | }
|
175 |
|
176 | int main(void){
|
177 | _delay_ms(10);
|
178 | lcd_init('c');
|
179 | lcd_clear('c');
|
180 | lcd_puts("Hallo ! Test XY Test XY Test XY Test XY ");
|
181 | while(1);
|
182 | }
|