hi
habs hinbekommen nach langem testen.
habe mal den geänderten Quelltext und die Testroutine angehängt
m50030.h
#ifndef M50530_H
#define M50530_H
#include <avr/io.h>
// Data and Control signals can be connected to different ports!
// data port, LCD signals DB4-DB7 have to be connected to P0-P3
#define LCDDATAPORT PORTB
#define LCDDATADIR DDRB
#define LCDDATAPIN PINB
// control port, LCD signals RW, EX, I/OC1, I/OC2
#define LCDCTRLPORT PORTD
#define LCDCTRLDIR DDRD
//#define LCDCTRLPIN PIND
#define LCDPIN_RW 4
#define LCDPIN_IOC1 7
#define LCDPIN_IOC2 5
#define LCDPIN_EX 6
// display commands
#define LCD_CMD_SETFUNCTIONMODE 0xc0 // SF
#define LCD_CMD_SETENTRYMODE 0x40 // SE
#define LCD_CMD_SETDISPLAYMODE 0x20 // SD
#define LCD_CMD_SHIFTCURDISPADDRESS 0x10 // MA
#define LCD_CMD_SETUNDERLINEMODE 0x0C // SU
#define LCD_CMD_WRITERAMUNDERLINEBIT 0x08 // WU
#define LCD_CMD_SETBLINKINGFREQUENCY 0x04 // SB
#define LCD_CMD_CURSORHOMESTARTADDR 0x03 // MH
#define LCD_CMD_CLEARCURSORDATAADDRHOME 0x01 // CH
#define LCD_CMD_NOOPERATION 0x00 // NOP
// SF - Set Function Mode constants
#define sfIO8BIT 0x20 // bit 5
#define sfIO4BIT 0x00
#define sfFont5x8 0x10 // bit 4
#define sfFont5x12 0x00
// SD - Set Display Mode constants
#define dmDisplayOn 0x10
//#define dmDisplayOn 16
#define dmCursorOn 0x08
#define dmUnderline 0x04
#define dmCursorBlink 0x02
#define dmCharacterBlink 0x01
// SU - Set Underline Mode constants
#define suSetUnderline 0x03
#define suResetUnderline 0x02
#define suNoUnderline 0x00
// SB - Set Blinking Frequency constants
#define sbSlow 0x00
#define sbNormal 0x01
#define sbFast 0x02
#define sbFastest 0x03
// SE - Set Entry Mode constants
// base definitions cursor
#define LCD_EM_CursorRead 0x08
#define LCD_EM_CursorWrite 0x10
#define LCD_EM_CursorIncrement 0x00
#define LCD_EM_CursorDecrement 0x20
// base definitions display
#define LCD_EM_DisplayRead 0x01
#define LCD_EM_DisplayWrite 0x02
#define LCD_EM_DisplayIncrement 0x00
#define LCD_EM_DisplayDecrement 0x04
// constants for cursor
#define emCursorNoChange 0x00
#define emCursorIncRead LCD_EM_CursorIncrement | LCD_EM_CursorRead
#define emCursorIncWrite LCD_EM_CursorIncrement | LCD_EM_CursorWrite
#define emCursorIncReadWrite LCD_EM_CursorIncrement | LCD_EM_CursorRead | LCD_EM_CursorWrite
#define emCursorDecRead LCD_EM_CursorDecrement | LCD_EM_CursorRead
#define emCursorDecWrite LCD_EM_CursorDecrement | LCD_EM_CursorWrite
#define emCursorDecReadWrite LCD_EM_CursorDecrement | LCD_EM_CursorRead | LCD_EM_CursorWrite
// constants for display start address
#define emDisplayNoChange 0x00
#define emDisplayIncRead LCD_EM_DisplayIncrement | LCD_EM_DisplayRead
#define emDisplayIncWrite LCD_EM_DisplayIncrement | LCD_EM_DisplayWrite
#define emDisplayIncReadWrite LCD_EM_DisplayIncrement | LCD_EM_DisplayRead | LCD_EM_DisplayWrite
#define emDisplayDecRead LCD_EM_DisplayDecrement | LCD_EM_DisplayRead
#define emDisplayDecWrite LCD_EM_DisplayDecrement | LCD_EM_DisplayWrite
#define emDisplayDecReadWrite LCD_EM_DisplayDecrement | LCD_EM_DisplayRead | LCD_EM_DisplayWrite
extern int LCDIsBusy(void);
extern void LCDSend(unsigned char AControl, unsigned char AData);
extern char LCDInit(void);
extern void LCDSetCursorPos(const unsigned char y, const unsigned char x);
extern const char LCDWrite(const char * c);
extern void LCDWritePGM(const char * c);
// schreibt das übergebene Zeichen an die aktuelle Cursor-Position
#define LCDWriteChar(c) LCDSend(_BV(LCDPIN_IOC2), c)
// setzt den Display-Modus
// man verwende die oben deklarierten Konstanten ;)
#define LCDSetDisplayMode(mode) LCDSend(0, mode | 32)
#define LCDSetEntryMode(mode) LCDSend(0, mode)
// setzt den Cursor an die angegebene Adresse
//#define LCDSetCursorAddress(address) LCDSend((1<<LCDPIN_IOC1) | (1<<LCDPIN_IOC2), address)
#define cls(void) LCDSend(0, LCD_CMD_CLEARCURSORDATAADDRHOME);
#endif
m50530.cpp
#include "m50530.h"
#include <util/delay.h>
#include <avr/pgmspace.h>
void LCDToggleEX(void)
{
//_delay_us(5);
LCDCTRLPORT |= (_BV(LCDPIN_EX));
_delay_us(2); // 10 2
LCDCTRLPORT &= ~(_BV(LCDPIN_EX));
//_delay_us(5);
}
int LCDIsBusy(void)
{
unsigned char lInpData = 0;
int lBusyFlag = 0;
int l4BitFlag = 0;
// data port set up to input
LCDDATADIR &= 0xf0;
// set RW signal
LCDCTRLPORT |= _BV(LCDPIN_RW);
// delay?
//_delay_us(5);
// set EX signal
LCDCTRLPORT |= _BV(LCDPIN_EX);
// delay?
//_delay_us(2); // 10
// read 1st nibble
lInpData = LCDDATAPIN;
// clear EX signal
LCDCTRLPORT &= ~_BV(LCDPIN_EX);
lBusyFlag = ( lInpData & (1 << 3) );
l4BitFlag = !( lInpData & (1 << 2) );
// delay?
//_delay_us(5);
// read 2nd nibble
if ( l4BitFlag )
{
// set EX signal
LCDCTRLPORT |= _BV(LCDPIN_EX);
// delay?
//_delay_us(2); // 10
// read 2nd nibble
LCDDATAPIN;
// clear EX signal
LCDCTRLPORT &= ~_BV(LCDPIN_EX);
}
//_delay_us(10);
// clear RW signal
LCDCTRLPORT &= ~_BV(LCDPIN_RW);
// set data port back to output
LCDDATADIR |= 0x0f;
// clear data outputs
LCDDATAPORT &= 0xf0;
return lBusyFlag;
}
void LCDSend(unsigned char AControl, unsigned char AData)
{
//Serial.println(AControl);
unsigned char lHN = ( AData & 0xf0 ) >> 4;
unsigned char lLN = ( AData & 0x0f );
while ( LCDIsBusy() )
;
LCDCTRLPORT &= ~(_BV(LCDPIN_RW) | _BV(LCDPIN_IOC1) | _BV(LCDPIN_IOC2) | _BV(LCDPIN_EX));
LCDCTRLPORT |= AControl;
LCDDATAPORT &= 0xf0;
LCDDATAPORT |= lHN;
LCDToggleEX();
LCDDATAPORT &= 0xf0;
LCDDATAPORT |= lLN;
LCDToggleEX();
LCDDATAPORT &= 0xf0;
LCDCTRLPORT &= ~AControl;
_delay_us(20);
//return LCDDATAPORT;
}
char LCDInit(void)
{
// port setup
LCDDATADIR |= 0x0F;
LCDCTRLDIR |= _BV(LCDPIN_RW) | _BV(LCDPIN_IOC1) | _BV(LCDPIN_IOC2) | _BV(LCDPIN_EX);
// SF - Set Function Mode
// >> 4 Bit I/O, 5x8 Font, 1/32 duty
// >> 4 lines x 40 words, 96 words CG RAM
LCDSend( 0, LCD_CMD_SETFUNCTIONMODE | sfIO4BIT | sfFont5x8 | 8 ); //geändert von 0x0b zu 8
// SE - Set Entry Mode
LCDSend( 0, LCD_CMD_SETENTRYMODE | emCursorIncWrite | emDisplayNoChange );
// SU - Set Underline Mode
LCDSend( 0, LCD_CMD_SETUNDERLINEMODE | suNoUnderline );
// SB - Set Blinking Frequency
LCDSend( 0, LCD_CMD_SETBLINKINGFREQUENCY | sbNormal );
// SD - Set Display Mode
LCDSend( 0, LCD_CMD_SETDISPLAYMODE | dmDisplayOn | dmCursorOn | dmCursorBlink);
// CH - Clear Cursor of DD RAM display data home & display start address home
LCDSend( 0, LCD_CMD_CLEARCURSORDATAADDRHOME );
_delay_ms(2);
return 't';
}
// setzt den Cursor an die angegebene Position (y = Zeile, x = Spalte)
void LCDSetCursorPos(const unsigned char y, const unsigned char x)
{
// Adresse aus x und y berechnen
// Adressen sind wie folgt: Zeile 0 = 0; Zeile 1 = 40; Zeile 2 = 80; Zeile 3 = 120; Zeile 4 = 160; Zeile 5 = 64+24; Zeile 6 = 128+24; Zeile 7 = 192+24
//unsigned char address = x + (y*40);
unsigned char address = x + ((y % 4) << 6);
if (y > 3)
address += 24;
LCDSend(_BV(LCDPIN_IOC1)|_BV(LCDPIN_IOC2), address);
}
// schreibt die übergebene Zeichenkette an die aktuelle Cursor-Position
const char LCDWrite(const char * c)
{
const char* bla = c;
while (*c)
LCDWriteChar(*c++);
return *bla;
}
// schreibt die übergebene Zeichenkette aus dem Programmspeicher
// an die aktuelle Cursor-Position
void LCDWritePGM(const char * c)
{
uint8_t b;
while ( (b = pgm_read_byte(c++)) )
LCDWriteChar(b);
}
und die Testroutine für die Arduino IDE
sketch.pde
#include <Libraries\m50530.cpp>
void setup()
{
Serial.begin(9600);
// wait for power up
delay(250);
// LCD initialisieren
LCDInit();
// Modus des LCDs ändern
LCDSetEntryMode( 80 | 64 );
// Cursor einschalten
LCDSetDisplayMode(dmDisplayOn | dmCursorOn | dmCursorBlink | dmCharacterBlink);
}
void loop()
{
//Konfiguration vor jedem Loop
LCDSend( 0, LCD_CMD_SETFUNCTIONMODE | sfIO4BIT | sfFont5x8 | 8 );
LCDSend( 0, LCD_CMD_SETENTRYMODE | emCursorIncWrite | emDisplayNoChange );
LCDSetDisplayMode(dmDisplayOn | dmCursorOn | dmCursorBlink | dmCharacterBlink);
//Text bei jedem Loop
LCDSetCursorPos(0,0);
LCDWrite((const char*)"LCD - 24x8 characters");
LCDSetCursorPos(5,0);
LCDWrite((const char*)"Samsung 2138a");
LCDSetCursorPos(4, 0);
LCDWrite((const char*)"test successful");
LCDSetCursorPos(7, 21);
LCDWrite((const char*)":-)");
delay(2);
digitalWrite(13, HIGH);
}