mirror of
https://github.com/IcedRooibos/py32f0-template.git
synced 2025-10-28 08:22:06 -07:00
feat: ll 1602 lcd example
This commit is contained in:
parent
624e851476
commit
983ff1cbc6
225
Examples/LL/I2C/PCF8574_1602LCD/bsp_i2c.c
Normal file
225
Examples/LL/I2C/PCF8574_1602LCD/bsp_i2c.c
Normal file
@ -0,0 +1,225 @@
|
||||
#include <stdio.h>
|
||||
#include "bsp_i2c.h"
|
||||
|
||||
|
||||
#define I2C_SELF_ADDRESS 0xA0 /* host address */
|
||||
#define I2C_MAX_TIMEOUT 0x2000
|
||||
#define I2C_STATE_READY 0
|
||||
#define I2C_STATE_BUSY_TX 1
|
||||
#define I2C_STATE_BUSY_RX 2
|
||||
|
||||
__IO uint32_t i2cState = I2C_STATE_READY;
|
||||
|
||||
|
||||
void BSP_I2C_Config(void)
|
||||
{
|
||||
LL_I2C_InitTypeDef I2C_InitStruct;
|
||||
/*
|
||||
* Clock speed:
|
||||
* - standard = 100khz, if PLL is on, set system clock <= 16MHz, or I2C might not work
|
||||
* - fast = 400khz
|
||||
*/
|
||||
I2C_InitStruct.ClockSpeed = LL_I2C_MAX_SPEED_FAST;
|
||||
I2C_InitStruct.DutyCycle = LL_I2C_DUTYCYCLE_16_9;
|
||||
I2C_InitStruct.OwnAddress1 = I2C_SELF_ADDRESS;
|
||||
I2C_InitStruct.TypeAcknowledge = LL_I2C_NACK;
|
||||
LL_I2C_Init(I2C1, &I2C_InitStruct);
|
||||
|
||||
/* Enale clock stretch (reset default: on) */
|
||||
// LL_I2C_EnableClockStretching(I2C1);
|
||||
|
||||
/* Enable general call (reset default: off) */
|
||||
// LL_I2C_EnableGeneralCall(I2C1);
|
||||
}
|
||||
|
||||
|
||||
void BSP_I2C_Scan(void)
|
||||
{
|
||||
for(uint16_t i = 0; i < 128; i++)
|
||||
{
|
||||
if(BSP_I2C_IsDeviceReady(i << 1, I2C_MAX_TIMEOUT) == SUCCESS)
|
||||
{
|
||||
printf("Found address: 0x%02X\r\n", i << 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ErrorStatus BSP_I2C_IsDeviceReady(uint8_t devAddress, uint16_t timeout)
|
||||
{
|
||||
uint16_t t = timeout;
|
||||
while (i2cState == I2C_STATE_BUSY_TX && t--);
|
||||
if (t == 0) return ERROR;
|
||||
t = timeout;
|
||||
|
||||
LL_I2C_DisableBitPOS(I2C1);
|
||||
|
||||
i2cState = I2C_STATE_BUSY_TX;
|
||||
|
||||
/* Start */
|
||||
LL_I2C_GenerateStartCondition(I2C1);
|
||||
while (LL_I2C_IsActiveFlag_SB(I2C1) != 1 && t--);
|
||||
if (t == 0)
|
||||
{
|
||||
i2cState = I2C_STATE_READY;
|
||||
return ERROR;
|
||||
}
|
||||
t = timeout;
|
||||
|
||||
/* Send slave address */
|
||||
LL_I2C_TransmitData8(I2C1, (devAddress & (uint8_t)(~0x01)));
|
||||
while (LL_I2C_IsActiveFlag_ADDR(I2C1) != 1 && t--)
|
||||
if (t == 0)
|
||||
{
|
||||
i2cState = I2C_STATE_READY;
|
||||
return ERROR;
|
||||
}
|
||||
t = timeout;
|
||||
|
||||
LL_I2C_ClearFlag_ADDR(I2C1);
|
||||
|
||||
/* Stop */
|
||||
LL_I2C_GenerateStopCondition(I2C1);
|
||||
|
||||
i2cState = I2C_STATE_READY;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
ErrorStatus BSP_I2C_MasterTransmit(uint16_t devAddress, uint8_t *pData, uint16_t len, uint16_t timeout)
|
||||
{
|
||||
uint16_t t = timeout;
|
||||
|
||||
while (i2cState == I2C_STATE_BUSY_TX && t--)
|
||||
if (t == 0) return ERROR;
|
||||
t = timeout;
|
||||
|
||||
LL_I2C_DisableBitPOS(I2C1);
|
||||
i2cState = I2C_STATE_BUSY_TX;
|
||||
|
||||
/* Start */
|
||||
LL_I2C_GenerateStartCondition(I2C1);
|
||||
while (LL_I2C_IsActiveFlag_SB(I2C1) != 1 && t--)
|
||||
if (t == 0)
|
||||
{
|
||||
i2cState = I2C_STATE_READY;
|
||||
return ERROR;
|
||||
}
|
||||
t = timeout;
|
||||
|
||||
/* Send slave address */
|
||||
LL_I2C_TransmitData8(I2C1, (devAddress & (uint8_t)(~0x01)));
|
||||
while (LL_I2C_IsActiveFlag_ADDR(I2C1) != 1 && t--)
|
||||
if (t == 0)
|
||||
{
|
||||
i2cState = I2C_STATE_READY;
|
||||
return ERROR;
|
||||
}
|
||||
t = timeout;
|
||||
|
||||
LL_I2C_ClearFlag_ADDR(I2C1);
|
||||
|
||||
/* Transfer data */
|
||||
while (len > 0)
|
||||
{
|
||||
while (LL_I2C_IsActiveFlag_TXE(I2C1) != 1 && t--)
|
||||
if (t == 0)
|
||||
{
|
||||
i2cState = I2C_STATE_READY;
|
||||
return ERROR;
|
||||
}
|
||||
t = timeout;
|
||||
|
||||
LL_I2C_TransmitData8(I2C1, *pData++);
|
||||
len--;
|
||||
|
||||
while (LL_I2C_IsActiveFlag_BTF(I2C1) != 1 && t--)
|
||||
if (t == 0)
|
||||
{
|
||||
i2cState = I2C_STATE_READY;
|
||||
return ERROR;
|
||||
}
|
||||
t = timeout;
|
||||
}
|
||||
|
||||
/* Stop */
|
||||
LL_I2C_GenerateStopCondition(I2C1);
|
||||
|
||||
i2cState = I2C_STATE_READY;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
ErrorStatus BSP_I2C_Transmit(uint8_t devAddress, uint8_t memAddress, uint8_t *pData, uint16_t len, uint16_t timeout)
|
||||
{
|
||||
uint16_t t = timeout;
|
||||
|
||||
while (i2cState == I2C_STATE_BUSY_TX && t--)
|
||||
if (t == 0) return ERROR;
|
||||
t = timeout;
|
||||
|
||||
LL_I2C_DisableBitPOS(I2C1);
|
||||
|
||||
i2cState = I2C_STATE_BUSY_TX;
|
||||
|
||||
/* Start */
|
||||
LL_I2C_GenerateStartCondition(I2C1);
|
||||
while (LL_I2C_IsActiveFlag_SB(I2C1) != 1 && t--)
|
||||
if (t == 0)
|
||||
{
|
||||
i2cState = I2C_STATE_READY;
|
||||
return ERROR;
|
||||
}
|
||||
t = timeout;
|
||||
/* Send slave address */
|
||||
LL_I2C_TransmitData8(I2C1, (devAddress & (uint8_t)(~0x01)));
|
||||
while (LL_I2C_IsActiveFlag_ADDR(I2C1) != 1 && t--)
|
||||
if (t == 0)
|
||||
{
|
||||
i2cState = I2C_STATE_READY;
|
||||
return ERROR;
|
||||
}
|
||||
t = timeout;
|
||||
LL_I2C_ClearFlag_ADDR(I2C1);
|
||||
|
||||
/* Send memory address */
|
||||
LL_I2C_TransmitData8(I2C1, memAddress);
|
||||
while (LL_I2C_IsActiveFlag_BTF(I2C1) != 1 && t--)
|
||||
if (t == 0)
|
||||
{
|
||||
i2cState = I2C_STATE_READY;
|
||||
return ERROR;
|
||||
}
|
||||
t = timeout;
|
||||
|
||||
/* Transfer data */
|
||||
while (len > 0)
|
||||
{
|
||||
while (LL_I2C_IsActiveFlag_TXE(I2C1) != 1 && t--)
|
||||
if (t == 0)
|
||||
{
|
||||
i2cState = I2C_STATE_READY;
|
||||
return ERROR;
|
||||
}
|
||||
t = timeout;
|
||||
|
||||
LL_I2C_TransmitData8(I2C1, *pData++);
|
||||
len--;
|
||||
|
||||
if ((LL_I2C_IsActiveFlag_BTF(I2C1) == 1) && (len != 0U))
|
||||
{
|
||||
LL_I2C_TransmitData8(I2C1, *pData++);
|
||||
len--;
|
||||
}
|
||||
|
||||
while (LL_I2C_IsActiveFlag_BTF(I2C1) != 1 && t--)
|
||||
if (t == 0)
|
||||
{
|
||||
i2cState = I2C_STATE_READY;
|
||||
return ERROR;
|
||||
}
|
||||
t = timeout;
|
||||
}
|
||||
|
||||
/* Stop */
|
||||
LL_I2C_GenerateStopCondition(I2C1);
|
||||
i2cState = I2C_STATE_READY;
|
||||
return SUCCESS;
|
||||
}
|
||||
35
Examples/LL/I2C/PCF8574_1602LCD/bsp_i2c.h
Normal file
35
Examples/LL/I2C/PCF8574_1602LCD/bsp_i2c.h
Normal file
@ -0,0 +1,35 @@
|
||||
// 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 __BSP_I2C_H
|
||||
#define __BSP_I2C_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "py32f0xx_ll_i2c.h"
|
||||
#include "py32f0xx_ll_utils.h"
|
||||
|
||||
void BSP_I2C_Config(void);
|
||||
void BSP_I2C_Scan(void);
|
||||
ErrorStatus BSP_I2C_IsDeviceReady(uint8_t devAddress, uint16_t timeout);
|
||||
ErrorStatus BSP_I2C_MasterTransmit(uint16_t devAddress, uint8_t *pData, uint16_t len, uint16_t timeout);
|
||||
ErrorStatus BSP_I2C_Transmit(uint8_t devAddress, uint8_t memAddress, uint8_t *pData, uint16_t len, uint16_t timeout);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BSP_I2C_H */
|
||||
179
Examples/LL/I2C/PCF8574_1602LCD/main.c
Normal file
179
Examples/LL/I2C/PCF8574_1602LCD/main.c
Normal file
@ -0,0 +1,179 @@
|
||||
// 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.
|
||||
|
||||
/***
|
||||
* Demo: I2C - PCF8574 1602 LCD
|
||||
*
|
||||
* PY32 PCF8574 1602 LCD
|
||||
* PF1/PA9 SCL
|
||||
* PF0/PA10 SDA
|
||||
*
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "main.h"
|
||||
#include "py32f0xx_bsp_printf.h"
|
||||
#include "py32f0xx_bsp_clock.h"
|
||||
#include "pcf8574_lcd.h"
|
||||
|
||||
const uint8_t cgrom[] = {
|
||||
0x1f, 0x1f, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, /* "" 0 */
|
||||
0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x1f, 0x1f, /* ,, 1 */
|
||||
0x01, 0x07, 0x0f, 0x0f, 0x1f, 0x1f, 0x1f, 0x1f, /* /| 2 */
|
||||
0x10, 0x1c, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, /* |\ 3 */
|
||||
0x1f, 0x1f, 0x1f, 0x1f, 0x0f, 0x0f, 0x07, 0x01, /* \| 4 */
|
||||
0x1f, 0x1f, 0x1f, 0x1f, 0x1e, 0x1e, 0x1c, 0x10, /* |/ 5 */
|
||||
0x00, 0x00, 0x00, 0x00, 0x10, 0x1c, 0x1e, 0x1e, /* |\ 6 */
|
||||
0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x00 /* . 7 */
|
||||
};
|
||||
|
||||
static void APP_GPIO_Config(void);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
BSP_RCC_HSI_24MConfig();
|
||||
|
||||
BSP_USART_Config(115200);
|
||||
printf("I2C Demo: PCF8574 1602 LCD\r\nClock: %ld\r\n", SystemCoreClock);
|
||||
|
||||
APP_GPIO_Config();
|
||||
BSP_I2C_Config();
|
||||
|
||||
printf("Scanning I2C bus...\r\n");
|
||||
BSP_I2C_Scan();
|
||||
|
||||
LCD_Init(LCD1602_I2C_ADDR);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
// clear display
|
||||
LCD_SendCommand(LCD1602_I2C_ADDR, LCD1602_CMD_CLEAR_DISPLAY);
|
||||
LL_mDelay(500);
|
||||
// move cursor to 0,0
|
||||
LCD_SendCommand(LCD1602_I2C_ADDR, LCD1602_DDRAM_ROW0|0);
|
||||
LCD_SendString(LCD1602_I2C_ADDR, " Using 1602 LCD");
|
||||
// move cursor to 1,0
|
||||
LCD_SendCommand(LCD1602_I2C_ADDR, LCD1602_DDRAM_ROW1|0);
|
||||
LCD_SendString(LCD1602_I2C_ADDR, " over I2C bus");
|
||||
LL_mDelay(1500);
|
||||
|
||||
// CGRAM test
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
LCD_SetCGRAM(LCD1602_I2C_ADDR, i, &cgrom[i * 8]);
|
||||
}
|
||||
LCD_SendCommand(LCD1602_I2C_ADDR, LCD1602_CMD_CLEAR_DISPLAY);
|
||||
LL_mDelay(500);
|
||||
// move cursor to 0,0
|
||||
LCD_SendCommand(LCD1602_I2C_ADDR, LCD1602_DDRAM_ROW0|0);
|
||||
LCD_SendString(LCD1602_I2C_ADDR, "Custom chars");
|
||||
LL_mDelay(500);
|
||||
LCD_SendCommand(LCD1602_I2C_ADDR, LCD1602_DDRAM_ROW1|0);
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
LCD_SendData(LCD1602_I2C_ADDR, i);
|
||||
LL_mDelay(200);
|
||||
}
|
||||
LCD_SendString(LCD1602_I2C_ADDR, " done");
|
||||
LL_mDelay(1500);
|
||||
|
||||
// Shift display test
|
||||
LCD_SendCommand(LCD1602_I2C_ADDR, LCD1602_CMD_CLEAR_DISPLAY);
|
||||
LL_mDelay(500);
|
||||
LCD_SendCommand(LCD1602_I2C_ADDR, LCD1602_DDRAM_ROW0|8);
|
||||
LCD_SendString(LCD1602_I2C_ADDR, "Shift");
|
||||
LCD_SendCommand(LCD1602_I2C_ADDR, LCD1602_DDRAM_ROW1|7);
|
||||
LCD_SendString(LCD1602_I2C_ADDR, "<<<->>>");
|
||||
LL_mDelay(500);
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
LCD_SendCommand(LCD1602_I2C_ADDR, LCD1602_CMD_DISPLAY_SHIFT_LEFT);
|
||||
LL_mDelay(200);
|
||||
}
|
||||
LL_mDelay(500);
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
LCD_SendCommand(LCD1602_I2C_ADDR, LCD1602_CMD_DISPLAY_SHIFT_RIGHT);
|
||||
LL_mDelay(200);
|
||||
}
|
||||
LL_mDelay(1500);
|
||||
|
||||
// Move cursor test
|
||||
LCD_SendCommand(LCD1602_I2C_ADDR, LCD1602_CMD_CLEAR_DISPLAY);
|
||||
LL_mDelay(500);
|
||||
LCD_SendCommand(LCD1602_I2C_ADDR, LCD1602_DDRAM_ROW0|0);
|
||||
LCD_SendString(LCD1602_I2C_ADDR, "Move cursor");
|
||||
LL_mDelay(500);
|
||||
for (i = 0; i < 11; i++)
|
||||
{
|
||||
LCD_SendCommand(LCD1602_I2C_ADDR, LCD1602_CMD_CURSOR_MOVE_LEFT);
|
||||
LL_mDelay(200);
|
||||
}
|
||||
LL_mDelay(500);
|
||||
for (i = 0; i < 12; i++)
|
||||
{
|
||||
LCD_SendCommand(LCD1602_I2C_ADDR, LCD1602_CMD_CURSOR_MOVE_RIGHT);
|
||||
LL_mDelay(200);
|
||||
}
|
||||
LL_mDelay(500);
|
||||
LCD_SendCommand(LCD1602_I2C_ADDR, LCD1602_DDRAM_ROW1|11);
|
||||
LCD_SendString(LCD1602_I2C_ADDR, "done");
|
||||
|
||||
LL_mDelay(2000);
|
||||
}
|
||||
}
|
||||
|
||||
static void APP_GPIO_Config(void)
|
||||
{
|
||||
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
|
||||
LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOF);
|
||||
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1);
|
||||
|
||||
/**
|
||||
* SCL: PF1 & AF_12, PA9 & AF_6
|
||||
* SDA: PF0 & AF_12, PA10 & AF_6
|
||||
*
|
||||
* Change pins to PF1 / PF0 for parts have no PA9 / PA10
|
||||
*/
|
||||
// PF1 SCL
|
||||
GPIO_InitStruct.Pin = LL_GPIO_PIN_1;
|
||||
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
|
||||
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
|
||||
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
|
||||
GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
|
||||
GPIO_InitStruct.Alternate = LL_GPIO_AF_12;
|
||||
LL_GPIO_Init(GPIOF, &GPIO_InitStruct);
|
||||
|
||||
// PF0 SDA
|
||||
GPIO_InitStruct.Pin = LL_GPIO_PIN_0;
|
||||
GPIO_InitStruct.Alternate = LL_GPIO_AF_12;
|
||||
LL_GPIO_Init(GPIOF, &GPIO_InitStruct);
|
||||
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1);
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C1);
|
||||
}
|
||||
|
||||
void APP_ErrorHandler(void)
|
||||
{
|
||||
while (1);
|
||||
}
|
||||
|
||||
#ifdef USE_FULL_ASSERT
|
||||
void assert_failed(uint8_t *file, uint32_t line)
|
||||
{
|
||||
while (1);
|
||||
}
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
43
Examples/LL/I2C/PCF8574_1602LCD/main.h
Normal file
43
Examples/LL/I2C/PCF8574_1602LCD/main.h
Normal file
@ -0,0 +1,43 @@
|
||||
// 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
|
||||
|
||||
#include "py32f0xx_ll_bus.h"
|
||||
#include "py32f0xx_ll_cortex.h"
|
||||
#include "py32f0xx_ll_dma.h"
|
||||
#include "py32f0xx_ll_exti.h"
|
||||
#include "py32f0xx_ll_gpio.h"
|
||||
#include "py32f0xx_ll_pwr.h"
|
||||
#include "py32f0xx_ll_rcc.h"
|
||||
#include "py32f0xx_ll_i2c.h"
|
||||
#include "py32f0xx_ll_system.h"
|
||||
#include "py32f0xx_ll_tim.h"
|
||||
#include "py32f0xx_ll_utils.h"
|
||||
|
||||
#include "bsp_i2c.h"
|
||||
|
||||
void APP_ErrorHandler(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MAIN_H */
|
||||
87
Examples/LL/I2C/PCF8574_1602LCD/pcf8574_lcd.c
Executable file
87
Examples/LL/I2C/PCF8574_1602LCD/pcf8574_lcd.c
Executable file
@ -0,0 +1,87 @@
|
||||
// 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.
|
||||
|
||||
#include "pcf8574_lcd.h"
|
||||
|
||||
|
||||
ErrorStatus LCD_SendInternal(uint8_t lcd_addr, uint8_t data, uint8_t flags)
|
||||
{
|
||||
ErrorStatus status;
|
||||
for(;;)
|
||||
{
|
||||
status = BSP_I2C_IsDeviceReady(lcd_addr, 5000);
|
||||
if(status == SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t up = data & 0xF0;
|
||||
uint8_t lo = (data << 4) & 0xF0;
|
||||
|
||||
uint8_t data_arr[4];
|
||||
data_arr[0] = up|flags|BACKLIGHT|PIN_EN;
|
||||
data_arr[1] = up|flags|BACKLIGHT;
|
||||
data_arr[2] = lo|flags|BACKLIGHT|PIN_EN;
|
||||
data_arr[3] = lo|flags|BACKLIGHT;
|
||||
|
||||
status = BSP_I2C_MasterTransmit(lcd_addr, data_arr, sizeof(data_arr), 5000);
|
||||
LL_mDelay(LCD1602_DELAY);
|
||||
return status;
|
||||
}
|
||||
|
||||
void LCD_SendCommand(uint8_t lcd_addr, uint8_t cmd)
|
||||
{
|
||||
LCD_SendInternal(lcd_addr, cmd, 0);
|
||||
}
|
||||
|
||||
void LCD_SendData(uint8_t lcd_addr, uint8_t data)
|
||||
{
|
||||
LCD_SendInternal(lcd_addr, data, PIN_RS);
|
||||
}
|
||||
|
||||
void LCD_SetCGRAM(uint8_t lcd_addr, uint8_t char_addr, const uint8_t *char_font)
|
||||
{
|
||||
uint8_t i = 8;
|
||||
|
||||
LCD_SendCommand(lcd_addr, LCD1602_CMD_CGRAM_ADDR | (char_addr << 3));
|
||||
|
||||
while(i--)
|
||||
{
|
||||
LCD_SendData(lcd_addr, *char_font++ );
|
||||
}
|
||||
|
||||
LCD_SendCommand(lcd_addr, LCD1602_CMD_CGRAM_ADDR);
|
||||
}
|
||||
|
||||
void LCD_Init(uint8_t lcd_addr)
|
||||
{
|
||||
// 4-bit mode, 2 lines, 5x8 format
|
||||
LCD_SendCommand(lcd_addr, LCD1602_CMD_FUNC_4B_2L_5X8);
|
||||
// display & cursor home
|
||||
LCD_SendCommand(lcd_addr, LCD1602_CMD_HOME);
|
||||
// display on, right shift, underline off, blink off
|
||||
LCD_SendCommand(lcd_addr, LCD1602_CMD_MODE_ON_CURSOR_BLNK);
|
||||
// clear display (optional here)
|
||||
LCD_SendCommand(lcd_addr, LCD1602_CMD_CLEAR_DISPLAY);
|
||||
}
|
||||
|
||||
void LCD_SendString(uint8_t lcd_addr, char *str)
|
||||
{
|
||||
while (*str)
|
||||
{
|
||||
LCD_SendData(lcd_addr, (uint8_t)(*str));
|
||||
str++;
|
||||
}
|
||||
}
|
||||
127
Examples/LL/I2C/PCF8574_1602LCD/pcf8574_lcd.h
Executable file
127
Examples/LL/I2C/PCF8574_1602LCD/pcf8574_lcd.h
Executable file
@ -0,0 +1,127 @@
|
||||
// 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.
|
||||
|
||||
/*-------------------------------------------------------------
|
||||
* Instruction D7 D6 D5 D4 D3 D2 D1 D0
|
||||
* ==============================================
|
||||
* Display clear 0 0 0 0 0 0 0 1
|
||||
* Cursor home 0 0 0 0 0 0 1 *
|
||||
* Entry Mode Set 0 0 0 0 0 1 I/D S
|
||||
* Display On/Off 0 0 0 0 1 D C B
|
||||
* Curs/Disp shift 0 0 0 1 S/C R/L * *
|
||||
* Function Set 0 0 1 DL N F * *
|
||||
* CG RAM addr set 0 1 ---------Acg---------
|
||||
* DD RAM addr set 1 -------------Add---------
|
||||
*
|
||||
* Meaning:
|
||||
* * - nonvalid bit
|
||||
* Acg - CG RAM address (CHARACTER GENERATOR)
|
||||
* Add - DD RAM address (DATA DISPLAY)
|
||||
* AC - adress counter
|
||||
*
|
||||
* I/D - 1-increment, 0-decrement
|
||||
* S - 1-display shift, 0-no display shift
|
||||
* D - 1-display ON, 0-display OFF
|
||||
* C - 1-cursor ON, 0-cursor OFF
|
||||
* B - 1-blink ON, 0-blink OFF
|
||||
* S/C - 1-display shift, 0-cursor movement
|
||||
* R/L - 1-right shift, 0-left shift
|
||||
* DL - 1-8 bits data transfer, 0-4 bits data transfer
|
||||
* N - 1-two lines, 0-one line
|
||||
* F - 1-5x10 dot matrix, 0-5x8 dot matrix
|
||||
* BF - 1-internal operation in progress, 0-display ready
|
||||
*
|
||||
\**************************************************************/
|
||||
|
||||
#ifndef __PCF8574_LCD_H__
|
||||
#define __PCF8574_LCD_H__
|
||||
|
||||
/* C++ detection */
|
||||
#ifdef __cplusplus
|
||||
extern C {
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "main.h"
|
||||
|
||||
|
||||
/* I2C address
|
||||
* - 7 bit slave address, left aligned, bits 7:1 are used, LSB bit is not used
|
||||
* - 0x4E or 0x7E
|
||||
*/
|
||||
#define LCD1602_I2C_ADDR 0x7E
|
||||
/* Delay in millisecond */
|
||||
#define LCD1602_DELAY 5
|
||||
/* Register selection */
|
||||
#define PIN_RS (1 << 0)
|
||||
/* Read/Write */
|
||||
#define PIN_RW (1 << 1)
|
||||
/* Chip enable */
|
||||
#define PIN_EN (1 << 2)
|
||||
/* Back light - might not be available on some PCF8574 modules */
|
||||
#define BACKLIGHT (1 << 3)
|
||||
|
||||
/* Clear display */
|
||||
#define LCD1602_CMD_CLEAR_DISPLAY 0b00000001
|
||||
/* Move cursor home */
|
||||
#define LCD1602_CMD_HOME 0b00000010
|
||||
|
||||
// Entry Mode, Set cursor/display moving direction
|
||||
#define LCD1602_CMD_DIRECTION_RIGHT 0b00000110
|
||||
#define LCD1602_CMD_DIRECTION_LEFT 0b00000100
|
||||
#define LCD1602_CMD_DIRECTION_RIGHT_SHIFT 0b00000111
|
||||
#define LCD1602_CMD_DIRECTION_LEFT_SHIFT 0b00000101
|
||||
// Display mode
|
||||
#define LCD1602_CMD_MODE_OFF 0b00001000
|
||||
#define LCD1602_CMD_MODE_ON_CURSOR_OFF 0b00001100
|
||||
#define LCD1602_CMD_MODE_ON_CURSOR_ON 0b00001110
|
||||
#define LCD1602_CMD_MODE_ON_CURSOR_BLNK 0b00001111
|
||||
// Cursor/Display Shift
|
||||
#define LCD1602_CMD_CURSOR_MOVE_LEFT 0b00010000
|
||||
#define LCD1602_CMD_CURSOR_MOVE_RIGHT 0b00010100
|
||||
#define LCD1602_CMD_DISPLAY_SHIFT_LEFT 0b00011000
|
||||
#define LCD1602_CMD_DISPLAY_SHIFT_RIGHT 0b00011100
|
||||
|
||||
/* Function set: 4-bit, 1 row, 5X8 matrix */
|
||||
#define LCD1602_CMD_FUNC_4B_1L_5X8 0b00100000
|
||||
/* Function set: 4-bit, 2 row, 5X8 matrix */
|
||||
#define LCD1602_CMD_FUNC_4B_2L_5X8 0b00101000
|
||||
/* Function set: 8-bit, 1 row, 5X8 matrix */
|
||||
#define LCD1602_CMD_FUNC_8B_1L_5X8 0b00110000
|
||||
/* Function set: 8-bit, 2 row, 5X8 matrix */
|
||||
#define LCD1602_CMD_FUNC_8B_2L_5X8 0b00111000
|
||||
/* Set/Read CGRAM address */
|
||||
#define LCD1602_CMD_CGRAM_ADDR 0b01000000
|
||||
/* Set/Read DDRAM address */
|
||||
#define LCD1602_CMD_DDRAM_ADDR 0b10000000
|
||||
|
||||
/* First row address */
|
||||
#define LCD1602_DDRAM_ROW0 0b10000000
|
||||
/* Second row address */
|
||||
#define LCD1602_DDRAM_ROW1 0b11000000
|
||||
|
||||
|
||||
void LCD_SendCommand(uint8_t lcd_addr, uint8_t cmd);
|
||||
void LCD_SendData(uint8_t lcd_addr, uint8_t data);
|
||||
void LCD_Init(uint8_t lcd_addr);
|
||||
void LCD_SendString(uint8_t lcd_addr, char *str);
|
||||
void LCD_SetCGRAM(uint8_t lcd_addr, uint8_t char_addr, const uint8_t *char_font);
|
||||
|
||||
/* C++ detection */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
40
Examples/LL/I2C/PCF8574_1602LCD/py32f0xx_it.c
Normal file
40
Examples/LL/I2C/PCF8574_1602LCD/py32f0xx_it.c
Normal file
@ -0,0 +1,40 @@
|
||||
#include "main.h"
|
||||
#include "py32f0xx_it.h"
|
||||
|
||||
/**
|
||||
* @brief This function handles Non maskable interrupt.
|
||||
*/
|
||||
void NMI_Handler(void)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Hard fault interrupt.
|
||||
*/
|
||||
void HardFault_Handler(void)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles System service call via SWI instruction.
|
||||
*/
|
||||
void SVC_Handler(void)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Pendable request for system service.
|
||||
*/
|
||||
void PendSV_Handler(void)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles System tick timer.
|
||||
*/
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
}
|
||||
19
Examples/LL/I2C/PCF8574_1602LCD/py32f0xx_it.h
Normal file
19
Examples/LL/I2C/PCF8574_1602LCD/py32f0xx_it.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef __PY32F0XX_IT_H
|
||||
#define __PY32F0XX_IT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void NMI_Handler(void);
|
||||
void HardFault_Handler(void);
|
||||
void SVC_Handler(void);
|
||||
void PendSV_Handler(void);
|
||||
void SysTick_Handler(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __PY32F0XX_IT_H */
|
||||
Loading…
x
Reference in New Issue
Block a user