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