LCD can be a very useful part in any microcontroller based project. It helps to monitor variables and program status with simple texts or numbers.
For this application I used a JHD 162 A alphanumeric LCD, like the picture above.
It hast 16 pins specified like this
VEE is used for contrast, so attache it to a potentiometer and choose your best contrast. Or simply plug it to 5V if you need maximum contrast.
D0, D1, D2, D3 are grounded
I managed to find a library for STM32VL, so I needed to bring some changes to it before it works. This library works both for JHD 162A and the hd44780.
lcd_hd44780.h
lcd_hd44780.c
main.c
Update:
lcd_hd44780.h
//******************************************************************************
// THE SOFTWARE INCLUDED IN THIS FILE IS FOR GUIDANCE ONLY.
// AUTHOR SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT
// OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
// FROM USE OF THIS SOFTWARE.
//******************************************************************************
//##############################################################################
// lcd_hd44780.h
//##############################################################################
//****************************************************************************//
#include "main.h"
#define LCD_GPIO GPIOD
#define LCD_CLK_LINE RCC_AHB1Periph_GPIOD
#define LCD_D4 GPIO_Pin_1
#define LCD_D5 GPIO_Pin_3
#define LCD_D6 GPIO_Pin_5
#define LCD_D7 GPIO_Pin_7
#define LCD_RS GPIO_Pin_0
#define LCD_RW GPIO_Pin_2
#define LCD_EN GPIO_Pin_4
//******************************************************************************//
#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_init(void);
void lcd_cls(void);
void lcd_str(unsigned char * text);
void lcd_strxy(unsigned char * text, unsigned char x, unsigned char y);
void lcd_locate(unsigned char x, unsigned char y);
void lcd_int(int n);
void lcd_intxy(int n, unsigned char x, unsigned char y);
//###############################################################
void lcd_writedata(unsigned char dataToWrite);
void lcd_writecommand(unsigned char commandToWrite);
void lcd_writebinary(unsigned int var, unsigned char bitCount);
void lcd_addchar (unsigned char chrNum, unsigned char n, const unsigned char *p);
lcd_hd44780.c
#include "lcd_hd44780.h"
#include "stm32f4xx_gpio.h"
#include
#include
#include
#include "stm32f4_discovery.h"
GPIO_InitTypeDef GPIO_InitStructure;
//-----------------------------------------------------------------------------
void lcd_writenibble(unsigned char nibbleToWrite)
{
GPIO_WriteBit(LCD_GPIO, LCD_EN, Bit_SET);
GPIO_WriteBit(LCD_GPIO, LCD_D4,(BitAction) (nibbleToWrite & 0x01));
GPIO_WriteBit(LCD_GPIO, LCD_D5,(BitAction)(nibbleToWrite & 0x02));
GPIO_WriteBit(LCD_GPIO, LCD_D6,(BitAction)(nibbleToWrite & 0x04));
GPIO_WriteBit(LCD_GPIO, LCD_D7,(BitAction)(nibbleToWrite & 0x08));
GPIO_WriteBit(LCD_GPIO, LCD_EN, Bit_RESET);
}
//-----------------------------------------------------------------------------
unsigned char LCD_ReadNibble(void)
{
unsigned char 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;
}
//-----------------------------------------------------------------------------
unsigned char LCD_ReadStatus(void)
{
unsigned char status = 0;
GPIO_InitStructure.GPIO_Pin = LCD_D4 | LCD_D5 | LCD_D6 | LCD_D7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
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_Init(LCD_GPIO, &GPIO_InitStructure);
return status;
}
//-----------------------------------------------------------------------------
void lcd_writedata(unsigned char 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(unsigned char 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_str(unsigned char * text)
{
while(*text)
lcd_writedata(*text++);
}
//-----------------------------------------------------------------------------
void lcd_locate(unsigned char x, unsigned char y)
{
lcd_writecommand(HD44780_DDRAM_SET | (x + (0x40 * y)));
}
//-----------------------------------------------------------------------------
void lcd_strxy(unsigned char * text, unsigned char x, unsigned char y)
{
lcd_locate(x,y);
while(*text)
lcd_writedata(*text++);
}
//-----------------------------------------------------------------------------
void lcd_writebinary(unsigned int var, unsigned char bitCount)
{
signed char 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_init(void)
{
volatile unsigned char i = 0;
volatile unsigned int delayCnt = 0;
RCC_AHB1PeriphClockCmd(LCD_CLK_LINE, ENABLE);
GPIO_InitStructure.GPIO_Pin = LCD_D4|LCD_D5|LCD_D6|LCD_D7|LCD_RS|LCD_RW|LCD_EN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_Init(LCD_GPIO, &GPIO_InitStructure);
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);
}
//-----------------------------------------------------------------------------
void lcd_addchar (unsigned char chrNum, unsigned char n, const unsigned char *p)
{
lcd_writecommand(HD44780_CGRAM_SET | chrNum * 8);
n *= 8;
do
lcd_writedata(*p++);
while (--n);
}
//-----------------------------------------------------------------------------
void lcd_cls(void){
lcd_writecommand(HD44780_CLEAR);
}
unsigned char* intToStr(int n){
int i = 0;
int j = 0;
char *tmp = (char*)malloc(sizeof(char));
unsigned char *ret = (unsigned char*)malloc(12);
if(n<0 data-blogger-escaped-i="" data-blogger-escaped-j="" data-blogger-escaped-n="" data-blogger-escaped-ret="-" data-blogger-escaped-while="">9){
*tmp = n%10+48;
n-=n%10;
n/=10;
tmp++;
i++;
}
*tmp = n+48;
i++;
while(i--){
ret[j++] = *tmp--;
}
return ret;
}
void lcd_int(int a){
unsigned short ch,
first; //you need this to display 0 if there was any char
//Get first char
ch = a/10000;
if(ch){
lcd_writedata(48+ch);
first = 1;
}
//Get second char
ch = (a/1000)%10;
if(ch || first){
lcd_writedata(48+ch);
first = 1;
}
//Get third char
ch = (a/100)%10;
if(ch || first){
lcd_writedata(48+ch);
first = 1;
}
//Get fourth char
ch = (a/10)%10;
if(ch || first){
lcd_writedata(48+ch);
//first = 1; //q
}
//Get fifth char
ch = a%10;
//if(ch || first) //you dont need to check las one if ch is 0 then just display it, unless you dont want to then uncomment this line ("//q" line too)
lcd_writedata(48+ch);
// lcd_str(intToStr(n));
}
void lcd_intxy(int n, unsigned char x, unsigned char y){
lcd_locate(x,y);
lcd_int(n);
}
main.c
lcd_init();
while (1)
{
lcd_locate(1,0);
lcd_str("Mazen");
lcd_locate(7,0);
lcd_str("A.");
lcd_locate(0,1);
lcd_str("-3125");
}
Update:
Number display function is fixed