2022-04-26 06:31 AM
Hello all members,
I am interfacing LCD module in 8bit mode to STM32F446RE Nucleo board the connections are as below:
The 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
Header for GPIO file and GPIO functions .c files for GPIO clock and pin /port config functions:
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..
2022-04-26 06:41 AM
Do you have an oscilloscope or logic analyser to see what's actually happening on the wires?
2022-04-26 07:46 AM
Dear Andrew,
Thank you for your reply..
Unfortunately, I don't have an oscilloscope or logic analyzer..
2022-04-26 09:09 AM
That's going to make it very hard to debug, then!
2022-04-26 09:17 AM
@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?
2022-04-26 09:33 AM
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.
2022-04-26 11:05 AM
@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?
2022-04-27 06:13 AM
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
2022-04-27 06:34 AM
2022-04-28 08:08 AM
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.