Question
STM32F4 Discovery HD44780 4bit mode
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