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