diff --git a/Core/Inc/lcd.h b/Core/Inc/lcd.h new file mode 100644 index 0000000..0558f54 --- /dev/null +++ b/Core/Inc/lcd.h @@ -0,0 +1,20 @@ +#ifndef __I2C_LCD_H +#define __I2C_LCD_H + +#include "stm32f1xx_hal.h" + +typedef struct +{ + I2C_HandleTypeDef *I2C_Handle; //I2C handle parameters + uint8_t address; + uint8_t rows; + uint8_t cols; +} LCD_HandleTypeDef; + +HAL_StatusTypeDef LCD_SendInternal(LCD_HandleTypeDef *lcd, uint8_t data, uint8_t flags); +void LCD_SendCommand(LCD_HandleTypeDef *lcd, uint8_t cmd); +void LCD_SendData(LCD_HandleTypeDef *lcd, uint8_t data); +void LCD_Init(LCD_HandleTypeDef *lcd); +void LCD_SendString(LCD_HandleTypeDef *lcd, char *str); + +#endif \ No newline at end of file diff --git a/Core/Src/lcd.c b/Core/Src/lcd.c new file mode 100644 index 0000000..25f643c --- /dev/null +++ b/Core/Src/lcd.c @@ -0,0 +1,107 @@ +#include "lcd.h" + +#define LCD_COLS 20 + +#define LCD_DELAY_MS 5 + +// commands +#define LCD_CLEARDISPLAY 0x01 +#define LCD_RETURNHOME 0x02 +#define LCD_ENTRYMODESET 0x04 +#define LCD_DISPLAYCONTROL 0x08 +#define LCD_CURSORSHIFT 0x10 +#define LCD_FUNCTIONSET 0x20 +#define LCD_SETCGRAMADDR 0x40 +#define LCD_SETDDRAMADDR 0x80 + +// flags for display entry mode +#define LCD_ENTRYRIGHT 0x00 +#define LCD_ENTRYLEFT 0x02 +#define LCD_ENTRYSHIFTINCREMENT 0x01 +#define LCD_ENTRYSHIFTDECREMENT 0x00 + +// flags for display on/off control +#define LCD_DISPLAYON 0x04 +#define LCD_DISPLAYOFF 0x00 +#define LCD_CURSORON 0x02 +#define LCD_CURSOROFF 0x00 +#define LCD_BLINKON 0x01 +#define LCD_BLINKOFF 0x00 + +// flags for display/cursor shift +#define LCD_DISPLAYMOVE 0x08 +#define LCD_CURSORMOVE 0x00 +#define LCD_MOVERIGHT 0x04 +#define LCD_MOVELEFT 0x00 + +// flags for function set +#define LCD_8BITMODE 0x10 +#define LCD_4BITMODE 0x00 +#define LCD_MULTILINE 0x08 +#define LCD_SINGLELINE 0x00 +#define LCD_5x10DOTS 0x04 +#define LCD_5x8DOTS 0x00 + +// flags for backlight control +#define LCD_BACKLIGHT 0x08 +#define LCD_NOBACKLIGHT 0x00 + +//moving +#define LCD_LINE1 0x00 +#define LCD_LINE2 0x40 +#define LCD_LINE3 0x14 +#define LCD_LINE4 0x54 + +#define LCD_PIN_EN 0b00000100 // Enable bit +#define LCD_PIN_RW 0b00000010 // Read/Write bit +#define LCD_PIN_RS 0b00000001 // Register select bit + +HAL_StatusTypeDef LCD_SendInternal(LCD_HandleTypeDef *lcd, uint8_t data, uint8_t flags) { + HAL_StatusTypeDef res; + for(;;) { + res = HAL_I2C_IsDeviceReady(lcd->I2C_Handle, lcd->address, 1, HAL_MAX_DELAY); + if(res == HAL_OK) + break; + } + + uint8_t up = data & 0xF0; + uint8_t lo = (data << 4) & 0xF0; + + uint8_t data_arr[4]; + data_arr[0] = up|flags|LCD_BACKLIGHT|LCD_PIN_EN; + data_arr[1] = up|flags|LCD_BACKLIGHT; + data_arr[2] = lo|flags|LCD_BACKLIGHT|LCD_PIN_EN; + data_arr[3] = lo|flags|LCD_BACKLIGHT; + + res = HAL_I2C_Master_Transmit(lcd->I2C_Handle, lcd->address, data_arr, + sizeof(data_arr), HAL_MAX_DELAY); + HAL_Delay(LCD_DELAY_MS); + return res; +} + +void LCD_SendCommand(LCD_HandleTypeDef *lcd, uint8_t cmd) { + LCD_SendInternal(lcd->address, cmd, 0); +} + +void LCD_SendData(LCD_HandleTypeDef *lcd, uint8_t data) { + LCD_SendInternal(lcd->address, data, LCD_PIN_RS); +} + +void LCD_Init(LCD_HandleTypeDef *lcd) { + //http://easyelectronics.ru/avr-uchebnyj-kurs-podklyuchenie-k-avr-lcd-displeya-hd44780.html + + LCD_SendCommand(lcd->address, LCD_FUNCTIONSET | LCD_4BITMODE | LCD_MULTILINE | LCD_5x8DOTS); // 0b00110000); + // display & cursor home (keep this!) + LCD_SendCommand(lcd->address, LCD_RETURNHOME); + // display on, right shift, underline off, blink off + LCD_SendCommand(lcd->address, LCD_DISPLAYCONTROL|LCD_DISPLAYON|LCD_CURSOROFF|LCD_BLINKOFF); // 0b00001100); + // clear display (optional here) + LCD_SendCommand(lcd->address, LCD_CLEARDISPLAY); +} + +void LCD_SendString(LCD_HandleTypeDef *lcd, char *str) { + while(*str) { + LCD_SendData(lcd->address, (uint8_t)(*str)); + str++; + } +} diff --git a/Core/Src/main.c b/Core/Src/main.c index 711252a..21c078d 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -24,6 +24,7 @@ /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ +#include "lcd.h" /* USER CODE END Includes */ @@ -53,6 +54,12 @@ UART_HandleTypeDef huart1; DMA_HandleTypeDef hdma_usart1_tx; /* USER CODE BEGIN PV */ +LCD_HandleTypeDef hlcd = { + &hi2c1, + (0x27 << 1), + 4, + 20 +}; /* USER CODE END PV */ @@ -109,7 +116,7 @@ int main(void) MX_USART1_UART_Init(); MX_USB_DEVICE_Init(); /* USER CODE BEGIN 2 */ - + LCD_Init(&hlcd); /* USER CODE END 2 */ /* Infinite loop */ diff --git a/Makefile b/Makefile index 52b4fd7..1e1996a 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ TARGET = Uberdevice # debug build? DEBUG = 1 # optimization -OPT = -Og -Os +OPT = -Og ####################################### @@ -37,6 +37,7 @@ BUILD_DIR = build # C sources C_SOURCES = \ Core/Src/main.c \ +Core/Src/lcd.c \ Core/Src/stm32f1xx_it.c \ Core/Src/stm32f1xx_hal_msp.c \ USB_DEVICE/App/usb_device.c \