I have written an LDC driver for STM32f3xx. Wiring is correct but LCD doesn't work. LCD shows only white squares so I think data pins doesn't work correctly or there are logical error. I use char because data is 1 byte actually.
Here are the function's tasks:
fallingEdge()
: send to falling edge signal for the waking up LCD.
send4BitMode()
: LCD works in 4bit mode. So first of all, it will send MSB(4) bits to LCD. After, I use bitwise operator for shifting 4bit right so LSB(4) bits sent to LCD.
sendCommand()
: This function sends commands to LCD. (two times)
sendCharacter()
: This function sends characters to LCD. (two times)
Here is the lcd.h for prototype functions;
/*
* lcd.h
* Created on: 1 Ara 2020
* Author: fatay
*/
/*
* LCD Connection Pins for Using This Library
* DataPin1 -> RB1
* DataPin2 -> RB2
* DataPin3 -> RB3
* DataPin4 -> RB4
* EPin -> RB5
* RSPin -> RB6
*
*/
#ifndef INC_LCD_H_
#define INC_LCD_H_
#include <stdint.h>
#include "stm32f3xx.h"
#define DataPin1 1
#define DataPin2 2
#define DataPin3 3
#define DataPin4 4
#define EPin 5
#define RSPin 6
void clearLCD(void);
void setCursorToFirstLine(void);
void setCursorToSecondLine(void);
void initLCD(void);
void writeLCD(char str);
#endif /* INC_LCD_H_ */
and this is the lcd.c file;
#include <stdlib.h>
#include "stm32f3xx_hal.h"
#include "lcd.h"
/*
* LCD Connection Pins for Using This Library
* DataPin1 -> RB1
* DataPin2 -> RB2
* DataPin3 -> RB3
* DataPin4 -> RB4
* EPin -> RB5
* RSPin -> RB6
*
*/
//for manipulating bits
#define SET_IF(expr) ((expr) ? GPIO_PIN_SET : GPIO_PIN_RESET)
/*
* We will be send falling edge signal
* for waking up an LCD. So function
* should be like this;
*
*/
static void fallingEdge(void)
{
HAL_GPIO_WritePin(GPIOB, EPin, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(GPIOB, EPin, GPIO_PIN_RESET);
}
/*
* We send parallel 4 bit data in two times.
* We will be getting first four (LSB) bits and then
* the second one (MSB) bits.
*/
static void send4BitMode(char data)
{
HAL_GPIO_WritePin(GPIOB, DataPin4, SET_IF(data & 0x08));
HAL_GPIO_WritePin(GPIOB, DataPin3, SET_IF(data & 0x04));
HAL_GPIO_WritePin(GPIOB, DataPin2, SET_IF(data & 0x02));
HAL_GPIO_WritePin(GPIOB, DataPin1, SET_IF(data & 0x01));
fallingEdge();
HAL_Delay(1);
}
static void sendCommand(char command)
{
HAL_GPIO_WritePin(GPIOB, RSPin, GPIO_PIN_RESET);
send4BitMode(command >> 4);
send4BitMode(command);
}
static void sendCharacter(char character)
{
HAL_GPIO_WritePin(GPIOB, RSPin, GPIO_PIN_SET);
send4BitMode(character >> 4);
send4BitMode(character);
}
/*
*
* USER SCOPE
*
*/
void clearLCD(void) {
sendCommand(0x01);
}
void setCursorToFirstLine(void)
{
sendCommand((char) 0x80);
}
void setCursorToSecondLine(void)
{
sendCommand((char) 0x40);
}
void initLCD(void)
{
HAL_GPIO_WritePin(GPIOB, EPin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB, RSPin, GPIO_PIN_RESET);
sendCommand((char) 0x20 | 0x00 | 0x08);
HAL_Delay(5);
clearLCD();
setCursorToFirstLine();
HAL_Delay(500);
}
void writeLCD(char str)
{
sendCharacter(str);
}
thanks for your interest .
Have you tried to do something like that:
static void send4BitMode(char data)
{
HAL_GPIO_WritePin(GPIOB, EPin, GPIO_PIN_SET);
HAL_Delay(1);
// delay of 100 MicroSec on my side
HAL_GPIO_WritePin(GPIOB, DataPin4, SET_IF(data & 0x08));
HAL_GPIO_WritePin(GPIOB, DataPin3, SET_IF(data & 0x04));
HAL_GPIO_WritePin(GPIOB, DataPin2, SET_IF(data & 0x02));
HAL_GPIO_WritePin(GPIOB, DataPin1, SET_IF(data & 0x01));
HAL_GPIO_WritePin(GPIOB, EPin, GPIO_PIN_RESET);
}
Have a look to https://www.waveshare.com/datasheet/LCD_en_PDF/LCD1602.pdf 12. INITIALIZATION SEQUENCE, the sequence is:
void initLCD(void)
{
HAL_GPIO_WritePin(GPIOB, EPin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB, RSPin, GPIO_PIN_RESET);
// The RW pin must be low
send4BitMode((char) 0x03);
// wait 4.1 ms
send4BitMode((char) 0x03);
// wait 100 us
send4BitMode((char) 0x03);
send4BitMode((char) 0x02); // set interface to 4 bit
sendCommand( 0x28 ); // 0x20: Function set, 0x08: 2 lines
...
}
Yes, actually initilization is wrong. Thanks for answering. I use this initialization and problem was solved.