I have used this library to write something on my LCD screen. When I try to clear it with my own code, it doesn't work for some reason. Clearing text with library works fine. I'm using screen on 8-bit mode.
I have checked that the pins are configured the same way. I have used debugger to confirm that right bits are toggled in ODR.
main.c
#include "GPIO_Lib.h"
#include "systick_lib.h"
#include "lcd.h"
int main(void) {
GPIOA_enable_clock();
GPIOB_enable_clock();
init_lcd();
write_data_pins(0x01);
while (1);
}
lcd.h
#ifndef __LCD_H
#define __LCD_H
#include "GPIO_Lib.h"
pin_type data0;
pin_type data1;
pin_type data2;
pin_type data3;
pin_type data4;
pin_type data5;
pin_type data6;
pin_type data7;
pin_type RS;
pin_type RW;
pin_type E;
pin_type data_pins[8];
void init_lcd(void);
void write_data_pins(uint8_t data);
#endif
lcd.c
#include "lcd.h"
#include "systick_lib.h"
void init_lcd() {
init_pin(&data0, GPIOA, 5, output, no_PUPD);
init_pin(&data1, GPIOA, 6, output, no_PUPD);
init_pin(&data2, GPIOA, 7, output, no_PUPD);
init_pin(&data3, GPIOB, 6, output, no_PUPD);
init_pin(&data4, GPIOB, 10, output, no_PUPD);
init_pin(&data5, GPIOB, 4, output, no_PUPD);
init_pin(&data6, GPIOB, 5, output, no_PUPD);
init_pin(&data7, GPIOB, 3, output, no_PUPD);
init_pin(&RS, GPIOB, 8, output, no_PUPD);
//init_pin(&RW, GPIOA, 6, output, no_PUPD); // connected to GND
init_pin(&E, GPIOB, 9, output, no_PUPD);
data_pins[0] = data0;
data_pins[1] = data1;
data_pins[2] = data2;
data_pins[3] = data3;
data_pins[4] = data4;
data_pins[5] = data5;
data_pins[6] = data6;
data_pins[7] = data7;
}
void write_data_pins(uint8_t data) {
write_pin(&RS, LOW);
write_pin(&E, LOW);
for (int i = 0; i < 8; i++) {
write_pin(&(data_pins[i]), (data >> i) & 0x01);
}
write_pin(&E, HIGH);
delay(1);
write_pin(&E, LOW);
}
GPIO_lib.c
#include "GPIO_Lib.h"
void GPIOA_enable_clock(void) {
RCC->AHB1ENR |= 0x1u;
}
void GPIOB_enable_clock(void) {
RCC->AHB1ENR |= 0x2u;
}
void GPIOC_enable_clock(void) {
RCC->AHB1ENR |= 0x4u;
}
void GPIOD_enable_clock(void) {
RCC->AHB1ENR |= 0x8u;
}
void GPIOE_enable_clock(void) {
RCC->AHB1ENR |= 0x10u;
}
void GPIOH_enable_clock(void) {
RCC->AHB1ENR |= 0x80u;
}
void init_pin(pin_type* pin, GPIO_TypeDef* _gpio, uint32_t _pin_num, uint32_t _mode, uint32_t _PUPD) {
pin->gpio = _gpio;
pin->mode = _mode;
pin->pin_num = _pin_num;
pin->PUPD = _PUPD;
pin->gpio->MODER |= pin->mode << ((pin->pin_num * 2));
pin->gpio->PUPDR |= pin->PUPD << ((pin->pin_num * 2));
write_pin(pin, LOW);
}
void set_input(pin_type* pin) {
pin->gpio->MODER &= ~(3u << ((pin->pin_num * 2)));
}
void set_output(pin_type* pin) {
pin->gpio->MODER |= output << ((pin->pin_num * 2));
}
pin_state write_pin(pin_type* pin, pin_state state) {
if (state == HIGH) {
pin->gpio->ODR |= (1u << pin->pin_num);
} else {
pin->gpio->ODR &= ~(1u << pin->pin_num);
}
return state;
}
pin_state read_pin(pin_type* pin) {
uint8_t state = ( pin->gpio->IDR >> pin->pin_num) & 1u;
if (state == 1) {
return HIGH;
}
return LOW;
}
pin_state toggle_pin(pin_type* pin) {
pin->gpio->ODR ^= (1u << pin->pin_num);
return read_pin(pin);
}
systick_lib.c
#include "systick_lib.h"
#include "systick_registers.h"
void delay(uint32_t ms) {
systick_reg->LOAD |= 16000u - 1;
systick_reg->CTRL |= 5u;
for (int i = 0; i < ms; i++) {
while (!(systick_reg->CTRL & (1u << 16u)));
}
systick_reg->LOAD = 0;
systick_reg->CTRL = 0;
}
void delay_micros(uint32_t micros) {
systick_reg->LOAD |= 16u - 1;
systick_reg->CTRL |= 5u;
for (int i = 0; i < micros; i++) {
while (!(systick_reg->CTRL & (1u << 16u)));
}
systick_reg->LOAD = 0;
systick_reg->CTRL = 0;
}
How library clears the display
#define CLEAR_DISPLAY 0x01
#define LCD_COMMAND_REG 0
#define LCD_BYTE 8
#define DELAY(X) HAL_Delay(X)
void Lcd_clear(Lcd_HandleTypeDef * lcd) {
lcd_write_command(lcd, CLEAR_DISPLAY);
}
void lcd_write_command(Lcd_HandleTypeDef * lcd, uint8_t command)
{
HAL_GPIO_WritePin(lcd->rs_port, lcd->rs_pin, LCD_COMMAND_REG); // Write to command register
if(lcd->mode == LCD_4_BIT_MODE)
{
lcd_write(lcd, (command >> 4), LCD_NIB);
lcd_write(lcd, command & 0x0F, LCD_NIB);
}
else
{
lcd_write(lcd, command, LCD_BYTE);
}
}
void lcd_write(Lcd_HandleTypeDef * lcd, uint8_t data, uint8_t len)
{
for(uint8_t i = 0; i < len; i++)
{
HAL_GPIO_WritePin(lcd->data_port[i], lcd->data_pin[i], (data >> i) & 0x01);
}
HAL_GPIO_WritePin(lcd->en_port, lcd->en_pin, 1);
DELAY(1);
HAL_GPIO_WritePin(lcd->en_port, lcd->en_pin, 0); // Data receive on falling edge
}