EmbeddedRelated.com
Forums

EADOGM LCD interface with STM32

Started by cumin1091 November 13, 2012
Hello All,

I am undergraduate student. I want to interface LCD display EADOGM 16*2
with STM32 controller.
I am using 8 bit interface.
The connection is as below
RS-D7
RW-D8
E-D9
C0-C7 are connected to data lines of LCD.
I could find some display driver and i have modified according to my
requirement.
When i run this application, I could not see anything Displayed.
Can anyone pls suggest where am i wrong

ea-dogm-ex1.c     
 
#include "ea-dogm-ex1.h"
#include <stdio.h>
#define EADOGM162		1


// some special symbol chrs defined
#define EADMSYM_DEG     0b11011111     // degree symbol
#define EADMSYM_DARWL   0b11111011     // double <<
#define EADMSYM_DARWR   0b11111100     // double >>
#define EADMSYM_LT      0b00111100     // less than <
#define EADMSYM_GT      0b00111110     // greater than >
#define EADMSYM_OHM     0b00011110     // ohm symbol

// some command defines
#define EADMCMD_CONTRAST 0b0111000      // contrast command (0b0111xxxx)


// we noticed some issues with GLOBAL on pic24 devices
#ifndef GLOBAL
  #define GLOBAL INTR_GLOBAL
#endif




// 2x16
#ifdef EADOGM162
   #define EADOGM_ROWS 2
    #if EADOGMVDD == 5
     #define EADOGM_INIT_BIAS_SET 0x1C
     #define EADOGM_INIT_POWER_CONTROL 0x52
     #define EADOGM_INIT_FOLLOWER_CONTROL 0x69
     #define EADOGM_INIT_CONTRAST_SET 0x74
   #else
     #define EADOGM_INIT_BIAS_SET 0x14
     #define EADOGM_INIT_POWER_CONTROL 0x55
     #define EADOGM_INIT_FOLLOWER_CONTROL 0x6D
     #define EADOGM_INIT_CONTRAST_SET 0x78
   #endif

   #define EADOGM_INIT_FS1 0x39
   #define EADOGM_INIT_FS2 0x38
   #define EADOGM_INIT_CLEAR_DISPLAY 0x01
   #define EADOGM_INIT_ENTRY_MODE 0x06
   #define EADOGM_COLSPAN 40  // suggested that this be 40 on model 162
#endif




#define EADOGM_CMD_CLR 1
#define EADOGM_CMD_CURSOR_ON     0b00001111
#define EADOGM_CMD_CURSOR_OFF    0b00001100
#define EADOGM_CMD_DISPLAY_ON    0xC
#define EADOGM_CMD_DISPLAY_OFF   0b00001000
#define EADOGM_CMD_DDRAM_ADDR    0x80
#define EADOGM_CMD_CGRAM_ADDR    0x40
#define EADOGM_CMD_SELECT_R0     0b00011000
#define EADOGM_CMD_SELECT_R1     0b00010000
#define EADOGM_CMD_SET_TABLE2    0b00101010

void eaDogM_ini8Bit(void)
{
   DisplayOutputDrive(DISPLAY_E);
   DisplayOutputDrive(DISPLAY_RW);
   DisplayOutputDrive(DISPLAY_RS);
   DisplayOutputLow(DISPLAY_E);
   DisplayOutputLow(DISPLAY_RS);
   DisplayOutputLow(DISPLAY_RW);
}


void eaDogM_WriteChr(char value)
{
   DisplayOutputHigh(DISPLAY_RS);
   DisplayOutputLow(DISPLAY_RW);
   DisplayOutputLow(DISPLAY_E);
  
   DisplayOutputHigh(DISPLAY_E);
   Delay(1);
   DisplayOutputDrive(value);
  
   DisplayOutputLow(DISPLAY_E);
   Delay(1);
}

void eaDogM_WriteCommand(uint8_t cmd)
{
   DisplayOutputLow(DISPLAY_RS);
   DisplayOutputLow(DISPLAY_RW);
   DisplayOutputLow(DISPLAY_E);
//   #ifndef EADOGM_NOCSB
////     DisplayOutputLow(EADOGM_PIN_CSB);
//     #endif
   DisplayOutputHigh(DISPLAY_E);
   Delay(1);
//   EADOGM_8BIT_PORT(cmd);
   DisplayOutputLow(DISPLAY_E);
   Delay(1);
//   #ifndef EADOGM_NOCSB
//     DisplayOutputLow(EADOGM_PIN_CSB);
//     #endif
//   Delay(1);
}

//// spi mode
//void eaDogM_WriteChr(char value)
//{
//   DisplayOutputHigh(EADOGM_PIN_RS);
//   DisplayOutputLow(EADOGM_PIN_CSB);
//   eaDogM_outSPI(value);
//   DisplayOutputHigh(EADOGM_PIN_CSB);
//   Delay(1);
//}
//
//void eaDogM_WriteCommand(uint8_t cmd)
//{
//   DisplayOutputLow(DISPLAY_RS);
//   DisplayOutputLow(EADOGM_PIN_CSB);
//   eaDogM_outSPI(cmd);
//   DisplayOutputHigh(EADOGM_PIN_CSB);
//   Delay(1);
//}



void eaDogM_Initialize(void)
{



   eaDogM_ini8Bit();
//#else
//   DisplayOutputDrive(EADOGM_PIN_CSB);
//   DisplayOutputDrive(DISPLAY_RS);
//   DisplayOutputHigh(EADOGM_PIN_CSB);
//   DisplayOutputHigh(DISPLAY_RS);


   Delay(200);

   eaDogM_WriteCommand(EADOGM_INIT_FS1);
   eaDogM_WriteCommand(EADOGM_INIT_BIAS_SET);
   eaDogM_WriteCommand(EADOGM_INIT_POWER_CONTROL);
   eaDogM_WriteCommand(EADOGM_INIT_FOLLOWER_CONTROL);
   eaDogM_WriteCommand(EADOGM_INIT_CONTRAST_SET);
   eaDogM_WriteCommand(EADOGM_INIT_FS2);
   eaDogM_WriteCommand(EADOGM_INIT_CLEAR_DISPLAY);
   eaDogM_WriteCommand(EADOGM_INIT_ENTRY_MODE);
}



// v2.01 moved functions to macros
#define eaDogM_DoubleHeightOff() eaDogM_WriteCommand(0b00101000)
#define eaDogM_Cls()             eaDogM_WriteCommand(EADOGM_CMD_CLR)
#define eaDogM_CursorOn()        eaDogM_WriteCommand(EADOGM_CMD_CURSOR_ON)
#define eaDogM_CursorOff()      
eaDogM_WriteCommand(EADOGM_CMD_CURSOR_OFF)
#define eaDogM_DisplayOff()     
eaDogM_WriteCommand(EADOGM_CMD_DISPLAY_OFF)

void eaDogM_DisplayOn()
{
eaDogM_WriteCommand(EADOGM_CMD_DISPLAY_ON);
}

void eaDogM_SetPos(uint8_t r, uint8_t c)
{
   uint8_t cmdPos;
   cmdPos = EADOGM_CMD_DDRAM_ADDR + (r * EADOGM_COLSPAN) + c;
   eaDogM_WriteCommand(cmdPos);
}

void eaDogM_ClearRow(uint8_t r)
{
   uint8_t i;
   eaDogM_SetPos(r,0);
   for(i=0; i<EADOGM_COLSPAN; i++) {
     eaDogM_WriteChr(' ');
   }
}

void eaDogM_WriteString(char strPtr)
{
	  
  eaDogM_WriteChr(strPtr);
  
}



void eaDogM_WriteIntAtPos(uint8_t r, uint8_t c, uint8_t i)
{
  
   eaDogM_WriteCommand((EADOGM_CMD_DDRAM_ADDR + (r * EADOGM_COLSPAN) +
c));

   eaDogM_WriteChr(i/10+'0');
   eaDogM_WriteChr(i%10+'0');

}

// this writes a byte to the internal CGRAM (v2.02)
// format for ndx: 00CCCRRR = CCC = character 0 to 7, RRR = row 0 to 7
void eaDogM_WriteByteToCGRAM(char ndx, char data)
{
   unsigned int cmd;

   cmd = ndx & 0x3f; // mask off upper to bits
   cmd = cmd | EADOGM_CMD_CGRAM_ADDR; // set bit cmd bits

   eaDogM_WriteCommand(cmd);
   eaDogM_WriteChr(data);

   // this is done to make sure we are back in data mode
   eaDogM_SetPos(0,0);
}


//#endif


static void Delay(int nCount)
{
  int index = 0; 
  for(index = (100 * nCount); index != 0; index--)
  {
  }
}

void DisplayOutputHigh(uint16_t LCDRegValue)
{
 GPIO_WriteBit(GPIOD, LCDRegValue, (BitAction)1);

}

void DisplayOutputLow(uint16_t LCDRegValue)
{
	GPIO_WriteBit(GPIOD, LCDRegValue,(BitAction)0);
	
}

void DisplayOutputDrive(uint8_t data)
 {
	 GPIO_Write(GPIOC, data);
	 
 }







ea-dogm-ex1.h


#define EADOGM163       1        // to use MODEL EADOG163
#define EADOGMVDD       5        // 5v LCD Vdd



#define EADOGM162 					1
#define DISPLAY_ROWS			 	2
#define DISPLAY_VDD 				3.3

#define DISPLAY_GPIO_PORT				GPIOD
#define DISPLAY_E 		 					     GPIO_PinSource9				
#define DISPLAY_RS 							GPIO_PinSource7	
#define DISPLAY_RW 							GPIO_PinSource8		



#define DISPLAY_INIT_BIAS_SET			0x14
#define DISPLAY_INIT_POWER_CONTROL		0x55
#define DISPLAY_INIT_FOLLOWER_CONTROL 	0x6D
#define DISPLAY_INIT_FUNCTION_SET1		0x39
#define DISPLAY_INIT_FUNCTION_SET2		0x38
#define DISPLAY_INIT_CONTRAST_SET		0x78
#define DISPLAY_INIT_CLEAR_DISPLAY		0x01
#define DISPLAY_INIT_ENTRY_MODE			0x06

#define DISPLAY_CMD_CONTRAST_SET	0x70
#define DISPLAY_CMD_DISPLAY_ON	  0xC0
#define DISPLAY_CMD_DISPLAY_OFF		0B00001000
#define DISPLAY_CMD_CLR				1
#define DISPLAY_CMD_CURSOR_ON		0xF //Check the value
#define DISPLAY_CMD_CURSOR_OFF		0B00001100
#define DISPLAY_CMD_DDRAM_ADD		0x80
#define DISPLAY_START_LINE1_ADD		0x00
#define DISPLAY_START_LINE2_ADD		0x40

#define DISPLAY_SYM_DEG				0B11011111
#define DISPLAY_SYM_SLASH			0B00101111
#define DISPLAY_SYM_LEFT_PARAN		0B10000010
#define DISPLAY_SYM_RIGHT_PARAN		0B10010010
#define DISPLAY_SYM_MUL				0B01111111
#define DISPLAY_SYM_DOT				0B00000100


#define INPUT_POWER_ON			00
#define INPUT_TEMPERATURE		01
#define INPUT_GENERAL			02
#define START_UP_SCREEN 		03
#define MEASUREMENT_SCREEN 		04
#define GENERAL_SCREEN 			05

#define READ_BUSY_FLAG			0
#define READ_DATA_FROM_LCD		1

void eaDogM_Initialize(void);
void eaDogM_DisplayOn(void);							
void eaDogM_WriteChr(char value);
void eaDogM_WriteIntAtPos(uint8_t r, uint8_t c, uint8_t i);	
void eaDogM_DisplayOn(void);  
void eaDogM_WriteString(char strPtr);  
void eaDogM_ClearRow(uint8_t r)	;
 





Thanks

	   
					
---------------------------------------		
Posted through http://www.EmbeddedRelated.com
On Tue, 13 Nov 2012 09:24:45 -0600, "cumin1091" <29963@embeddedrelated>
wrote:

>Hello All, > >I am undergraduate student. I want to interface LCD display EADOGM 16*2 >with STM32 controller. >I am using 8 bit interface. >The connection is as below >RS-D7 >RW-D8 >E-D9 >C0-C7 are connected to data lines of LCD. >I could find some display driver and i have modified according to my >requirement. >When i run this application, I could not see anything Displayed. >Can anyone pls suggest where am i wrong
I've coded to the EA DOG displays with an STM32F103 controller so I know that it's (unsurprisingly) do-able. Proper initialization is where getting character LCD displays up and running usually runs into difficulties. I'd recommend starting with your own code, rather than trying to adapt someone else's boilerplate. The EADOG datasheet together with the controller's datasheet should have enough pseudocode and command sequences. <http://www.lcd-module.de/eng/pdf/zubehoer/st7036.pdf> I notice, for example, that you have both #define EADOGMVDD 5 // 5v LCD Vdd and #define DISPLAY_VDD 3.3 defined. Which is correct? The EADOG's controller wants > 40 msec after Vdd is stable on a 3.3 V system and 15 msec for a 5 V. I'd check that first. Are you sure your Delay() function isn't getting optimized out? -- Rich Webb Norfolk, VA
Thanks for the reply

I have not set any optimization level, currently its 0.
And I am using 3.3 Volts.
i have written my own code as suggested.
And I am following the Pseudocode in ST datasheet for initilazation.

But still i could not find any difference.
And my delay is gretaer than 40 msec.





>On Tue, 13 Nov 2012 09:24:45 -0600, "cumin1091" <29963@embeddedrelated> >wrote: > >>Hello All, >> >>I am undergraduate student. I want to interface LCD display EADOGM 16*2 >>with STM32 controller. >>I am using 8 bit interface. >>The connection is as below >>RS-D7 >>RW-D8 >>E-D9 >>C0-C7 are connected to data lines of LCD. >>I could find some display driver and i have modified according to my >>requirement. >>When i run this application, I could not see anything Displayed. >>Can anyone pls suggest where am i wrong > >I've coded to the EA DOG displays with an STM32F103 controller so I know >that it's (unsurprisingly) do-able. > >Proper initialization is where getting character LCD displays up and >running usually runs into difficulties. > >I'd recommend starting with your own code, rather than trying to adapt >someone else's boilerplate. The EADOG datasheet together with the >controller's datasheet should have enough pseudocode and command >sequences. <http://www.lcd-module.de/eng/pdf/zubehoer/st7036.pdf> > >I notice, for example, that you have both > >#define EADOGMVDD 5 // 5v LCD Vdd > >and > >#define DISPLAY_VDD 3.3 > >defined. Which is correct? The EADOG's controller wants > 40 msec after >Vdd is stable on a 3.3 V system and 15 msec for a 5 V. I'd check that >first. Are you sure your Delay() function isn't getting optimized out? > >-- >Rich Webb Norfolk, VA >
--------------------------------------- Posted through http://www.EmbeddedRelated.com
On 2012-11-15, cumin1091 <29963@embeddedrelated> wrote:
> > Thanks for the reply > > I have not set any optimization level, currently its 0.
That's nowhere near good enough. The only way to be sure is to look at the generated code and make sure the statements in Delay() are present and are in the code path (either as a call to Delay() or placed inline by the compiler). If Delay() is been removed (and not replaced with inline code) then try making the loop counter volatile.
> And I am using 3.3 Volts. > i have written my own code as suggested. > And I am following the Pseudocode in ST datasheet for initilazation. > > But still i could not find any difference. > And my delay is gretaer than 40 msec. >
You don't know that until after you have looked at the generated code and estimated how many clock cycles each pass through the delay loop will take. Simon. -- Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP Microsoft: Bringing you 1980s technology to a 21st century world
On Thu, 15 Nov 2012 12:34:16 +0000 (UTC), Simon Clubley
<clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:

>On 2012-11-15, cumin1091 <29963@embeddedrelated> wrote: >> >> Thanks for the reply >> >> I have not set any optimization level, currently its 0. > >That's nowhere near good enough. > >The only way to be sure is to look at the generated code and make sure >the statements in Delay() are present and are in the code path (either >as a call to Delay() or placed inline by the compiler). > >If Delay() is been removed (and not replaced with inline code) then try >making the loop counter volatile. > >> And I am using 3.3 Volts. >> i have written my own code as suggested. >> And I am following the Pseudocode in ST datasheet for initilazation. >> >> But still i could not find any difference. >> And my delay is gretaer than 40 msec. >> > >You don't know that until after you have looked at the generated code >and estimated how many clock cycles each pass through the delay loop >will take.
Even then, I wouldn't (and don't, in my own work) believe it until I've seen the results on a scope or logic analyzer. In addition to the initial delay, there are (as I'm sure you know, this is for the OP) constraints on setup and hold times, and on minimum pulse widths. A recommended approach is to write and verify the initialization routine from the ST7036 flowchart one step at a time, making sure that all of the timing and instruction sequencing is good at each step. -- Rich Webb Norfolk, VA
In article <k82ng8$k1l$1@dont-email.me>, 
clubley@remove_me.eisner.decus.org-Earth.UFP says...
> > On 2012-11-15, cumin1091 <29963@embeddedrelated> wrote: > > > > Thanks for the reply > > > > I have not set any optimization level, currently its 0. > > That's nowhere near good enough. > > The only way to be sure is to look at the generated code and make sure > the statements in Delay() are present and are in the code path (either > as a call to Delay() or placed inline by the compiler). > > If Delay() is been removed (and not replaced with inline code) then try > making the loop counter volatile. > > > And I am using 3.3 Volts. > > i have written my own code as suggested. > > And I am following the Pseudocode in ST datasheet for initilazation. > > > > But still i could not find any difference. > > And my delay is gretaer than 40 msec. > > > > You don't know that until after you have looked at the generated code > and estimated how many clock cycles each pass through the delay loop > will take. >
This is the kind of problem that begs for the use of a few test output bits and an oscilloscope. IIRC, you can find USB scopes that display on your PC for under $200. Until you can put a probe on various signal lines to the LCD, you don't really know if you've forgotten to turn on the clock to one of the peripheral ports. I've had problems of that nature on the STM32 quite often. I'll cut and paste code for a peripheral, but forget to change one of the clock or port assignments. Mark Borgerson