lcd.c


1
/*------------------------------------------------------------------------------
2
 Copyright:      Radig Ulrich  mailto: mail@ulrichradig.de
3
 Author:         Radig Ulrich
4
 Remarks:        
5
 known Problems: none
6
 Version:        22.11.2007
7
 Description:    Programm zur Ansteuerung eines Standart LCD
8
         (HD44870),(SED1278F) und kompatible
9
------------------------------------------------------------------------------*/
10
11
#include <stdlib.h>
12
#include <stdarg.h>
13
#include <ctype.h>
14
#include <string.h>
15
#include <avr/io.h>
16
#include <avr/pgmspace.h>
17
#include "lcd.h"
18
#include <avr/delay.h>
19
20
//const char LINE_ADDRESS[] ={0x80,0xC0,0x90,0xD0}; //2 x 16;4 x 16 uvm.
21
const char LINE_ADDRESS[] ={0x80,0xC0,0x94,0xD4}; //4 mal 20
22
volatile unsigned char back_light = 0;
23
24
//------------------------------------------------------------------------------
25
26
void enable(void)
27
{
28
  PORT_LCD_DATA_ENABLE |= (1<<LCD_DATA_ENABLE);
29
  _delay_ms(50);
30
  
31
  PORT_LCD_DATA_ENABLE &= ~(1<<LCD_DATA_ENABLE);
32
  _delay_ms(50);
33
}
34
35
void Clock (void)
36
{
37
  PORT_LCD_CLOCK |= (1<<LCD_CLOCK); //Clock PIN (High)
38
  _delay_ms(20);
39
  
40
  PORT_LCD_CLOCK &= ~(1<<LCD_CLOCK); //Clock PIN (Low)
41
  _delay_ms(20);
42
}
43
44
void lcd_char(char ps, char cd)
45
{
46
  switch(ps)
47
  {
48
    case 'ä' : ps = 0xE1; break;
49
    case 'ö' : ps = 0xEF; break;
50
    case 'ü' : ps = 0xF5; break;
51
    case 'ß' : ps = 0xE2; break;
52
    case '°' : ps = 0xDF; break;
53
    case 'µ' : ps = 0xE4; break;
54
    case 'Ä' : ps = 0x00; break;  // Point to CG-RAM
55
    case 'Ö' : ps = 0x01; break; // self defined characters
56
    case 'Ü' : ps = 0x02; break;
57
  }
58
  lcd_write(ps,1);
59
}
60
61
void lcd_init (void)
62
{  
63
  //Set Port Direction Register  
64
  
65
  DDRB =0xff;
66
  DDR_LCD_DATA_ENABLE  |= (1<<LCD_DATA_ENABLE);
67
  DDR_LCD_CLOCK |= (1<<LCD_CLOCK);
68
  DDR_LCD_DATA |= (1<<LCD_DATA);
69
  PORT_LCD_DATA_ENABLE &= ~(1<<LCD_DATA_ENABLE);
70
  
71
  shift_data_out(0x02<<3);
72
  _delay_us(10);
73
  shift_data_out(0x02<<3);
74
  _delay_us(10);
75
  
76
  shift_data_out(0x08<<3);
77
  _delay_us(10);
78
79
  shift_data_out(0x00<<3);
80
  _delay_us(10);
81
  
82
  
83
  shift_data_out(0x0F<<3);
84
  _delay_us(10);
85
  
86
  shift_data_out(0x00<<3);
87
  _delay_us(10);
88
  
89
  shift_data_out(0x01<<3);
90
  _delay_us(10);
91
  
92
  shift_data_out(0x00<<3);
93
  _delay_us(10);
94
  
95
  shift_data_out(0x0C<<3);
96
  _delay_us(10);
97
};
98
99
//------------------------------------------------------------------------------
100
void lcd_write (char data,char cd)
101
102
  {  
103
  unsigned char h_nibble = 0;
104
  unsigned char l_nibble = 0;
105
  
106
  _delay_us(10);
107
  
108
  //Soll ins Steuer oder Datenregister geschrieben werden?
109
  
110
  if(cd)
111
  {
112
    h_nibble &=~ (1<<LCD_RS_PIN);
113
  }
114
  else
115
  {
116
    l_nibble |= (1<<LCD_RS_PIN);
117
  }
118
  
119
  if(back_light)
120
  {
121
    h_nibble |= (1<<LCD_LIGHT_PIN);
122
    l_nibble |= (1<<LCD_LIGHT_PIN);
123
  }
124
  
125
   
126
  h_nibble |= (data&0xF0)>>1; //Write Nibbel MSB
127
  _delay_ms(10);
128
  l_nibble |= (data&0x0F)<<3; //Write Nibbel LSB
129
  _delay_ms(10);
130
  //Schreiben der 1. 4Bit an das LCD Display
131
  shift_data_out(h_nibble);
132
133
  //Schreiben der 2. 4Bit an das LCD Display  
134
  shift_data_out(l_nibble);
135
};
136
137
//------------------------------------------------------------------------------
138
void shift_data_out (char byte)
139
{
140
  for (unsigned char a=8; a>0; a--)
141
  {  
142
    if ( (byte & (1<<(a-1))) != 0)
143
    {
144
      PORT_LCD_DATA |= (1<<LCD_DATA); //Data PIN (High)
145
    
146
    }
147
    else
148
    {
149
      PORT_LCD_DATA &= ~(1<<LCD_DATA); //Data PIN (LOW)
150
    
151
    }
152
    Clock();
153
  }
154
  
155
  enable();
156
};
157
//------------------------------------------------------------------------------
158
void lcd_print_P (unsigned char zeile,unsigned char spalte,const char *Buffer,...)
159
{
160
  va_list ap;
161
  va_start (ap, Buffer);  
162
  
163
  int format_flag;
164
  char str_buffer[10];
165
  char str_null_buffer[10];
166
  char move = 0;
167
  char Base = 0;
168
  int tmp = 0;
169
  char by;
170
  char *ptr;
171
  
172
  //Berechnet Adresse für die Zeile und schreibt sie ins DD-Ram
173
  zeile = LINE_ADDRESS[zeile];
174
  zeile += spalte;
175
  lcd_write(zeile,0);
176
  
177
  //Ausgabe der Zeichen
178
    for(;;)
179
  {
180
    by = *(Buffer++);
181
    if(by==0) break; // end of format string
182
    
183
    if (by == '%')
184
    {
185
            by = *(Buffer++);
186
      if (isdigit(by)>0)
187
        {
188
                                 
189
         str_null_buffer[0] = by;
190
        str_null_buffer[1] = '\0';
191
        move = atoi(str_null_buffer);
192
                by = *(Buffer++);
193
        }
194
        
195
      switch (by)
196
        {
197
        case 's':
198
                    ptr = va_arg(ap,char *);
199
                    while(*ptr) {lcd_write(*ptr++,1); }
200
                    break;
201
        case 'b':
202
          Base = 2;
203
          goto ConversionLoop;
204
        case 'c':
205
          //Int to char
206
          format_flag = va_arg(ap,int);
207
          lcd_write (format_flag++,1); 
208
          break;
209
        case 'i':
210
          Base = 10;
211
          goto ConversionLoop;
212
        case 'o':
213
          Base = 8;
214
          goto ConversionLoop;
215
        case 'x':
216
          Base = 16;
217
          //****************************
218
          ConversionLoop:
219
          //****************************
220
          itoa(va_arg(ap,int),str_buffer,Base);
221
          int b=0;
222
          while (str_buffer[b++] != 0){};
223
          b--;
224
          if (b<move)
225
            {
226
            move -=b;
227
            for (tmp = 0;tmp<move;tmp++)
228
              {
229
              str_null_buffer[tmp] = '0';
230
              }
231
            //tmp ++;
232
            str_null_buffer[tmp] = '\0';
233
            strcat(str_null_buffer,str_buffer);
234
            strcpy(str_buffer,str_null_buffer);
235
            }
236
          lcd_char(str_buffer,1);
237
          move =0;
238
          break;
239
        }
240
      
241
      }  
242
    else
243
      {
244
      lcd_write (by,1);
245
      }
246
    }
247
  va_end(ap);
248
};
249
250
//------------------------------------------------------------------------------
251
void lcd_print_str (char *Buffer)
252
{
253
  while (*Buffer != 0)
254
    {
255
    lcd_char(*Buffer++,1);
256
    };
257
};
258
259
//------------------------------------------------------------------------------
260
void lcd_clear (void)
261
{
262
  lcd_write (1,0); //Clear Display
263
  lcd_write (0x80,0);  //Set DD-Ram Adresse = 0
264
}