[RESOLU] LCD Samsung 0282A sur Arduino Mega

Bonjour à vous, je débute totalement dans l’univers Arduino et C, et je galére un peu à faire marcher un LCD Samsung 0282A basé sur un Chip M50530.

J’ai bien trouvé la librairie du M50530 qui a l’air de marcher sur un Arduino UNO, mais que je n’arrive pas à adapter au Arduino Mega, je pense que c’est une question de port qui ne sont pas les méme sur les deux cartes arduino cité, mais bon comme je débute vraiment je ne sais pas comment adapter le code pour que celui ci fonctionne sur le Atmega 2560, mon soucis viendrait donc de ce bout de code:

// 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

Mes questions sont donc comment brancher l’Afficheur LCD sur l’arduino Mega?, qu’elles sont les changements à effectuer dans le bout de code pour que celui ci soit compatible?, et comment avez vous fait pour les définir?

Vous remerciant par avance de vos éventuelles réponses.

Je vous joint:

le M50530.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

Le 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);
}

et le Test.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);
}

Et le Mappage d’un atmega168

et d’un atmega2560

Salut Salut, bon et bien comme on dit le nuit porte conseil, le probléme est résolus.

Dans le M50530.h j'ai donc changé les branchements sur la carte, et le PORTD qui est passé en PORTA (en vert):

// Data and Control signals can be connected to different ports!

// data port, LCD signals DB4 To Pin53, DB5 To Pin52, DB6 To Pin51, DB7 To Pin50

define LCDDATAPORT PORTB

define LCDDATADIR DDRB

define LCDDATAPIN PINB

// control port, LCD signals RW, EX, I/OC1, I/OC2

define LCDCTRLPORT PORTA

define LCDCTRLDIR DDRA

//#define LCDCTRLPIN PINA

define LCDPIN_RW 4 // To Pin26

define LCDPIN_IOC1 7 // To Pin29

define LCDPIN_IOC2 5 // To Pin27

define LCDPIN_EX 6 // To Pin28

Voili voilou.

Par contre est ce normal que la LED L sur la carte Arduino Mega ne scintille que trés peu contrairement au code que j'ai testé avec un autre afficheur LCD 4x20?

A+