AnsweredAssumed Answered

STM32F4 Discovery HD44780 4bit mode

Question asked by gamersat678 on Jun 16, 2012
Latest reply on Apr 6, 2014 by dyche.lee
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;
}
//hdd44780.c
#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

Outcomes