Forum: Compiler & IDEs Peter Fleury LCD Lib für AT90USB162?


von Tobias P. (wuka-rudi)


Lesenswert?

Hallo,
hat einer von euch schon mal die "Peter Fleury LCD Lib" auf einem 
AT90USB162 zum laufen gebracht? Hab auf einem ATmega644 sehr gute 
Erfahrungen damit gemacht aber jetzt bekomme ich die Sache einfach nicht 
zulaufen. Der µC hängt sich immer schon bei der Initialisierung auf. Ich 
benutze auch das gleiche LCD wie bei dem anderen Projekt.

von Tobias P. (wuka-rudi)


Lesenswert?

Hey,
hab mal versucht mittels "LED-Debugging" die Fehlerquelle einzugrenzen
und ich vermute das es aus der delay Funktion kommt:
1
/*************************************************************************
2
 delay loop for small accurate delays: 16-bit counter, 4 cycles/loop
3
*************************************************************************/
4
static inline void _delayFourCycles(unsigned int __count)
5
{
6
    if ( __count == 0 )    
7
        __asm__ __volatile__( "rjmp 1f\n 1:" );    // 2 cycles
8
    else
9
        __asm__ __volatile__ (
10
          "1: sbiw %0,1" "\n\t"                  
11
          "brne 1b"                              // 4 cycles/loop
12
          : "=w" (__count)
13
          : "0" (__count)
14
         );
15
}
16
17
18
/************************************************************************* 
19
delay for a minimum of <us> microseconds
20
the number of loops is calculated at compile-time from MCU clock frequency
21
*************************************************************************/
22
#define delay(us)  _delayFourCycles( ( ( 1*(XTAL/4000) )*us)/1000 )

leider sind meine Assemblerkenntnisse allzu groß, ich hoffe ihr könnt 
mir weiter helfen.

von Tobias P. (wuka-rudi)


Lesenswert?

Hat keiner einen Tip für mich?
ich habe mal die delay-Funktion durch die aus der delay.h ersetzt doch 
auch das hat mich leider nicht weitergebracht.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Tobias Pfundt schrieb:
> und ich vermute das es aus der delay Funktion kommt:

Was treibt dich zu einer derartigen Vermutung?

Wenn die Delays zu lang sind, verschwendest du Zeit, aber es sollte
sonst nichts weiter passieren, insbesondere sollte es nicht zu einem
"Aufhängen" führen.

Wenn die Delays zu kurz sind, zeigt das Display Müll an oder im
schlimmsten Fall gar nichts bzw. den schwarzen Balken, den es nach
dem Einschalten hat.

von Simon B. (nomis)


Lesenswert?

Tobias Pfundt schrieb:
> Hat keiner einen Tip für mich?

Ich habe im Moment nur den ganz generischen Tip:

* poste den Sourcecode
* poste den Schaltplan

Dann bietest Du einfach mehr Gelegenheiten für Tips. Selbst wenn ich 
z.B. wollte wäre es mir im Moment nicht möglich, dein Problem 
nachzuvollziehen.

Viele Grüße,
        Simon

von Tobias P. (wuka-rudi)


Angehängte Dateien:

Lesenswert?

Hey Danke erst mal für die Antworten.
Wollte am Anfang nur raus finden ob jemand schon mal die Lib's bei einem 
AT90USB162 Benutzt hat. Einen richtigen Schaltplan gibt es momentan 
nicht da ich die AVR Entwicklungsplatine AT90USB162 (AVR-USB-162)aus dem 
Shop nutze.
Hab einfach nur die 4 Daten und 3 Steuerleitungen ran gehängt. Die 
Hintergrundbeleuchtung ist momentan nicht angeschlossen aber das sollte 
ja auch keine Rolle spielen. Als Entwicklungsumgebung benutze ich das 
AVR Studio 5 und meine Code übertrage ich mit Filp.
Meine Code besteht aus dem Startbeispiel mit der Blinkenden LED und der 
LCD Lib von Peter Fleury

hier LCD_Test.c
1
#include <avr/io.h>
2
#include "lcd.h"
3
void PORT_Init()
4
{
5
  PORTB = 0b00000000;
6
  DDRB  = 0b11111111;
7
8
  PORTC = 0b00000000;
9
  DDRC = 0b11111111;
10
11
  PORTD = 0b00000000;
12
  DDRD = 0b00010000;    //set led as output
13
}
14
15
16
int main(void)
17
{  
18
  PORT_Init();
19
  int i;
20
  
21
  lcd_init(LCD_DISP_ON);          //put LCD on and initialize them
22
   lcd_clrscr();              //clear LCD 
23
  lcd_puts("Geht :-)");
24
25
  while (1)
26
  {  
27
28
    PORTD = PORTD | 0b00010000;
29
    for (i = 5000; i; i--);
30
    PORTD = PORTD & 0b11101111;
31
    for (i = 5000; i; i--);
32
33
  }
34
  return 0;
35
}

hier die lcd.h
1
#ifndef LCD_H
2
#define LCD_H
3
/*************************************************************************
4
 Title  :   C include file for the HD44780U LCD library (lcd.c)
5
 Author:    Peter Fleury <pfleury@gmx.ch>  http://jump.to/fleury
6
 File:      $Id: lcd.h,v 1.13.2.2 2006/01/30 19:51:33 peter Exp $
7
 Software:  AVR-GCC 3.3
8
 Hardware:  any AVR device, memory mapped mode only for AT90S4414/8515/Mega
9
***************************************************************************/
10
11
12
/*@{*/
13
14
#if (__GNUC__ * 100 + __GNUC_MINOR__) < 303
15
#error "This library requires AVR-GCC 3.3 or later, update to newer AVR-GCC compiler !"
16
#endif
17
18
#include <inttypes.h>
19
#include <avr/pgmspace.h>
20
21
/** 
22
 *  @name  Definitions for MCU Clock Frequency
23
 *  Adapt the MCU clock frequency in Hz to your target. 
24
 */
25
#define XTAL  8000000              /**< clock frequency in Hz, used to calculate delay timer */
26
         
27
28
/**
29
 * @name  Definition for LCD controller type
30
 * Use 0 for HD44780 controller, change to 1 for displays with KS0073 controller.
31
 */
32
#define LCD_CONTROLLER_KS0073 1  /**< Use 0 for HD44780 controller, 1 for KS0073 controller */
33
34
/** 
35
 *  @name  Definitions for Display Size 
36
 *  Change these definitions to adapt setting to your display
37
 */
38
#define LCD_LINES           2     /**< number of visible lines of the display */
39
#define LCD_DISP_LENGTH    16     /**< visibles characters per line of the display */
40
#define LCD_LINE_LENGTH  0x40     /**< internal line length of the display    */
41
#define LCD_START_LINE1  0x00     /**< DDRAM address of first char of line 1 */
42
#define LCD_START_LINE2  0x40     /**< DDRAM address of first char of line 2 */
43
#define LCD_START_LINE3  0x14     /**< DDRAM address of first char of line 3 */
44
#define LCD_START_LINE4  0x54     /**< DDRAM address of first char of line 4 */
45
#define LCD_WRAP_LINES      0     /**< 0: no wrap, 1: wrap at end of visibile line */
46
47
48
#define LCD_IO_MODE      1         /**< 0: memory mapped mode, 1: IO port mode */
49
#if LCD_IO_MODE
50
/**
51
 *  @name Definitions for 4-bit IO mode
52
 *  Change LCD_PORT if you want to use a different port for the LCD pins.
53
 *
54
 *  The four LCD data lines and the three control lines RS, RW, E can be on the 
55
 *  same port or on different ports. 
56
 *  Change LCD_RS_PORT, LCD_RW_PORT, LCD_E_PORT if you want the control lines on
57
 *  different ports. 
58
 *
59
 *  Normally the four data lines should be mapped to bit 0..3 on one port, but it
60
 *  is possible to connect these data lines in different order or even on different
61
 *  ports by adapting the LCD_DATAx_PORT and LCD_DATAx_PIN definitions.
62
 *  
63
 */
64
#define LCD_PORT         PORTD        /**< port for the LCD lines   */
65
#define LCD_DATA0_PORT   LCD_PORT     /**< port for 4bit data bit 0 */
66
#define LCD_DATA1_PORT   LCD_PORT     /**< port for 4bit data bit 1 */
67
#define LCD_DATA2_PORT   LCD_PORT     /**< port for 4bit data bit 2 */
68
#define LCD_DATA3_PORT   LCD_PORT     /**< port for 4bit data bit 3 */
69
#define LCD_DATA0_PIN    0            /**< pin for 4bit data bit 0  */
70
#define LCD_DATA1_PIN    1            /**< pin for 4bit data bit 1  */
71
#define LCD_DATA2_PIN    2            /**< pin for 4bit data bit 2  */
72
#define LCD_DATA3_PIN    3            /**< pin for 4bit data bit 3  */
73
#define LCD_RS_PORT      PORTC      /**< port for RS line      */
74
#define LCD_RS_PIN       5            /**< pin  for RS line         */
75
#define LCD_RW_PORT      PORTC      /**< port for RW line      */
76
#define LCD_RW_PIN       6            /**< pin  for RW line      */
77
#define LCD_E_PORT       PORTC      /**< port for Enable line    */
78
#define LCD_E_PIN        7            /**< pin  for Enable line     */
79
80
#elif defined(__AVR_AT90S4414__) || defined(__AVR_AT90S8515__) || defined(__AVR_ATmega64__) || \
81
      defined(__AVR_ATmega8515__)|| defined(__AVR_ATmega103__) || defined(__AVR_ATmega128__) || \
82
      defined(__AVR_ATmega161__) || defined(__AVR_ATmega162__)
83
/*
84
 *  memory mapped mode is only supported when the device has an external data memory interface
85
 */
86
#define LCD_IO_DATA      0xC000    /* A15=E=1, A14=RS=1                 */
87
#define LCD_IO_FUNCTION  0x8000    /* A15=E=1, A14=RS=0                 */
88
#define LCD_IO_READ      0x0100    /* A8 =R/W=1 (R/W: 1=Read, 0=Write   */
89
#else
90
#error "external data memory interface not available for this device, use 4-bit IO port mode"
91
92
#endif
93
94
95
/**
96
 *  @name Definitions for LCD command instructions
97
 *  The constants define the various LCD controller instructions which can be passed to the 
98
 *  function lcd_command(), see HD44780 data sheet for a complete description.
99
 */
100
101
/* instruction register bit positions, see HD44780U data sheet */
102
#define LCD_CLR               0      /* DB0: clear display                  */
103
#define LCD_HOME              1      /* DB1: return to home position        */
104
#define LCD_ENTRY_MODE        2      /* DB2: set entry mode                 */
105
#define LCD_ENTRY_INC         1      /*   DB1: 1=increment, 0=decrement     */
106
#define LCD_ENTRY_SHIFT       0      /*   DB2: 1=display shift on           */
107
#define LCD_ON                3      /* DB3: turn lcd/cursor on             */
108
#define LCD_ON_DISPLAY        2      /*   DB2: turn display on              */
109
#define LCD_ON_CURSOR         1      /*   DB1: turn cursor on               */
110
#define LCD_ON_BLINK          0      /*     DB0: blinking cursor ?          */
111
#define LCD_MOVE              4      /* DB4: move cursor/display            */
112
#define LCD_MOVE_DISP         3      /*   DB3: move display (0-> cursor) ?  */
113
#define LCD_MOVE_RIGHT        2      /*   DB2: move right (0-> left) ?      */
114
#define LCD_FUNCTION          5      /* DB5: function set                   */
115
#define LCD_FUNCTION_8BIT     4      /*   DB4: set 8BIT mode (0->4BIT mode) */
116
#define LCD_FUNCTION_2LINES   3      /*   DB3: two lines (0->one line)      */
117
#define LCD_FUNCTION_10DOTS   2      /*   DB2: 5x10 font (0->5x7 font)      */
118
#define LCD_CGRAM             6      /* DB6: set CG RAM address             */
119
#define LCD_DDRAM             7      /* DB7: set DD RAM address             */
120
#define LCD_BUSY              7      /* DB7: LCD is busy                    */
121
122
/* set entry mode: display shift on/off, dec/inc cursor move direction */
123
#define LCD_ENTRY_DEC            0x04   /* display shift off, dec cursor move dir */
124
#define LCD_ENTRY_DEC_SHIFT      0x05   /* display shift on,  dec cursor move dir */
125
#define LCD_ENTRY_INC_           0x06   /* display shift off, inc cursor move dir */
126
#define LCD_ENTRY_INC_SHIFT      0x07   /* display shift on,  inc cursor move dir */
127
128
/* display on/off, cursor on/off, blinking char at cursor position */
129
#define LCD_DISP_OFF             0x08   /* display off                            */
130
#define LCD_DISP_ON              0x0C   /* display on, cursor off                 */
131
#define LCD_DISP_ON_BLINK        0x0D   /* display on, cursor off, blink char     */
132
#define LCD_DISP_ON_CURSOR       0x0E   /* display on, cursor on                  */
133
#define LCD_DISP_ON_CURSOR_BLINK 0x0F   /* display on, cursor on, blink char      */
134
135
/* move cursor/shift display */
136
#define LCD_MOVE_CURSOR_LEFT     0x10   /* move cursor left  (decrement)          */
137
#define LCD_MOVE_CURSOR_RIGHT    0x14   /* move cursor right (increment)          */
138
#define LCD_MOVE_DISP_LEFT       0x18   /* shift display left                     */
139
#define LCD_MOVE_DISP_RIGHT      0x1C   /* shift display right                    */
140
141
/* function set: set interface data length and number of display lines */
142
#define LCD_FUNCTION_4BIT_1LINE  0x20   /* 4-bit interface, single line, 5x7 dots */
143
#define LCD_FUNCTION_4BIT_2LINES 0x28   /* 4-bit interface, dual line,   5x7 dots */
144
#define LCD_FUNCTION_8BIT_1LINE  0x30   /* 8-bit interface, single line, 5x7 dots */
145
#define LCD_FUNCTION_8BIT_2LINES 0x38   /* 8-bit interface, dual line,   5x7 dots */
146
147
148
#define LCD_MODE_DEFAULT     ((1<<LCD_ENTRY_MODE) | (1<<LCD_ENTRY_INC) )
149
150
151
152
/** 
153
 *  @name Functions
154
 */
155
156
157
/**
158
 @brief    Initialize display and select type of cursor
159
 @param    dispAttr \b LCD_DISP_OFF display off\n
160
                    \b LCD_DISP_ON display on, cursor off\n
161
                    \b LCD_DISP_ON_CURSOR display on, cursor on\n
162
                    \b LCD_DISP_ON_CURSOR_BLINK display on, cursor on flashing             
163
 @return  none
164
*/
165
extern void lcd_init(uint8_t dispAttr);
166
167
168
/**
169
 @brief    Clear display and set cursor to home position
170
 @param    void                                        
171
 @return   none
172
*/
173
extern void lcd_clrscr(void);
174
175
176
/**
177
 @brief    Set cursor to home position
178
 @param    void                                        
179
 @return   none
180
*/
181
extern void lcd_home(void);
182
183
184
/**
185
 @brief    Set cursor to specified position
186
 
187
 @param    x horizontal position\n (0: left most position)
188
 @param    y vertical position\n   (0: first line)
189
 @return   none
190
*/
191
extern void lcd_gotoxy(uint8_t x, uint8_t y);
192
193
194
/**
195
 @brief    Display character at current cursor position
196
 @param    c character to be displayed                                       
197
 @return   none
198
*/
199
extern void lcd_putc(char c);
200
201
202
/**
203
 @brief    Display string without auto linefeed
204
 @param    s string to be displayed                                        
205
 @return   none
206
*/
207
extern void lcd_puts(const char *s);
208
209
210
/**
211
 @brief    Display string from program memory without auto linefeed
212
 @param    s string from program memory be be displayed                                        
213
 @return   none
214
 @see      lcd_puts_P
215
*/
216
extern void lcd_puts_p(const char *progmem_s);
217
218
219
/**
220
 @brief    Send LCD controller instruction command
221
 @param    cmd instruction to send to LCD controller, see HD44780 data sheet
222
 @return   none
223
*/
224
extern void lcd_command(uint8_t cmd);
225
226
227
/**
228
 @brief    Send data byte to LCD controller 
229
 
230
 Similar to lcd_putc(), but without interpreting LF
231
 @param    data byte to send to LCD controller, see HD44780 data sheet
232
 @return   none
233
*/
234
extern void lcd_data(uint8_t data);
235
236
237
/**
238
 @brief macros for automatically storing string constant in program memory
239
*/
240
#define lcd_puts_P(__s)         lcd_puts_p(PSTR(__s))
241
242
/*@}*/
243
#endif //LCD_H

und hier die lcd.c
1
/****************************************************************************
2
 Title  :   HD44780U LCD library
3
 Author:    Peter Fleury <pfleury@gmx.ch>  http://jump.to/fleury
4
 File:      $Id: lcd.c,v 1.14.2.1 2006/01/29 12:16:41 peter Exp $
5
 Software:  AVR-GCC 3.3 
6
 Target:    any AVR device, memory mapped mode only for AT90S4414/8515/Mega
7
8
 DESCRIPTION
9
       Basic routines for interfacing a HD44780U-based text lcd display
10
11
       Originally based on Volker Oth's lcd library,
12
       changed lcd_init(), added additional constants for lcd_command(),
13
       added 4-bit I/O mode, improved and optimized code.
14
15
       Library can be operated in memory mapped mode (LCD_IO_MODE=0) or in 
16
       4-bit IO port mode (LCD_IO_MODE=1). 8-bit IO port mode not supported.
17
       
18
       Memory mapped mode compatible with Kanda STK200, but supports also
19
       generation of R/W signal through A8 address line.
20
21
 USAGE
22
       See the C include lcd.h file for a description of each function
23
       
24
*****************************************************************************/
25
26
#include <inttypes.h>
27
#include <avr/io.h>
28
#include <avr/pgmspace.h>
29
#include "lcd.h"
30
31
32
33
/* 
34
** constants/macros 
35
*/
36
#define DDR(x) (*(&x - 1))      /* address of data direction register of port x */
37
#if defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__)
38
    /* on ATmega64/128 PINF is on port 0x00 and not 0x60 */
39
    #define PIN(x) ( &PORTF==&(x) ? _SFR_IO8(0x00) : (*(&x - 2)) )
40
#else
41
  #define PIN(x) (*(&x - 2))    /* address of input register of port x          */
42
#endif
43
44
45
#if LCD_IO_MODE
46
#define lcd_e_delay()   __asm__ __volatile__( "rjmp 1f\n 1:" );
47
#define lcd_e_high()    LCD_E_PORT  |=  _BV(LCD_E_PIN);
48
#define lcd_e_low()     LCD_E_PORT  &= ~_BV(LCD_E_PIN);
49
#define lcd_e_toggle()  toggle_e()
50
#define lcd_rw_high()   LCD_RW_PORT |=  _BV(LCD_RW_PIN)
51
#define lcd_rw_low()    LCD_RW_PORT &= ~_BV(LCD_RW_PIN)
52
#define lcd_rs_high()   LCD_RS_PORT |=  _BV(LCD_RS_PIN)
53
#define lcd_rs_low()    LCD_RS_PORT &= ~_BV(LCD_RS_PIN)
54
#endif
55
56
#if LCD_IO_MODE
57
#if LCD_LINES==1
58
#define LCD_FUNCTION_DEFAULT    LCD_FUNCTION_4BIT_1LINE 
59
#else
60
#define LCD_FUNCTION_DEFAULT    LCD_FUNCTION_4BIT_2LINES 
61
#endif
62
#else
63
#if LCD_LINES==1
64
#define LCD_FUNCTION_DEFAULT    LCD_FUNCTION_8BIT_1LINE
65
#else
66
#define LCD_FUNCTION_DEFAULT    LCD_FUNCTION_8BIT_2LINES
67
#endif
68
#endif
69
70
#if LCD_CONTROLLER_KS0073
71
#if LCD_LINES==4
72
73
#define KS0073_EXTENDED_FUNCTION_REGISTER_ON  0x24   /* |0|010|0100 4-bit mode extension-bit RE = 1 */
74
#define KS0073_EXTENDED_FUNCTION_REGISTER_OFF 0x20   /* |0|000|1001 4 lines mode */
75
#define KS0073_4LINES_MODE                    0x09   /* |0|001|0000 4-bit mode, extension-bit RE = 0 */
76
77
#endif
78
#endif
79
80
/* 
81
** function prototypes 
82
*/
83
#if LCD_IO_MODE
84
static void toggle_e(void);
85
#endif
86
87
/*
88
** local functions
89
*/
90
91
92
93
/*************************************************************************
94
 delay loop for small accurate delays: 16-bit counter, 4 cycles/loop
95
*************************************************************************/
96
static inline void _delayFourCycles(unsigned int __count)
97
{
98
    if ( __count == 0 )    
99
        __asm__ __volatile__( "rjmp 1f\n 1:" );    // 2 cycles
100
    else
101
        __asm__ __volatile__ (
102
          "1: sbiw %0,1" "\n\t"                  
103
          "brne 1b"                              // 4 cycles/loop
104
          : "=w" (__count)
105
          : "0" (__count)
106
         );
107
}
108
109
110
/************************************************************************* 
111
delay for a minimum of <us> microseconds
112
the number of loops is calculated at compile-time from MCU clock frequency
113
*************************************************************************/
114
#define delay(us)  _delayFourCycles( ( ( 1*(XTAL/4000) )*us)/1000 )
115
116
117
#if LCD_IO_MODE
118
/* toggle Enable Pin to initiate write */
119
static void toggle_e(void)
120
{
121
    lcd_e_high();
122
    lcd_e_delay();
123
    lcd_e_low();
124
}
125
#endif
126
127
128
/*************************************************************************
129
Low-level function to write byte to LCD controller
130
Input:    data   byte to write to LCD
131
          rs     1: write data    
132
                 0: write instruction
133
Returns:  none
134
*************************************************************************/
135
#if LCD_IO_MODE
136
static void lcd_write(uint8_t data,uint8_t rs) 
137
{
138
    unsigned char dataBits ;
139
140
141
    if (rs) {   /* write data        (RS=1, RW=0) */
142
       lcd_rs_high();
143
    } else {    /* write instruction (RS=0, RW=0) */
144
       lcd_rs_low();
145
    }
146
    lcd_rw_low();
147
148
    if ( ( &LCD_DATA0_PORT == &LCD_DATA1_PORT) && ( &LCD_DATA1_PORT == &LCD_DATA2_PORT ) && ( &LCD_DATA2_PORT == &LCD_DATA3_PORT )
149
      && (LCD_DATA0_PIN == 0) && (LCD_DATA1_PIN == 1) && (LCD_DATA2_PIN == 2) && (LCD_DATA3_PIN == 3) )
150
    {
151
        /* configure data pins as output */
152
        DDR(LCD_DATA0_PORT) |= 0x0F;
153
154
        /* output high nibble first */
155
        dataBits = LCD_DATA0_PORT & 0xF0;
156
        LCD_DATA0_PORT = dataBits |((data>>4)&0x0F);
157
        lcd_e_toggle();
158
159
        /* output low nibble */
160
        LCD_DATA0_PORT = dataBits | (data&0x0F);
161
        lcd_e_toggle();
162
163
        /* all data pins high (inactive) */
164
        LCD_DATA0_PORT = dataBits | 0x0F;
165
    }
166
    else
167
    {
168
        /* configure data pins as output */
169
        DDR(LCD_DATA0_PORT) |= _BV(LCD_DATA0_PIN);
170
        DDR(LCD_DATA1_PORT) |= _BV(LCD_DATA1_PIN);
171
        DDR(LCD_DATA2_PORT) |= _BV(LCD_DATA2_PIN);
172
        DDR(LCD_DATA3_PORT) |= _BV(LCD_DATA3_PIN);
173
        
174
        /* output high nibble first */
175
        LCD_DATA3_PORT &= ~_BV(LCD_DATA3_PIN);
176
        LCD_DATA2_PORT &= ~_BV(LCD_DATA2_PIN);
177
        LCD_DATA1_PORT &= ~_BV(LCD_DATA1_PIN);
178
        LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN);
179
      if(data & 0x80) LCD_DATA3_PORT |= _BV(LCD_DATA3_PIN);
180
      if(data & 0x40) LCD_DATA2_PORT |= _BV(LCD_DATA2_PIN);
181
      if(data & 0x20) LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN);
182
      if(data & 0x10) LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN);   
183
        lcd_e_toggle();
184
        
185
        /* output low nibble */
186
        LCD_DATA3_PORT &= ~_BV(LCD_DATA3_PIN);
187
        LCD_DATA2_PORT &= ~_BV(LCD_DATA2_PIN);
188
        LCD_DATA1_PORT &= ~_BV(LCD_DATA1_PIN);
189
        LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN);
190
      if(data & 0x08) LCD_DATA3_PORT |= _BV(LCD_DATA3_PIN);
191
      if(data & 0x04) LCD_DATA2_PORT |= _BV(LCD_DATA2_PIN);
192
      if(data & 0x02) LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN);
193
      if(data & 0x01) LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN);
194
        lcd_e_toggle();        
195
        
196
        /* all data pins high (inactive) */
197
        LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN);
198
        LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN);
199
        LCD_DATA2_PORT |= _BV(LCD_DATA2_PIN);
200
        LCD_DATA3_PORT |= _BV(LCD_DATA3_PIN);
201
    }
202
}
203
#else
204
#define lcd_write(d,rs) if (rs) *(volatile uint8_t*)(LCD_IO_DATA) = d; else *(volatile uint8_t*)(LCD_IO_FUNCTION) = d;
205
/* rs==0 -> write instruction to LCD_IO_FUNCTION */
206
/* rs==1 -> write data to LCD_IO_DATA */
207
#endif
208
209
210
/*************************************************************************
211
Low-level function to read byte from LCD controller
212
Input:    rs     1: read data    
213
                 0: read busy flag / address counter
214
Returns:  byte read from LCD controller
215
*************************************************************************/
216
#if LCD_IO_MODE
217
static uint8_t lcd_read(uint8_t rs) 
218
{
219
    uint8_t data;
220
    
221
    
222
    if (rs)
223
        lcd_rs_high();                       /* RS=1: read data      */
224
    else
225
        lcd_rs_low();                        /* RS=0: read busy flag */
226
    lcd_rw_high();                           /* RW=1  read mode      */
227
    
228
    if ( ( &LCD_DATA0_PORT == &LCD_DATA1_PORT) && ( &LCD_DATA1_PORT == &LCD_DATA2_PORT ) && ( &LCD_DATA2_PORT == &LCD_DATA3_PORT )
229
      && ( LCD_DATA0_PIN == 0 )&& (LCD_DATA1_PIN == 1) && (LCD_DATA2_PIN == 2) && (LCD_DATA3_PIN == 3) )
230
    {
231
        DDR(LCD_DATA0_PORT) &= 0xF0;         /* configure data pins as input */
232
        
233
        lcd_e_high();
234
        lcd_e_delay();        
235
        data = PIN(LCD_DATA0_PORT) << 4;     /* read high nibble first */
236
        lcd_e_low();
237
        
238
        lcd_e_delay();                       /* Enable 500ns low       */
239
        
240
        lcd_e_high();
241
        lcd_e_delay();
242
        data |= PIN(LCD_DATA0_PORT)&0x0F;    /* read low nibble        */
243
        lcd_e_low();
244
    }
245
    else
246
    {
247
        /* configure data pins as input */
248
        DDR(LCD_DATA0_PORT) &= ~_BV(LCD_DATA0_PIN);
249
        DDR(LCD_DATA1_PORT) &= ~_BV(LCD_DATA1_PIN);
250
        DDR(LCD_DATA2_PORT) &= ~_BV(LCD_DATA2_PIN);
251
        DDR(LCD_DATA3_PORT) &= ~_BV(LCD_DATA3_PIN);
252
                
253
        /* read high nibble first */
254
        lcd_e_high();
255
        lcd_e_delay();        
256
        data = 0;
257
        if ( PIN(LCD_DATA0_PORT) & _BV(LCD_DATA0_PIN) ) data |= 0x10;
258
        if ( PIN(LCD_DATA1_PORT) & _BV(LCD_DATA1_PIN) ) data |= 0x20;
259
        if ( PIN(LCD_DATA2_PORT) & _BV(LCD_DATA2_PIN) ) data |= 0x40;
260
        if ( PIN(LCD_DATA3_PORT) & _BV(LCD_DATA3_PIN) ) data |= 0x80;
261
        lcd_e_low();
262
263
        lcd_e_delay();                       /* Enable 500ns low       */
264
    
265
        /* read low nibble */    
266
        lcd_e_high();
267
        lcd_e_delay();
268
        if ( PIN(LCD_DATA0_PORT) & _BV(LCD_DATA0_PIN) ) data |= 0x01;
269
        if ( PIN(LCD_DATA1_PORT) & _BV(LCD_DATA1_PIN) ) data |= 0x02;
270
        if ( PIN(LCD_DATA2_PORT) & _BV(LCD_DATA2_PIN) ) data |= 0x04;
271
        if ( PIN(LCD_DATA3_PORT) & _BV(LCD_DATA3_PIN) ) data |= 0x08;        
272
        lcd_e_low();
273
    }
274
    return data;
275
}
276
#else
277
#define lcd_read(rs) (rs) ? *(volatile uint8_t*)(LCD_IO_DATA+LCD_IO_READ) : *(volatile uint8_t*)(LCD_IO_FUNCTION+LCD_IO_READ)
278
/* rs==0 -> read instruction from LCD_IO_FUNCTION */
279
/* rs==1 -> read data from LCD_IO_DATA */
280
#endif
281
282
283
/*************************************************************************
284
loops while lcd is busy, returns address counter
285
*************************************************************************/
286
static uint8_t lcd_waitbusy(void)
287
288
{
289
    register uint8_t c;
290
    
291
    /* wait until busy flag is cleared */
292
    while ( (c=lcd_read(0)) & (1<<LCD_BUSY)) {}
293
    
294
    /* the address counter is updated 4us after the busy flag is cleared */
295
    delay(2);
296
297
    /* now read the address counter */
298
    return (lcd_read(0));  // return address counter
299
    
300
}/* lcd_waitbusy */
301
302
303
/*************************************************************************
304
Move cursor to the start of next line or to the first line if the cursor 
305
is already on the last line.
306
*************************************************************************/
307
static inline void lcd_newline(uint8_t pos)
308
{
309
    register uint8_t addressCounter;
310
311
312
#if LCD_LINES==1
313
    addressCounter = 0;
314
#endif
315
#if LCD_LINES==2
316
    if ( pos < (LCD_START_LINE2) )
317
        addressCounter = LCD_START_LINE2;
318
    else
319
        addressCounter = LCD_START_LINE1;
320
#endif
321
#if LCD_LINES==4
322
#if KS0073_4LINES_MODE
323
    if ( pos < LCD_START_LINE2 )
324
        addressCounter = LCD_START_LINE2;
325
    else if ( (pos >= LCD_START_LINE2) && (pos < LCD_START_LINE3) )
326
        addressCounter = LCD_START_LINE3;
327
    else if ( (pos >= LCD_START_LINE3) && (pos < LCD_START_LINE4) )
328
        addressCounter = LCD_START_LINE4;
329
    else 
330
        addressCounter = LCD_START_LINE1;
331
#else
332
    if ( pos < LCD_START_LINE3 )
333
        addressCounter = LCD_START_LINE2;
334
    else if ( (pos >= LCD_START_LINE2) && (pos < LCD_START_LINE4) )
335
        addressCounter = LCD_START_LINE3;
336
    else if ( (pos >= LCD_START_LINE3) && (pos < LCD_START_LINE2) )
337
        addressCounter = LCD_START_LINE4;
338
    else 
339
        addressCounter = LCD_START_LINE1;
340
#endif
341
#endif
342
    lcd_command((1<<LCD_DDRAM)+addressCounter);
343
344
}/* lcd_newline */
345
346
347
/*
348
** PUBLIC FUNCTIONS 
349
*/
350
351
/*************************************************************************
352
Send LCD controller instruction command
353
Input:   instruction to send to LCD controller, see HD44780 data sheet
354
Returns: none
355
*************************************************************************/
356
void lcd_command(uint8_t cmd)
357
{
358
    lcd_waitbusy();
359
    lcd_write(cmd,0);
360
}
361
362
363
/*************************************************************************
364
Send data byte to LCD controller 
365
Input:   data to send to LCD controller, see HD44780 data sheet
366
Returns: none
367
*************************************************************************/
368
void lcd_data(uint8_t data)
369
{
370
    lcd_waitbusy();
371
    lcd_write(data,1);
372
}
373
374
375
376
/*************************************************************************
377
Set cursor to specified position
378
Input:    x  horizontal position  (0: left most position)
379
          y  vertical position    (0: first line)
380
Returns:  none
381
*************************************************************************/
382
void lcd_gotoxy(uint8_t x, uint8_t y)
383
{
384
#if LCD_LINES==1
385
    lcd_command((1<<LCD_DDRAM)+LCD_START_LINE1+x);
386
#endif
387
#if LCD_LINES==2
388
    if ( y==0 ) 
389
        lcd_command((1<<LCD_DDRAM)+LCD_START_LINE1+x);
390
    else
391
        lcd_command((1<<LCD_DDRAM)+LCD_START_LINE2+x);
392
#endif
393
#if LCD_LINES==4
394
    if ( y==0 )
395
        lcd_command((1<<LCD_DDRAM)+LCD_START_LINE1+x);
396
    else if ( y==1)
397
        lcd_command((1<<LCD_DDRAM)+LCD_START_LINE2+x);
398
    else if ( y==2)
399
        lcd_command((1<<LCD_DDRAM)+LCD_START_LINE3+x);
400
    else /* y==3 */
401
        lcd_command((1<<LCD_DDRAM)+LCD_START_LINE4+x);
402
#endif
403
404
}/* lcd_gotoxy */
405
406
407
/*************************************************************************
408
*************************************************************************/
409
int lcd_getxy(void)
410
{
411
    return lcd_waitbusy();
412
}
413
414
415
/*************************************************************************
416
Clear display and set cursor to home position
417
*************************************************************************/
418
void lcd_clrscr(void)
419
{
420
    lcd_command(1<<LCD_CLR);
421
}
422
423
424
/*************************************************************************
425
Set cursor to home position
426
*************************************************************************/
427
void lcd_home(void)
428
{
429
    lcd_command(1<<LCD_HOME);
430
}
431
432
433
/*************************************************************************
434
Display character at current cursor position 
435
Input:    character to be displayed                                       
436
Returns:  none
437
*************************************************************************/
438
void lcd_putc(char c)
439
{
440
    uint8_t pos;
441
442
443
    pos = lcd_waitbusy();   // read busy-flag and address counter
444
    if (c=='\n')
445
    {
446
        lcd_newline(pos);
447
    }
448
    else
449
    {
450
#if LCD_WRAP_LINES==1
451
#if LCD_LINES==1
452
        if ( pos == LCD_START_LINE1+LCD_DISP_LENGTH ) {
453
            lcd_write((1<<LCD_DDRAM)+LCD_START_LINE1,0);
454
        }
455
#elif LCD_LINES==2
456
        if ( pos == LCD_START_LINE1+LCD_DISP_LENGTH ) {
457
            lcd_write((1<<LCD_DDRAM)+LCD_START_LINE2,0);    
458
        }else if ( pos == LCD_START_LINE2+LCD_DISP_LENGTH ){
459
            lcd_write((1<<LCD_DDRAM)+LCD_START_LINE1,0);
460
        }
461
#elif LCD_LINES==4
462
        if ( pos == LCD_START_LINE1+LCD_DISP_LENGTH ) {
463
            lcd_write((1<<LCD_DDRAM)+LCD_START_LINE2,0);    
464
        }else if ( pos == LCD_START_LINE2+LCD_DISP_LENGTH ) {
465
            lcd_write((1<<LCD_DDRAM)+LCD_START_LINE3,0);
466
        }else if ( pos == LCD_START_LINE3+LCD_DISP_LENGTH ) {
467
            lcd_write((1<<LCD_DDRAM)+LCD_START_LINE4,0);
468
        }else if ( pos == LCD_START_LINE4+LCD_DISP_LENGTH ) {
469
            lcd_write((1<<LCD_DDRAM)+LCD_START_LINE1,0);
470
        }
471
#endif
472
        lcd_waitbusy();
473
#endif
474
        lcd_write(c, 1);
475
    }
476
477
}/* lcd_putc */
478
479
480
/*************************************************************************
481
Display string without auto linefeed 
482
Input:    string to be displayed
483
Returns:  none
484
*************************************************************************/
485
void lcd_puts(const char *s)
486
/* print string on lcd (no auto linefeed) */
487
{
488
    register char c;
489
490
    while ( (c = *s++) ) {
491
        lcd_putc(c);
492
    }
493
494
}/* lcd_puts */
495
496
497
/*************************************************************************
498
Display string from program memory without auto linefeed 
499
Input:     string from program memory be be displayed                                        
500
Returns:   none
501
*************************************************************************/
502
void lcd_puts_p(const char *progmem_s)
503
/* print string from program memory on lcd (no auto linefeed) */
504
{
505
    register char c;
506
507
    while ( (c = pgm_read_byte(progmem_s++)) ) {
508
        lcd_putc(c);
509
    }
510
511
}/* lcd_puts_p */
512
513
514
/*************************************************************************
515
Initialize display and select type of cursor 
516
Input:    dispAttr LCD_DISP_OFF            display off
517
                   LCD_DISP_ON             display on, cursor off
518
                   LCD_DISP_ON_CURSOR      display on, cursor on
519
                   LCD_DISP_CURSOR_BLINK   display on, cursor on flashing
520
Returns:  none
521
*************************************************************************/
522
void lcd_init(uint8_t dispAttr)
523
{
524
#if LCD_IO_MODE
525
    /*
526
     *  Initialize LCD to 4 bit I/O mode
527
     */
528
    
529
    if ( ( &LCD_DATA0_PORT == &LCD_DATA1_PORT) && ( &LCD_DATA1_PORT == &LCD_DATA2_PORT ) && ( &LCD_DATA2_PORT == &LCD_DATA3_PORT )
530
      && ( &LCD_RS_PORT == &LCD_DATA0_PORT) && ( &LCD_RW_PORT == &LCD_DATA0_PORT) && (&LCD_E_PORT == &LCD_DATA0_PORT)
531
      && (LCD_DATA0_PIN == 0 ) && (LCD_DATA1_PIN == 1) && (LCD_DATA2_PIN == 2) && (LCD_DATA3_PIN == 3) 
532
      && (LCD_RS_PIN == 4 ) && (LCD_RW_PIN == 5) && (LCD_E_PIN == 6 ) )
533
    {
534
        /* configure all port bits as output (all LCD lines on same port) */
535
        DDR(LCD_DATA0_PORT) |= 0x7F;
536
    }
537
    else if ( ( &LCD_DATA0_PORT == &LCD_DATA1_PORT) && ( &LCD_DATA1_PORT == &LCD_DATA2_PORT ) && ( &LCD_DATA2_PORT == &LCD_DATA3_PORT )
538
           && (LCD_DATA0_PIN == 0 ) && (LCD_DATA1_PIN == 1) && (LCD_DATA2_PIN == 2) && (LCD_DATA3_PIN == 3) )
539
    {
540
        /* configure all port bits as output (all LCD data lines on same port, but control lines on different ports) */
541
        DDR(LCD_DATA0_PORT) |= 0x0F;
542
        DDR(LCD_RS_PORT)    |= _BV(LCD_RS_PIN);
543
        DDR(LCD_RW_PORT)    |= _BV(LCD_RW_PIN);
544
        DDR(LCD_E_PORT)     |= _BV(LCD_E_PIN);
545
    }
546
    else
547
    {
548
        /* configure all port bits as output (LCD data and control lines on different ports */
549
        DDR(LCD_RS_PORT)    |= _BV(LCD_RS_PIN);
550
        DDR(LCD_RW_PORT)    |= _BV(LCD_RW_PIN);
551
        DDR(LCD_E_PORT)     |= _BV(LCD_E_PIN);
552
        DDR(LCD_DATA0_PORT) |= _BV(LCD_DATA0_PIN);
553
        DDR(LCD_DATA1_PORT) |= _BV(LCD_DATA1_PIN);
554
        DDR(LCD_DATA2_PORT) |= _BV(LCD_DATA2_PIN);
555
        DDR(LCD_DATA3_PORT) |= _BV(LCD_DATA3_PIN);
556
    }
557
  
558
  delay(16000);        /* wait 16ms or more after power-on       */
559
  PORTD = PORTD | 0b00010000;
560
  /* initial write to lcd is 8bit */
561
    LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN);  // _BV(LCD_FUNCTION)>>4;
562
    LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN);  // _BV(LCD_FUNCTION_8BIT)>>4;
563
    lcd_e_toggle();
564
    delay(4992);         /* delay, busy flag can't be checked here */
565
    /* repeat last command */ 
566
    lcd_e_toggle();      
567
    delay(64);           /* delay, busy flag can't be checked here */
568
569
    
570
    /* repeat last command a third time */
571
    lcd_e_toggle();      
572
    delay(64);           /* delay, busy flag can't be checked here */
573
574
575
    /* now configure for 4bit mode */
576
    LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN);   // LCD_FUNCTION_4BIT_1LINE>>4
577
    lcd_e_toggle();
578
    delay(64);           /* some displays need this additional delay */
579
580
    
581
    /* from now the LCD only accepts 4 bit I/O, we can use lcd_command() */    
582
#else
583
    /*
584
     * Initialize LCD to 8 bit memory mapped mode
585
     */
586
    
587
    /* enable external SRAM (memory mapped lcd) and one wait state */        
588
    MCUCR = _BV(SRE) | _BV(SRW);
589
590
    /* reset LCD */
591
    delay(16000);                           /* wait 16ms after power-on     */
592
    lcd_write(LCD_FUNCTION_8BIT_1LINE,0);   /* function set: 8bit interface */                   
593
    delay(4992);                            /* wait 5ms                     */
594
    lcd_write(LCD_FUNCTION_8BIT_1LINE,0);   /* function set: 8bit interface */                 
595
    delay(64);                              /* wait 64us                    */
596
    lcd_write(LCD_FUNCTION_8BIT_1LINE,0);   /* function set: 8bit interface */                
597
    delay(64);                              /* wait 64us                    */
598
#endif
599
600
#if KS0073_4LINES_MODE
601
    /* Display with KS0073 controller requires special commands for enabling 4 line mode */
602
  lcd_command(KS0073_EXTENDED_FUNCTION_REGISTER_ON);
603
  lcd_command(KS0073_4LINES_MODE);
604
  lcd_command(KS0073_EXTENDED_FUNCTION_REGISTER_OFF);
605
#else
606
    lcd_command(LCD_FUNCTION_DEFAULT);      /* function set: display lines  */
607
#endif
608
    lcd_command(LCD_DISP_OFF);              /* display off                  */
609
    lcd_clrscr();                           /* display clear                */ 
610
    lcd_command(LCD_MODE_DEFAULT);          /* set entry mode               */
611
    lcd_command(dispAttr);                  /* display/cursor control       */
612
613
}/* lcd_init */


Zur meiner Annahme mit dem delay bin ich nur gekommen weil ich Stück für 
Stück den Code durch gegangen bin, an ausgewählten Stellen hab ich meine 
LED einschalten lassen und bis zum erst Aufruf dieser delay Funktion 
ging sie auch immer an(bzw. fing sie an zu Blinken was ja bedeute das 
der Controller läuft aber das LCD blieb trotzdem uninitialisiert) nach 
der delay Funktion blieb sie aus. Ich hoffe man konnte verstehen was ich 
damit sagen wollte.

von Tobias P. (wuka-rudi)


Angehängte Dateien:

Lesenswert?

Achso hier noch der Schaltplan der AVR Entwicklungsplatine AT90USB162 
(AVR-USB-162)

von Peter D. (peda)


Lesenswert?

Puh, das Scrollrad an meiner Maus ist rot glühend, bis ich endlich hier 
unten angekommen bin.
Was soll das, hast Du noch nie was von Dateianhang gehört?

Mir ist die Fleury LCD Lib viel zu gewaltig, viel zuviel Code.
Ich mags lieber klein und einfach:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=102296


Peter

von Karl H. (kbuchegg)


Lesenswert?

Tobias Pfundt schrieb:
> Achso hier noch der Schaltplan der AVR Entwicklungsplatine AT90USB162
> (AVR-USB-162)

Schön.
Und wo sieht man da jetzt, wie du das LCD angeschlossen hast?


Die Fleury Lib will eine funktionierende R/W Leitung.
Hast du die angeschlossen?

von Tobias P. (wuka-rudi)


Lesenswert?

Sorry auf's als Datei anhängen bin ick irgendwie nicht gekommen.

Habe das LCD an R/W Leitungen angeschlossen. Hab gehofft das geht aus 
der LCD.h und meinem Bild hervor.

von Tobias P. (wuka-rudi)


Lesenswert?

So geht jetzt. Kann nicht genau sagen woran es lag. Ich denke ein 
Problem war der Wachtdog und maximale verwirrtheit meiner Seits :-)

von Thomas M. (thomaswm)


Lesenswert?

"Maximale Verwirrtheit"  :-D

MfG, bis morgen zum Käffchen...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.