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
18
#include "lcd.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
  NOP();
30
  NOP();
31
  PORT_LCD_DATA_ENABLE &= ~(1<<LCD_DATA_ENABLE);
32
}
33
34
void Clock (void)
35
{
36
  PORT_LCD_CLOCK |= (1<<LCD_CLOCK); //Clock PIN (High)
37
  NOP();
38
  NOP();
39
  PORT_LCD_CLOCK &= ~(1<<LCD_CLOCK); //Clock PIN (Low)
40
}
41
void shift_out(char data, char cd)
42
{
43
  unsigned int h_nibble;
44
  unsigned int l_nibble;
45
46
  h_nibble |= (data & 0xF0)>>1;
47
  Clock();
48
  shift_data_out(h_nibble);
49
  enable();
50
51
  l_nibble|= (data&0x0F)<<3;
52
  Clock();
53
  shift_data_out(l_nibble);
54
  enable();
55
}
56
57
void lcd_init (void)
58
{  
59
  //Set Port Direction Register
60
  
61
  DDR_LCD_DATA_ENABLE  |= (1<<LCD_DATA_ENABLE);
62
  DDR_LCD_CLOCK |= (1<<LCD_CLOCK);
63
  DDR_LCD_DATA |= (1<<LCD_DATA);
64
  PORT_LCD_DATA_ENABLE &= ~(1<<LCD_DATA_ENABLE);
65
66
  //Wait a short Time afer Power on  
67
  WAIT(20);
68
  lcd_clear();
69
  enable();
70
  for (unsigned char a=0;a<3;a++)
71
    {
72
    shift_out() (0x22,0);  //Init in 4 Bit Mode
73
    WAIT(5);
74
    enable();
75
    }
76
  WAIT(10);
77
  lcd_write(0x80,0);
78
  Clock();
79
  enable();  
80
  WAIT(10);  
81
  lcd_write(0x80,0);
82
  Clock();
83
  enable();
84
  WAIT(10);
85
  
86
#ifdef ONE_LINES
87
  lcd_write (0x22,0);  //1 Zeilen
88
  enable();
89
#else
90
  lcd_write (0x28,0);  //mehrere Zeilen
91
  enable();
92
#endif
93
  lcd_write (0xD0,0);  //Display On
94
  enable();
95
}
96
97
//------------------------------------------------------------------------------
98
void lcd_write (char data,char cd)
99
{
100
  WAIT(BUSY_WAIT_US);
101
  
102
  unsigned char h_byte = 0;
103
  unsigned char l_byte = 0;
104
  
105
  //Soll ins Seuer oder Datenregister geschrieben werden?
106
  if(cd)
107
  {
108
    h_byte |= (1<<LCD_RS_PIN);
109
    l_byte |= (1<<LCD_RS_PIN);
110
  }
111
  
112
  if(back_light)
113
  {
114
    h_byte |= (1<<LCD_LIGHT_PIN);
115
    l_byte |= (1<<LCD_LIGHT_PIN);
116
  }
117
  
118
  h_byte |= (data&0xF0)>>1; //Write Nibbel MSB
119
  l_byte |= (data&0x0F)<<3; //Write Nibbel LSB
120
    
121
  //Schreiben der 1. 4Bit an das LCD Display
122
  shift_data_out(h_byte);
123
124
  //Schreiben der 2. 4Bit an das LCD Display  
125
  shift_data_out(l_byte);
126
}
127
128
//------------------------------------------------------------------------------
129
void shift_data_out (char byte)
130
{
131
  for (unsigned char a=8; a>0; a--)
132
  {  
133
    if ( (byte & (1<<(a-1))) != 0)
134
    {
135
      PORT_LCD_DATA |= (1<<LCD_DATA); //Data PIN (High)
136
    }
137
    else
138
    {
139
      PORT_LCD_DATA &= ~(1<<LCD_DATA); //Data PIN (LOW)
140
    }
141
    Clock();
142
  }
143
  
144
  enable();
145
}
146
147
//------------------------------------------------------------------------------
148
void lcd_print_P (unsigned char zeile,unsigned char spalte,const char *Buffer,...)
149
{
150
  va_list ap;
151
  va_start (ap, Buffer);  
152
  
153
  int format_flag;
154
  char str_buffer[10];
155
  char str_null_buffer[10];
156
  char move = 0;
157
  char Base = 0;
158
  int tmp = 0;
159
  char by;
160
  char *ptr;
161
  
162
  //Berechnet Adresse für die Zeile und schreibt sie ins DD-Ram
163
  zeile = LINE_ADDRESS[zeile];
164
  zeile += spalte;
165
  lcd_write(zeile,0);
166
  
167
  //Ausgabe der Zeichen
168
    for(;;)
169
  {
170
    by = pgm_read_byte(Buffer++);
171
    if(by==0) break; // end of format string
172
    
173
    if (by == '%')
174
    {
175
            by = pgm_read_byte(Buffer++);
176
      if (isdigit(by)>0)
177
        {
178
                                 
179
         str_null_buffer[0] = by;
180
        str_null_buffer[1] = '\0';
181
        move = atoi(str_null_buffer);
182
                by = pgm_read_byte(Buffer++);
183
        }
184
        
185
      switch (by)
186
        {
187
        case 's':
188
                    ptr = va_arg(ap,char *);
189
                    while(*ptr) {lcd_write(*ptr++,1); }
190
                    break;
191
        case 'b':
192
          Base = 2;
193
          goto ConversionLoop;
194
        case 'c':
195
          //Int to char
196
          format_flag = va_arg(ap,int);
197
          lcd_write (format_flag++,1); 
198
          break;
199
        case 'i':
200
          Base = 10;
201
          goto ConversionLoop;
202
        case 'o':
203
          Base = 8;
204
          goto ConversionLoop;
205
        case 'x':
206
          Base = 16;
207
          //****************************
208
          ConversionLoop:
209
          //****************************
210
          itoa(va_arg(ap,int),str_buffer,Base);
211
          int b=0;
212
          while (str_buffer[b++] != 0){};
213
          b--;
214
          if (b<move)
215
            {
216
            move -=b;
217
            for (tmp = 0;tmp<move;tmp++)
218
              {
219
              str_null_buffer[tmp] = '0';
220
              }
221
            //tmp ++;
222
            str_null_buffer[tmp] = '\0';
223
            strcat(str_null_buffer,str_buffer);
224
            strcpy(str_buffer,str_null_buffer);
225
            }
226
          lcd_print_str (str_buffer);
227
          move =0;
228
          break;
229
        }
230
      
231
      }  
232
    else
233
      {
234
      lcd_write (by,1);
235
      }
236
    }
237
  va_end(ap);
238
}
239
240
//------------------------------------------------------------------------------
241
void lcd_print_str (char *Buffer)
242
{
243
  while (*Buffer != 0)
244
    {
245
    lcd_write (*Buffer++,1);
246
    };
247
}
248
249
//------------------------------------------------------------------------------
250
void lcd_clear (void)
251
{
252
  lcd_write (1,0); //Clear Display
253
  lcd_write (0x80,0);  //Set DD-Ram Adresse = 0
254
255
}