cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 Discovery HD44780 4bit mode

gamersat678
Associate II
Posted on June 16, 2012 at 22:38

Can't seem to get any text output using the 4 bit mode of the chip (managed to get 8bit mode). Tried following the HD44780/SPLC780D datasheets to no avail. Here's my code. Hope someone can help as I've been struggling for a couple days now.

//main.c
#include ''stm32f4xx.h''
#include ''board.h''
int
main(
void
)
{
SystemInit();
LCD_Initialize();
while
(1){};
return
0;
}
//hdd447c
#include ''stm32f4xx.h''
#include ''board.h''
GPIO_InitTypeDef GPIO_InitStructure;
void
Delaynus(vu32 nus)
{
u8 nCount;
while
(nus--)
{
for
(nCount = 6; nCount != 0; nCount--);
}
}
void
delayms ( 
int
ms ) {
int
i = 4000 * ms;
Delaynus(i);
}
void
LCD_WriteNibble(u8 nibbleToWrite)
{
GPIO_WriteBit(LCD_GPIO, LCD_EN, Bit_SET);
GPIO_WriteBit(GPIOA, LCD_D4, (nibbleToWrite & 0x01));
GPIO_WriteBit(GPIOA, LCD_D5, (nibbleToWrite & 0x02));
GPIO_WriteBit(GPIOA, LCD_D6, (nibbleToWrite & 0x04));
GPIO_WriteBit(GPIOA, LCD_D7, (nibbleToWrite & 0x08));
GPIO_WriteBit(LCD_GPIO, LCD_EN, Bit_RESET);
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
u8 LCD_ReadNibble(
void
)
{
u8 tmp = 0;
GPIO_WriteBit(LCD_GPIO, LCD_EN, Bit_SET);
tmp |= (GPIO_ReadInputDataBit(GPIOA, LCD_D4) << 0);
tmp |= (GPIO_ReadInputDataBit(GPIOA, LCD_D5) << 1);
tmp |= (GPIO_ReadInputDataBit(GPIOA, LCD_D6) << 2);
tmp |= (GPIO_ReadInputDataBit(GPIOA, LCD_D7) << 3);
GPIO_WriteBit(LCD_GPIO, LCD_EN, Bit_RESET);
return
tmp;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
u8 LCD_ReadStatus(
void
)
{
u8 status = 0;
GPIO_InitStructure.GPIO_Pin = LCD_D4 | LCD_D5 | LCD_D6 | LCD_D7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_WriteBit(LCD_GPIO, LCD_RW, Bit_SET);
GPIO_WriteBit(LCD_GPIO, LCD_RS, Bit_RESET);
status |= (LCD_ReadNibble() << 4);
status |= LCD_ReadNibble();
GPIO_InitStructure.GPIO_Pin = LCD_D4 | LCD_D5 | LCD_D6 | LCD_D7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
return
status;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void
LCD_WriteData(u8 dataToWrite)
{
GPIO_WriteBit(LCD_GPIO, LCD_RW, Bit_RESET);
GPIO_WriteBit(LCD_GPIO, LCD_RS, Bit_SET);
LCD_WriteNibble(dataToWrite >> 4);
delayms(1);
LCD_WriteNibble(dataToWrite & 0x0F);
delayms(1);
//while(LCD_ReadStatus() & 0x80);
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void
LCD_WriteCommand(u8 commandToWrite)
{
GPIO_WriteBit(LCD_GPIO, LCD_RW | LCD_RS, Bit_RESET);
LCD_WriteNibble(commandToWrite >> 4); 
//Shift Right
delayms(5);
LCD_WriteNibble(commandToWrite & 0x0F);
delayms(5);
//while(LCD_ReadStatus() & 0x80);
}
void
LCD_WriteCom(u8 commandToWrite)
{
GPIO_WriteBit(LCD_GPIO, LCD_RW | LCD_RS, Bit_RESET);
LCD_WriteNibble(commandToWrite >> 4); 
//Shift Right
delayms(5);
}
void
LCD_Initialize(
void
)
{
vu8 i = 0;
vu32 delayCnt = 0;
GPIO_InitTypeDef io_init;
/* enable peripheral clock for pa and pc */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
/* settings for both pa and pc */
io_init.GPIO_Mode = GPIO_Mode_OUT;
io_init.GPIO_OType = GPIO_OType_PP;
io_init.GPIO_Speed = GPIO_Speed_100MHz;
io_init.GPIO_PuPd = GPIO_PuPd_NOPULL;
/* init pa */
io_init.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_Init(GPIOA, &io_init);
/* init pc */
io_init.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2;
GPIO_Init(GPIOC, &io_init);
delayms(20);
LCD_WriteCom(0x30); 
//Reset the chip
delayms(5);
LCD_WriteCom(0x30);
Delaynus(200);
LCD_WriteCom(0x30);
Delaynus(200);
LCD_WriteCom(0x20);
//Set 4bit operation
delayms(5);
LCD_WriteCommand(0x20);
LCD_WriteCommand(0xE);
LCD_WriteCommand(0x06);
LCD_WriteData(0x57); 
//Write a W
}
//board.h
#define LCD_GPIO GPIOA
#define LCD_D4 GPIO_Pin_4
#define LCD_D5 GPIO_Pin_5
#define LCD_D6 GPIO_Pin_6
#define LCD_D7 GPIO_Pin_7
#define LCD_RS GPIO_Pin_2
#define LCD_RW GPIO_Pin_1
#define LCD_EN GPIO_Pin_0

3 REPLIES 3
gamersat678
Associate II
Posted on June 27, 2012 at 04:51

So figured it all out. Have to be careful about resetting your pins to 0 before you init the module. Also V0 likes to be around 1v (it floats high), so a 1k resistor to ground should do it. Make sure your clock is correctly configured (used IO_Toggle as base for this program). You can find the original here http://www.elektroda.pl/rtvforum/topic2265html

Here's another copy of it in case the original forum post decides to disappear.

//hd447c
//***************** (c) 2010 BTC Korporacja ***********************************
// http://www kamami.com
//
// THE SOFTWARE INCLUDED IN THIS FILE IS FOR GUIDANCE ONLY.
// BTC KORPORACJA SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT
// OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
// FROM USE OF THIS SOFTWARE.
//
//******************************************************************************
#include ''hd447h''
#include ''stm32f4xx.h''
#include <stdio.h>
#include <stdarg.h>
#define LCD_GPIO GPIOE
#define LCD_D4 GPIO_Pin_10
#define LCD_D5 GPIO_Pin_11
#define LCD_D6 GPIO_Pin_12
#define LCD_D7 GPIO_Pin_13
#define LCD_RS GPIO_Pin_7
#define LCD_RW GPIO_Pin_8
#define LCD_EN GPIO_Pin_9
extern
GPIO_InitTypeDef GPIO_InitStructure;
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void
LCD_WriteNibble(u8 nibbleToWrite)
{
GPIO_WriteBit(LCD_GPIO, LCD_EN, Bit_SET);
GPIO_WriteBit(LCD_GPIO, LCD_D4, (nibbleToWrite & 0x01));
GPIO_WriteBit(LCD_GPIO, LCD_D5, (nibbleToWrite & 0x02));
GPIO_WriteBit(LCD_GPIO, LCD_D6, (nibbleToWrite & 0x04));
GPIO_WriteBit(LCD_GPIO, LCD_D7, (nibbleToWrite & 0x08));
GPIO_WriteBit(LCD_GPIO, LCD_EN, Bit_RESET);
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
u8 LCD_ReadNibble(
void
)
{
u8 tmp = 0;
GPIO_WriteBit(LCD_GPIO, LCD_EN, Bit_SET);
tmp |= (GPIO_ReadInputDataBit(LCD_GPIO, LCD_D4) << 0);
tmp |= (GPIO_ReadInputDataBit(LCD_GPIO, LCD_D5) << 1);
tmp |= (GPIO_ReadInputDataBit(LCD_GPIO, LCD_D6) << 2);
tmp |= (GPIO_ReadInputDataBit(LCD_GPIO, LCD_D7) << 3);
GPIO_WriteBit(LCD_GPIO, LCD_EN, Bit_RESET);
return
tmp;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
u8 LCD_ReadStatus(
void
)
{
u8 status = 0;
GPIO_InitStructure.GPIO_Pin = LCD_D4 | LCD_D5 | LCD_D6 | LCD_D7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_Init(LCD_GPIO, &GPIO_InitStructure);
GPIO_WriteBit(LCD_GPIO, LCD_RW, Bit_SET);
GPIO_WriteBit(LCD_GPIO, LCD_RS, Bit_RESET);
status |= (LCD_ReadNibble() << 4);
status |= LCD_ReadNibble();
GPIO_InitStructure.GPIO_Pin = LCD_D4 | LCD_D5 | LCD_D6 | LCD_D7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_Init(LCD_GPIO, &GPIO_InitStructure);
return
status;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void
LCD_WriteData(u8 dataToWrite)
{
GPIO_WriteBit(LCD_GPIO, LCD_RW, Bit_RESET);
GPIO_WriteBit(LCD_GPIO, LCD_RS, Bit_SET);
LCD_WriteNibble(dataToWrite >> 4);
LCD_WriteNibble(dataToWrite & 0x0F);
while
(LCD_ReadStatus() & 0x80);
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void
LCD_WriteCommand(u8 commandToWrite)
{
GPIO_WriteBit(LCD_GPIO, LCD_RW | LCD_RS, Bit_RESET);
LCD_WriteNibble(commandToWrite >> 4);
LCD_WriteNibble(commandToWrite & 0x0F);
while
(LCD_ReadStatus() & 0x80);
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void
LCD_DefineCharacter(
char
index, 
char
* pattern)
{
char
i ;
LCD_WriteCommand(HD44780_CGRAM_SET + (8 * index));
for
(i = 0; i < 8; i++)
LCD_WriteData(*(pattern + i));
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void
LCD_WriteText(
char
* text)
{
while
((*text !=0) && (*text != 13))
LCD_WriteData(*text++);
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void
LCD_GoTo(unsigned 
char
x, unsigned 
char
y)
{
LCD_WriteCommand(HD44780_DDRAM_SET | (x + (0x40 * y)));
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void
LCD_WriteTextXY(
char
* text, u8 x, u8 y)
{
LCD_GoTo(x,y);
LCD_WriteText(text);
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void
LCD_Clear(
void
)
{
LCD_WriteCommand(HD44780_CLEAR);
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void
LCD_WriteBinary(u32 var, u8 bitCount)
{
s8 i;
for
(i = (bitCount - 1); i >= 0; i--)
{
LCD_WriteData((var & (1 << i))?
'1'
:
'0'
);
}
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void
LCD_ShiftLeft(
void
)
{
LCD_WriteCommand(HD44780_DISPLAY_CURSOR_SHIFT | HD44780_SHIFT_LEFT | HD44780_SHIFT_DISPLAY);
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void
LCD_ShiftRight(
void
)
{
LCD_WriteCommand(HD44780_DISPLAY_CURSOR_SHIFT | HD44780_SHIFT_RIGHT | HD44780_SHIFT_DISPLAY);
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void
LCD_Initialize(
void
)
{
vu8 i = 0;
vu32 delayCnt = 0;
GPIO_InitStructure.GPIO_Pin=LCD_D4 | LCD_D5 | LCD_D6 | LCD_D7 | LCD_RS | LCD_RW | LCD_EN;
GPIO_InitStructure.GPIO_OType= GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
GPIO_InitStructure.GPIO_PuPd= GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_Init (LCD_GPIO, & GPIO_InitStructure);
GPIO_Write (LCD_GPIO,0);
GPIO_ResetBits(LCD_GPIO, LCD_RS | LCD_EN | LCD_RW);
for
(delayCnt = 0; delayCnt < 300000; delayCnt++);
for
(i = 0; i < 3; i++) 
{
LCD_WriteNibble(0x03); 
for
(delayCnt = 0;delayCnt < 30000; delayCnt++);
}
LCD_WriteNibble(0x02); 
for
(delayCnt = 0;delayCnt < 6000; delayCnt++);
LCD_WriteCommand(HD44780_FUNCTION_SET | 
HD44780_FONT5x7 | 
HD44780_TWO_LINE | 
HD44780_4_BIT);
LCD_WriteCommand(HD44780_DISPLAY_ONOFF | 
HD44780_DISPLAY_OFF); 
LCD_WriteCommand(HD44780_CLEAR); 
LCD_WriteCommand(HD44780_ENTRY_MODE | 
HD44780_EM_SHIFT_CURSOR | 
HD44780_EM_INCREMENT);
LCD_WriteCommand(HD44780_DISPLAY_ONOFF | 
HD44780_DISPLAY_ON |
HD44780_CURSOR_OFF | 
HD44780_CURSOR_NOBLINK);
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
//
//hd447h
#include ''stm32f4xx.h''
#define HD44780_CLEAR 0x01
#define HD44780_HOME 0x02
#define HD44780_ENTRY_MODE 0x04
#define HD44780_EM_SHIFT_CURSOR 0
#define HD44780_EM_SHIFT_DISPLAY 1
#define HD44780_EM_DECREMENT 0
#define HD44780_EM_INCREMENT 2
#define HD44780_DISPLAY_ONOFF 0x08
#define HD44780_DISPLAY_OFF 0
#define HD44780_DISPLAY_ON 4
#define HD44780_CURSOR_OFF 0
#define HD44780_CURSOR_ON 2
#define HD44780_CURSOR_NOBLINK 0
#define HD44780_CURSOR_BLINK 1
#define HD44780_DISPLAY_CURSOR_SHIFT 0x10
#define HD44780_SHIFT_CURSOR 0
#define HD44780_SHIFT_DISPLAY 8
#define HD44780_SHIFT_LEFT 0
#define HD44780_SHIFT_RIGHT 4
#define HD44780_FUNCTION_SET 0x20
#define HD44780_FONT5x7 0
#define HD44780_FONT5x10 4
#define HD44780_ONE_LINE 0
#define HD44780_TWO_LINE 8
#define HD44780_4_BIT 0
#define HD44780_8_BIT 16
#define HD44780_CGRAM_SET 0x40
#define HD44780_DDRAM_SET 0x80
void
LCD_Initialize(
void
);
void
LCD_WriteData(u8);
void
LCD_WriteText(
char
*);
void
LCD_WriteTextXY(
char
* , u8 , u8);
void
LCD_GoTo(unsigned 
char
, unsigned 
char
);
void
LCD_WriteBinary(u32 var, u8 bitCount);
//main.c
#include ''stm32f4_discovery.h''
#include ''stm32f4xx.h''
#include ''hd447h''
GPIO_InitTypeDef GPIO_InitStructure;
int
main (
void
){
NVIC_SetVectorTable (NVIC_VectTab_FLASH, 0x0);
RCC_AHB1PeriphClockCmd (RCC_AHB1Periph_GPIOE, ENABLE);
LCD_Initialize ();
//LCD_GoTo (0,0);
LCD_WriteText (
''work?''
);
while
(1){
Delaynus(3000);
LCD_WriteText (
''work?''
);
}
}

fjohnnn
Associate
Posted on March 17, 2014 at 22:57

Hi, i'm trying to use your code and am having troubles displaying anything. I need your help.

do you have skype? or facebook? or phone number? any means i can contact you.

thanks

lee2
Associate II
Posted on April 06, 2014 at 23:20

Hi mfinanga.frederick,

if your still having trouble i've written a guide to getting the HD44780 display working with the STM32F4Discovery on tecsploit http://tecsploit.com/stm32f4-discovery/controling-an-lcd-screen-hd44780u00a/

hope it helps!