diff --git a/Examples/HAL/I2C/PCF8574_I2C_LCD_F003_SOP16/LCD1602.c b/Examples/HAL/I2C/PCF8574_I2C_LCD_F003_SOP16/LCD1602.c new file mode 100644 index 0000000..935c597 --- /dev/null +++ b/Examples/HAL/I2C/PCF8574_I2C_LCD_F003_SOP16/LCD1602.c @@ -0,0 +1,102 @@ +#include "LCD1602.h" + +uint8_t portLcd = 0; + +static void LCD_WriteByte(uint8_t bt) { + HAL_I2C_Master_Transmit(&LCD_I2C, ADRESS_I2C_LCD, &bt, 1, 1000); +} + +static void LCD_SendCmd_8bit(uint8_t bt) { + LCD_WriteByte(portLcd |= 0x04); + HAL_Delay(1); + LCD_WriteByte(portLcd | bt); + LCD_WriteByte(portLcd &= ~ 0x04); + HAL_Delay(1); +} + +static void LCD_SendCmd(uint8_t bt) { + bt <<= 4; + LCD_SendCmd_8bit(bt); +} + +static void LCD_SendByte(uint8_t bt, uint8_t mode) { + if (mode == 0) { + LCD_WriteByte(portLcd &= ~ 0x01); // RS = 0; + } + else { + LCD_WriteByte(portLcd |= 0x01); // RS = 1; + } + + uint8_t tempBuf = 0; + tempBuf = bt >> 4; + + LCD_SendCmd(tempBuf); + LCD_SendCmd(bt); +} + +void LCD_Init(void) { + HAL_Delay(50); + LCD_SendCmd(0x03); + HAL_Delay(5); + LCD_SendCmd(0x03); + HAL_Delay(1); + LCD_SendCmd(0x03); + HAL_Delay(10); + + LCD_SendCmd(0x02); // 0x02 // 4bit mode + HAL_Delay(2); + + LCD_SendByte(0x38, 0); + HAL_Delay(2); + + LCD_SendByte(0x02, 0); + HAL_Delay(2); + LCD_SendByte(0x0C, 0); + HAL_Delay(2); + LCD_SendByte(0x01, 0); + HAL_Delay(2); + LCD_SendByte(0x06, 0); + HAL_Delay(1); + //--------------------------------------------------------------------------------- + + LCD_WriteByte(portLcd |= 0x08); + LCD_WriteByte (portLcd &= ~ 0x02); +} + +void LCD_PrintString(char* str) { + uint8_t i = 0; + + while (str[i] != 0) { + LCD_SendByte(str[i], 1); + i++; + } +} + +void LCD_Clear(void) { + + LCD_SendByte(0x01, 0); + HAL_Delay(2); +} + +void LCD_SetCursor(uint8_t x, uint8_t y) { + switch (y) { + case 0: + LCD_SendByte(x | 0x80, 0); + HAL_Delay(1); + break; + case 1: + LCD_SendByte(( 0x40 + x) | 0x80, 0); + HAL_Delay(1); + break; + case 2: + LCD_SendByte(( 0x14 + x) | 0x80, 0); + HAL_Delay(1); + break; + case 3: + LCD_SendByte(( 0x54 + x) | 0x80, 0); + HAL_Delay(1); + break; + default: + break; + } +} diff --git a/Examples/HAL/I2C/PCF8574_I2C_LCD_F003_SOP16/LCD1602.h b/Examples/HAL/I2C/PCF8574_I2C_LCD_F003_SOP16/LCD1602.h new file mode 100644 index 0000000..9b2f804 --- /dev/null +++ b/Examples/HAL/I2C/PCF8574_I2C_LCD_F003_SOP16/LCD1602.h @@ -0,0 +1,34 @@ +#ifndef _LCD1602_H +#define _LCD1602_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include "py32f0xx_hal.h" +#include "py32f0xx_hal_i2c.h" + +#include "main.h" +#include "LCD1602_config.h" + +extern uint8_t portLcd; + +#ifdef LCD1602_I2C +extern I2C_HandleTypeDef I2cHandle; +#endif + +void LCD_Init(void); + +void LCD_PrintString( char* str ); + +void LCD_Clear(void); + +void LCD_SetCursor( uint8_t x, uint8_t y ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Examples/HAL/I2C/PCF8574_I2C_LCD_F003_SOP16/LCD1602_config.h b/Examples/HAL/I2C/PCF8574_I2C_LCD_F003_SOP16/LCD1602_config.h new file mode 100644 index 0000000..b2c475b --- /dev/null +++ b/Examples/HAL/I2C/PCF8574_I2C_LCD_F003_SOP16/LCD1602_config.h @@ -0,0 +1,23 @@ +#ifndef _LCD1602_CONFIG_H +#define _LCD1602_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "main.h" + +#define LCD1602_I2C + +#if defined (LCD1602_I2C) + +#define LCD_I2C I2cHandle +#define ADRESS_I2C_LCD (0x27 << 1) // (0x27 << 1) (0x3F << 1) + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Examples/HAL/I2C/PCF8574_I2C_LCD_F003_SOP16/main.c b/Examples/HAL/I2C/PCF8574_I2C_LCD_F003_SOP16/main.c index b9de429..968b3c1 100644 --- a/Examples/HAL/I2C/PCF8574_I2C_LCD_F003_SOP16/main.c +++ b/Examples/HAL/I2C/PCF8574_I2C_LCD_F003_SOP16/main.c @@ -4,93 +4,30 @@ #include "py32f0xx_hal_i2c.h" #include "py32f0xx_bsp_printf.h" -#define I2C_ADDRESS 0xA0 /* host address */ +#include "LCD1602.h" + +#define I2C_ADDRESS 0xA0 // host address I2C_HandleTypeDef I2cHandle; void APP_ErrorHandler(void); static void APP_I2C_Config(void); -#define SLAVE_ADDRESS_LCD 0x4E // PCF8574 +int SLAVE_ADDRESS_LCD = 0; // PCF8574 -// LCD handling functions are borrowed from https://controllerstech.com/i2c-lcd-in-stm32/ -void lcd_send_cmd (char cmd) -{ - char data_u, data_l; - uint8_t data_t[4]; - data_u = (cmd&0xf0); - data_l = ((cmd<<4)&0xf0); - data_t[0] = data_u|0x0C; // en=1, rs=0 - data_t[1] = data_u|0x08; // en=0, rs=0 - data_t[2] = data_l|0x0C; // en=1, rs=0 - data_t[3] = data_l|0x08; // en=0, rs=0 - HAL_I2C_Master_Transmit (&I2cHandle, SLAVE_ADDRESS_LCD,(uint8_t *) data_t, 4, 100); -} +int find_lcd_i2c_address() { + int ret = -1; -void lcd_send_data (char data) -{ - char data_u, data_l; - uint8_t data_t[4]; - data_u = (data&0xf0); - data_l = ((data<<4)&0xf0); - data_t[0] = data_u|0x0D; // en=1, rs=0 - data_t[1] = data_u|0x09; // en=0, rs=0 - data_t[2] = data_l|0x0D; // en=1, rs=0 - data_t[3] = data_l|0x09; // en=0, rs=0 - HAL_I2C_Master_Transmit (&I2cHandle, SLAVE_ADDRESS_LCD,(uint8_t *) data_t, 4, 100); -} - -void lcd_clear (void) -{ - lcd_send_cmd (0x80); - for (int i=0; i<70; i++) { - lcd_send_data (' '); - } -} - -void lcd_put_cur(int row, int col) -{ - switch (row) { - case 0: - col |= 0x80; - break; - case 1: - col |= 0xC0; - break; + for (int i = 1; i < 128; i++) { + ret = HAL_I2C_IsDeviceReady(&I2cHandle, (uint16_t)(i << 1), 3, 1000); + if (ret != HAL_OK) { } + else if (ret == HAL_OK) { + return i; + } + } - lcd_send_cmd (col); -} - -void lcd_init (void) -{ - // 4 bit initialisation - HAL_Delay(50); // wait for > 40ms - lcd_send_cmd (0x30); - HAL_Delay(5); // wait for > 4.1ms - lcd_send_cmd (0x30); - HAL_Delay(1); // wait for > 100us - lcd_send_cmd (0x30); - HAL_Delay(10); - lcd_send_cmd (0x20); // 4bit mode - HAL_Delay(10); - - // display initialisation - lcd_send_cmd (0x28); // Function set --> DL=0 (4 bit mode), N = 1 (2 line display) F = 0 (5x8 characters) - HAL_Delay(1); - lcd_send_cmd (0x08); // Display on/off control --> D=0, C=0, B=0 ---> display off - HAL_Delay(1); - lcd_send_cmd (0x01); // clear display - HAL_Delay(1); - HAL_Delay(1); - lcd_send_cmd (0x06); // Entry mode set --> I/D = 1 (increment cursor) & S = 0 (no shift) - HAL_Delay(1); - lcd_send_cmd (0x0C); // Display on/off control --> D = 1, C and B = 0. (Cursor and blink, last two bits) -} - -void lcd_send_string (char *str) -{ - while (*str) lcd_send_data (*str++); + return -1; } int main(void) @@ -102,12 +39,15 @@ int main(void) APP_I2C_Config(); - lcd_init (); + SLAVE_ADDRESS_LCD = find_lcd_i2c_address(); + SLAVE_ADDRESS_LCD = (SLAVE_ADDRESS_LCD << 1); - lcd_send_string ("HELLO WORLD!"); + LCD_Init(); + LCD_SetCursor(0, 0); + LCD_PrintString("HELLO WORLD!"); HAL_Delay(1000); - lcd_put_cur(1, 0); - lcd_send_string("HOWDY!"); + LCD_SetCursor(0, 1); + LCD_PrintString("HOWDY!"); HAL_Delay(2000); while(1); diff --git a/Examples/HAL/I2C/PCF8574_I2C_LCD_F003_SOP16/main.h b/Examples/HAL/I2C/PCF8574_I2C_LCD_F003_SOP16/main.h new file mode 100644 index 0000000..1fb427b --- /dev/null +++ b/Examples/HAL/I2C/PCF8574_I2C_LCD_F003_SOP16/main.h @@ -0,0 +1,29 @@ +// Copyright 2021 IOsetting +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef __MAIN_H +#define __MAIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +void APP_ErrorHandler(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* __MAIN_H */