Skip to main content
gamersat678
Associate
June 16, 2012
Question

STM32F4 Discovery HD44780 4bit mode

  • June 16, 2012
  • 3 replies
  • 971 views
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

    This topic has been closed for replies.

    3 replies

    gamersat678
    Associate
    June 27, 2012
    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
    Visitor II
    March 17, 2014
    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
    Visitor II
    April 6, 2014
    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!