cancel
Showing results for 
Search instead for 
Did you mean: 

LCD HD44780 interface problems with Nucleo board

dk.2
Associate II

Hello all members,

I am interfacing LCD module in 8bit mode to STM32F446RE Nucleo board the connections are as below:

0693W00000Lz4htQAB.pngThe pin connections(if unclear in diagram):

Control pins:

RS-->PB0

RW-->PB1

E-->PB3

8bit data pins LCD:

D0-D7-->PC0-PC7

Program Lcd.c:

 #include "lcd.h"
 
  #include <stdint.h>
 
  #include "delay.h"
 
 
 
  GPIO_Handle_t GPIOConfig;
 
  void lcd_init()
 
  {
 
   
 
  	/*
 
  	 *
 
  	 * Step1: Make Control pins and LCD 8pins as o/p
 
  	 * Step2: Initialising sequence as per datasheet
 
  	 */
 
  //Each of this function enable's clock and configures the pin to o/p mode 
 
  	LCDControlpins_init(GPIO_PIN_NO_0); 
 
  	LCDControlpins_init(GPIO_PIN_NO_1);
 
  	LCDControlpins_init(GPIO_PIN_NO_3);
 
 //Each of this function enable's clock and configures the pin to o/p mode for PC0-PC7 pins
 
  	for(int x=0;x<=7;x++)
 
  		LCDDatapins_init(x);
 
   
 
  	/*
 
  	 * Init sequence:
 
  	 * as per datasheet
 
  	 * 
 
  	 */
 
  	delay_ms(100);       // all delays are 3/more times the delay specified in 
 
                     datasheet
 
  	send_cmd(0x30);
 
  	delay_ms(7);
 
  	send_cmd(0x30);
 
  	delay_ms(7);
 
  	send_cmd(0x30);
 
  	delay_ms(7);
 
   
 
  	send_cmd(0x38);		// Sets no of lines= 2 and F font = 8*5 pixel type
 
  	delay_ms(7);
 
   
 
  	send_cmd(0x08);		//Sets D,C,B off (Display Cursor,Blink)
 
  	delay_ms(7);
 
   
 
  	send_cmd(0x01);		//clears the entire display
 
  	delay_ms(7);
 
   
 
  	send_cmd(0x07);	 //I/D=1,S=1 sets the increment of cursor from left to right and no shift 
 
              of the data.
 
  	delay_ms(7);
 
   
 
   
 
  }
 
   
 
  void LCDControlpins_init(uint8_t pinno)
 
  {
 
  	GPIOConfig.pGPIOx=GPIOB;
 
  	GPIOConfig.GPIO_PinConfig.GPIO_PinMode=GPIO_MODE_OUT;
 
  	GPIOConfig.GPIO_PinConfig.GPIO_PinOPType=GPIO_OP_TYPE_PP;
 
  	GPIOConfig.GPIO_PinConfig.GPIO_PinSpeed=GPIO_SPEED_LOW;
 
   
 
  	switch(pinno)
 
  	{
 
  		case 0:
 
  			GPIOConfig.GPIO_PinConfig.GPIO_PinNumber=GPIO_PIN_NO_0;
 
  			break;
 
  		case 1:
 
  			GPIOConfig.GPIO_PinConfig.GPIO_PinNumber=GPIO_PIN_NO_1;
 
  			break;
 
  		case 3:
 
  			GPIOConfig.GPIO_PinConfig.GPIO_PinNumber=GPIO_PIN_NO_3;
 
  			break;
 
  		default :
 
  			break;
 
  	}
 
  	GPIO_Init(&GPIOConfig);
 
  }
 
   
 
  void LCDDatapins_init(uint8_t pinno)
 
  {
 
  	GPIOConfig.pGPIOx=GPIOC;
 
  	GPIOConfig.GPIO_PinConfig.GPIO_PinMode=GPIO_MODE_OUT;
 
  	GPIOConfig.GPIO_PinConfig.GPIO_PinOPType=GPIO_OP_TYPE_PP;
 
  	GPIOConfig.GPIO_PinConfig.GPIO_PinSpeed=GPIO_SPEED_LOW;
 
  	GPIOConfig.GPIO_PinConfig.GPIO_PinNumber=pinno;
 
  	GPIO_Init(&GPIOConfig);
 
  }
 
   
 
  void send_cmd(unsigned char cmd)
 
  {
 
  	/*
 
  	 * RS=0,RW=0,EN=0
 
  	 */
 
  	GPIO_WriteToOutputPin(GPIOB, GPIO_PIN_NO_0, 0); //RS as Instruction
 
  	GPIO_WriteToOutputPin(GPIOB, GPIO_PIN_NO_1, 0); //RW
 
  	GPIO_WriteToOutputPin(GPIOB, GPIO_PIN_NO_3, 0); //E
 
  	delay_ms(5); //extra setup time
 
  	GPIO_WriteToOutputPort(GPIOC,(uint16_t)cmd);
 
  	delay_ms(5); //extra setup time
 
    //Make E pin High to Low with reasonable wait time (more than time specified in datasheet)
 
  	GPIO_WriteToOutputPin(GPIOB, GPIO_PIN_NO_3, 1); //E=high
 
  	delay_ms(2);
 
  	GPIO_WriteToOutputPin(GPIOB, GPIO_PIN_NO_3, 0); //E=low
 
  	delay_ms(2);
 
   
 
  }
 
   
 
  void send_data(unsigned char data)
 
  {
 
  	/*
 
  	 * Step1: Set function set 0x38 value
 
  	 * Step2: Set 0x0e value that is display and cursor on no blink
 
  	 * Step3: Set 0x06 that is increment by 1 and shift display
 
  	 * Step4: write data
 
  	 */
 
  	send_cmd(0x38);delay_ms(7);
 
  	send_cmd(0x0E);delay_ms(7);
 
  	send_cmd(0x06);delay_ms(7);
 
  	GPIO_WriteToOutputPin(GPIOB, GPIO_PIN_NO_0, 1); //RS as data
 
  	GPIO_WriteToOutputPin(GPIOB, GPIO_PIN_NO_1, 0); //RW as write
 
  	GPIO_WriteToOutputPin(GPIOB, GPIO_PIN_NO_3, 0); //E
 
  	delay_ms(5); //extra setup time
 
  	GPIO_WriteToOutputPort(GPIOC,(uint16_t)data);
 
  	delay_ms(5); //extra setup time
 
  	GPIO_WriteToOutputPin(GPIOB, GPIO_PIN_NO_3, 1); //E=high
 
  	delay_ms(2);
 
  	GPIO_WriteToOutputPin(GPIOB, GPIO_PIN_NO_3, 0); //E=low
 
  	delay_ms(2);
 
   
 
  }

Program lcd.h

  

#ifndef LCD_H_
 
  #define LCD_H_
 
  #include <stdint.h>
 
  #include "STM32fxx_gpio.h"
 
  void LCDControlpins_init(uint8_t);
 
  void LCDDatapins_init(uint8_t );
 
  void send_cmd(unsigned char );
 
  void send_data(unsigned char );
 
  void lcd_init(void);
 
  #define RS	0
 
  #define RW	1
 
  #define E	3
 
   
 
   
 
  #endif /* LCD_H_ */
 

The code for delay.c file using SYSTICK & polling method:

  #include "delay.h"
 
    typedef struct
 
    		{
 
    			uint32_t CSR;
 
    			uint32_t RVR;
 
    			uint32_t CVR;
 
    			uint32_t CALIB;
 
    		}SYST_t;
 
     
 
    SYST_t *SYSTick = (SYST_t*)0xE000E010;
 
     
 
    //Initialise systick timer
 
    void systickinit()
 
    {
 
    	SYSTick->CSR|=(1<<2); //take processor as clock source for timer
 
    }
 
     
 
    //delay function for 1us delay
 
    void delay_us(uint32_t blinktime)
 
    {
 
     
 
    	systickinit();
 
    	for(int i=0;i<blinktime;i++)
 
    	{
 
    	SYSTick->RVR = 16; //reload value for 1us
 
    	SYSTick->CSR|=(1<<0);//enable the timer countdown
 
    	while(!(SYSTick->CSR & (1<<16) )); //count down flag until set
 
    	//SYSTick->CSR &=~(1<<16); //reset the countdown flag
 
    	SYSTick->CSR&=~(1<<0); //disable the timer
 
     
 
    	}
 
    }
 
     
 
    void delay_ms(uint32_t blinktime)
 
    {
 
    		blinktime*=1000;
 
    			delay_us(blinktime);
 
    }
 
     
 
    void delay(uint32_t count)			//provides for loopdelyin ms
 
    {
 
    		int i,j;
 
    		count=count*1000;
 
    		for(i=0;i<count;i++)
 
    		for(j=0;j<16;j++);		//gives 1us delay
 
    }
 
   

delay.h file:

 #ifndef DELAY_H_
 
  #define DELAY_H_
 
  #include <stdint.h>
 
   
 
  void delay_us(uint32_t blinktime);
 
  void delay_ms(uint32_t blinktime);
 
  void delay(uint32_t count);
 
  void systickinit(void);
 
  typedef struct
 
  {
 
  	uint32_t CSR;
 
  	uint32_t RVR;
 
  	uint32_t CVR;
 
  	uint32_t CALIB;
 
  }SYST;
 
   
 
   
 
  #endif /* DELAY_H_ */
 
 
 

   

The main.c:

  #include "STM32fxx_gpio.h"
 
  #include "lcd.h"
 
  int main(void)
 
  {
 
  	lcd_init();
 
  	send_data('H');
 
  	send_data('E');
 
  	for(;;);
 
  }
 

The header file for gpio API's are in below github links: 

Header file for STM peripheral specific registers

https://github.com/niekiran/MasteringMCU/blob/master/Resources/Source_code/Workspace/stm32f4xx_drivers/drivers/inc/stm32f407xx.h

Header for GPIO file and GPIO functions .c files for GPIO clock and pin /port config functions:

https://github.com/niekiran/MasteringMCU/blob/master/Resources/Source_code/Workspace/stm32f4xx_drivers/drivers/src/stm32f407xx_gpio_driver.c

https://github.com/niekiran/MasteringMCU/blob/master/Resources/Source_code/Workspace/stm32f4xx_drivers/drivers/inc/stm32f407xx_gpio_driver.h

Dear members,

I have pasted all my codes.. The GPIO.h,.c files are 100percent working fine I have checked with other peripheral projects. The delay function also works correctly tested for led blink...

Now I am stuck in LCD program only..

My main aim is to just display 1 character I have gone through datasheet and forums and have taken everyones's suggestion accurately I still can't figure out what's wrong with my program..

I have tried this LCD board for arduino program it works there.

Also I have checked voltage specifications and all pin's connected are 5v Tolerant as per stm32 datasheet.

Please can someone figure out whta I may be doing wrong..

Your suggestions may help me..

I would be greateful..

10 REPLIES 10
Andrew Neil
Evangelist III

Do you have an oscilloscope or logic analyser to see what's actually happening on the wires?

Dear Andrew,

Thank you for your reply..

Unfortunately, I don't have an oscilloscope or logic analyzer..

That's going to make it very hard to debug, then!

Andrew Neil
Evangelist III

@dk.2​ "pin connections(if unclear in diagram)"

Yes, the diagram is unclear - please post a better (higher resolution and/or bigger) one.

Are you sure that none of those connections clashes with anything on the Nucleo board?

Dear Andrew,

I am sorry for the inconvenience..

I am using Nucleo board only for the LCD program now and nothing else is connected to the board..

I would have drawn the Image Instead I will mention the pinouts here

The exact pin connections are as follows:

LCD--->STM(nucleo)pins

VSS--->GND

VCC--->5V(arduino connector CN6)

VEE---->middle pin of pot of 10k & it's powered with 5V

RS------->PB0

RW------->PB1

E---------->PB3

DB0------->PC0

DB1-------->PC1

..

..

..

DB7---------->PC7

LED+-------->5V

LED- --------->330ohms resistor in series and connected to GND.

@dk.2​ "I am using Nucleo board only for the LCD program now and nothing else is connected to the board"

I meant, are you sure that there's nothing internal - on the Nucleo board itself - to interfere with your LCD connections?

dk.2
Associate II

How do I know if anything internally is connected I referred to pinouts in the below attached refrence manual from page 45 to page 56. I found no problem in using the pins I have used. Is there anything else I need to consider?

https://drive.google.com/file/d/1dnmLzKT0rNZPzQGTHeYhKHrsnxpciBTq/view?usp=sharing

dk.2
Associate II

Hi Andrew,

I checked the schematic..except for pin PA2,PA3 which are connected to ST-link circuitry I don't find any issue in using PC0-PC6 pins for LCD. Can you please verify if I have got it right. I checked the schematic in above links.