mirror of
https://github.com/IcedRooibos/py32f0-template.git
synced 2025-10-28 08:22:06 -07:00
Add more robust init for 16x2 I2C LCD displays
This commit is contained in:
parent
46288c97e1
commit
ac2db183aa
102
Examples/HAL/I2C/PCF8574_I2C_LCD_F003_SOP16/LCD1602.c
Normal file
102
Examples/HAL/I2C/PCF8574_I2C_LCD_F003_SOP16/LCD1602.c
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
34
Examples/HAL/I2C/PCF8574_I2C_LCD_F003_SOP16/LCD1602.h
Normal file
34
Examples/HAL/I2C/PCF8574_I2C_LCD_F003_SOP16/LCD1602.h
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef _LCD1602_H
|
||||
#define _LCD1602_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#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
|
||||
23
Examples/HAL/I2C/PCF8574_I2C_LCD_F003_SOP16/LCD1602_config.h
Normal file
23
Examples/HAL/I2C/PCF8574_I2C_LCD_F003_SOP16/LCD1602_config.h
Normal file
@ -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
|
||||
@ -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);
|
||||
|
||||
29
Examples/HAL/I2C/PCF8574_I2C_LCD_F003_SOP16/main.h
Normal file
29
Examples/HAL/I2C/PCF8574_I2C_LCD_F003_SOP16/main.h
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2021 IOsetting <iosetting(at)outlook.com>
|
||||
//
|
||||
// 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 */
|
||||
Loading…
x
Reference in New Issue
Block a user