lcd.c


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