#ifndef OLED_CFG_H_
#define OLED_CFG_H_
//
#ifdef __cplusplus
extern "C" {
#endif
//
#include "complier_lib.h"
#include "i2c_task.h"
#include "delay_task.h"
//
//===OLED的显存
//===存放格式如下.
//---[0]0 1 2 3 ... 127
//---[1]0 1 2 3 ... 127
//---[2]0 1 2 3 ... 127
//---[3]0 1 2 3 ... 127
//---[4]0 1 2 3 ... 127
//---[5]0 1 2 3 ... 127
//---[6]0 1 2 3 ... 127
//---[7]0 1 2 3 ... 127
//===定义大小
#define OLED_PAGE_SIZE 8
#define OLED_MAX_COL 128
#define OLED_MAX_ROW 64
#define OLED_XLevelL 0x02
#define OLED_XLevelH 0x10
#define OLED_Brightness 0xFF
#define OLED_X_WIDTH 128
#define OLED_Y_WIDTH 64
//===结构体定义
typedef struct _OLED_IIC_HandlerType OLED_IIC_HandlerType;
//===指针结构体定义
typedef struct _OLED_IIC_HandlerType *pOLED_IIC_HandlerType;
//===OLED的数据结构体
struct _OLED_IIC_HandlerType
{
GPIO_HandlerType msgRST; //---复位端口
I2C_HandlerType msgI2C; //---使用的I2C
};
//===定义的任务函数
#define OLED_TASK_ONE pOLEDI2CDevice0
#define OLED_TASK_TWO 0
#define OLED_TASK_THREE 0
extern const UINT8_T SYN_LOGO[];
//===外部调用接口
extern OLED_IIC_HandlerType g_OLEDI2CDevice0;
extern pOLED_IIC_HandlerType pOLEDI2CDevice0;
//===函数定义
UINT8_T OLED_I2C_Init(OLED_IIC_HandlerType *OLEDx, void(*pFuncDelayus)(UINT32_T delay), UINT8_T isHWI2C);
UINT8_T OLED_I2C_WriteCmd(OLED_IIC_HandlerType *OLEDx, UINT8_T cmd);
UINT8_T OLED_I2C_WriteData(OLED_IIC_HandlerType *OLEDx, UINT8_T cmd);
void OLED_I2C_DisplayON(OLED_IIC_HandlerType *OLEDx);
void OLED_I2C_DisplayOFF(OLED_IIC_HandlerType *OLEDx);
void OLED_I2C_Fill(OLED_IIC_HandlerType *OLEDx, UINT8_T dat);
void OLED_I2C_Clear(OLED_IIC_HandlerType *OLEDx);
void OLED_I2C_SetPos(OLED_IIC_HandlerType *OLEDx, UINT8_T xPos, UINT8_T yPos);
void OLED_I2C_HWInit(OLED_IIC_HandlerType *OLEDx);
void OLED_I2C_DrawBMP(OLED_IIC_HandlerType *OLEDx, UINT8_T x0Pos, UINT8_T y0Pos, UINT8_T x1Pos, UINT8_T y1Pos, UINT8_T BMP[]);
//
#ifdef __cplusplus
}
#endif
//
#endif /*OLED_CFG_H_ */
#include "oled_cfg.h"
//===全局变量
OLED_IIC_HandlerType g_OLEDI2CDevice0;
pOLED_IIC_HandlerType pOLEDI2CDevice0 = &g_OLEDI2CDevice0;
///
//函 数:
//功 能:
//输入参数:
//输出参数:
//说 明:
//
UINT8_T OLED_Device0_Init(OLED_IIC_HandlerType *OLEDx)
{
//---如果为6针的IIC模式,RES端口必须接入端口控制,否者需要拉高处理
//---RST端口的配置
OLEDx->msgRST.msgGPIOBit = LL_GPIO_PIN_5;
OLEDx->msgRST.msgGPIOPort = GPIOB;
//---端口初始化
if (OLEDx->msgRST.msgGPIOPort != NULL)
{
GPIOTask_Clock(OLEDx->msgRST.msgGPIOPort, 1);
}
//---GPIO的结构体
LL_GPIO_InitTypeDef GPIO_InitStruct = { 0 };
GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; //---配置状态为输出模式
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_MEDIUM; //---GPIO的速度---低速设备
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; //---输出模式---推挽输出
GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; //---上拉
#ifndef USE_MCU_STM32F1
GPIO_InitStruct.Alternate = LL_GPIO_AF_0; //---端口复用模式
#endif
//---RST端口的初始化
GPIO_InitStruct.Pin = OLEDx->msgRST.msgGPIOBit;
if (OLEDx->msgRST.msgGPIOPort != NULL)
{
LL_GPIO_Init(OLEDx->msgRST.msgGPIOPort, &GPIO_InitStruct);
GPIO_OUT_1(OLEDx->msgRST.msgGPIOPort, OLEDx->msgRST.msgGPIOBit);
}
//---I2C的配置
OLEDx->msgI2C.msgI2Cx = NULL;
OLEDx->msgI2C.msgSCL.msgGPIOPort = GPIOB;
OLEDx->msgI2C.msgSCL.msgGPIOBit = LL_GPIO_PIN_6;
OLEDx->msgI2C.msgSDA.msgGPIOPort = GPIOB;
OLEDx->msgI2C.msgSDA.msgGPIOBit = LL_GPIO_PIN_7;
OLEDx->msgI2C.msgModelIsHW = 0;
OLEDx->msgI2C.msgPluseWidth = 1;
OLEDx->msgI2C.msgFuncDelayus = NULL;
//---通过调整0R电阻,屏可以0x78和0x7A两个地址 -- 默认0x78
OLEDx->msgI2C.msgAddr = 0x78;
OLEDx->msgI2C.msgClockSpeed = 0;
return OK_0;
}
///
//函 数:
//功 能:
//输入参数:
//输出参数:
//说 明:
//
UINT8_T OLED_Device1_Init(OLED_IIC_HandlerType *OLEDx)
{
return OK_0;
}
///
//函 数:
//功 能:
//输入参数:
//输出参数:
//说 明:
//
UINT8_T OLED_Device2_Init(OLED_IIC_HandlerType *OLEDx)
{
return OK_0;
}
///
//函 数:
//功 能:
//输入参数:
//输出参数:
//说 明:
//
UINT8_T OLED_I2C_Init(OLED_IIC_HandlerType *OLEDx, void(*pFuncDelayus)(UINT32_T delay), UINT8_T isHWI2C)
{
UINT8_T _return = OK_0;
//---指定设备的初始化
if ((OLEDx != NULL) && (OLEDx == OLED_TASK_ONE))
{
OLED_Device0_Init(OLEDx);
}
else if ((OLEDx != NULL) && (OLEDx == OLED_TASK_TWO))
{
OLED_Device1_Init(OLEDx);
}
else if ((OLEDx != NULL) && (OLEDx == OLED_TASK_THREE))
{
OLED_Device2_Init(OLEDx);
}
else
{
return ERROR_1;
}
//---判断是硬件I2C还是软件I2C
if (isHWI2C)
{
//---初始化硬件I2C
_return = I2CTask_MHW_Init(&(OLEDx->msgI2C));
OLEDx->msgI2C.msgModelIsHW = 1;
}
else
{
//---初始化软件模拟I2C
_return = I2CTask_MSW_Init(&(OLEDx->msgI2C), pFuncDelayus);
OLEDx->msgI2C.msgModelIsHW = 0;
}
//---硬件初始化
OLED_I2C_HWInit(OLEDx);
return _return;
}
///
//函 数:
//功 能:
//输入参数:
//输出参数:
//说 明:
//
UINT8_T OLED_SWI2C_WriteByte(OLED_IIC_HandlerType *OLEDx, UINT8_T adddr, UINT8_T dat)
{
UINT8_T _return = OK_0;
//---启动并发送地址
_return = I2CTask_MSW_START(&(OLEDx->msgI2C), 1);
//if (_return != OK_0)
//{
// //---启动写数据失败
// _return = ERROR_2;
// goto GoToExit;
//}
//---发送寄存器地址
I2CTask_MSW_SendByte(&(OLEDx->msgI2C), adddr);
//---读取ACK
_return = I2CTask_MSW_ReadACK(&(OLEDx->msgI2C));
//if (_return != OK_0)
//{
// //---发送数据失败
// _return = ERROR_3;
// goto GoToExit;
//}
//---发送寄存器地址
I2CTask_MSW_SendByte(&(OLEDx->msgI2C), dat);
//---读取ACK
_return = I2CTask_MSW_ReadACK(&(OLEDx->msgI2C));
//GoToExit:
//---发送停止信号
I2CTask_MSW_STOP(&(OLEDx->msgI2C));
return _return;
}
///
//函 数:
//功 能:
//输入参数:
//输出参数:
//说 明:
//
UINT8_T OLED_HWI2C_WriteByte(OLED_IIC_HandlerType *OLEDx, UINT8_T adddr, UINT8_T dat)
{
return OK_0;
}
///
//函 数:
//功 能:
//输入参数:
//输出参数:
//说 明:
//
UINT8_T OLED_I2C_WriteByte(OLED_IIC_HandlerType *OLEDx, UINT8_T adddr, UINT8_T dat)
{
if (OLEDx->msgI2C.msgModelIsHW == 0)
{
return OLED_SWI2C_WriteByte(OLEDx, adddr, dat);
}
else
{
return OLED_HWI2C_WriteByte(OLEDx, adddr, dat);
}
}
///
//函 数:
//功 能:
//输入参数:
//输出参数:
//说 明:
//
UINT8_T OLED_I2C_WriteCmd(OLED_IIC_HandlerType *OLEDx, UINT8_T cmd)
{
return OLED_I2C_WriteByte(OLEDx, 0x00, cmd);
}
///
//函 数:
//功 能:
//输入参数:
//输出参数:
//说 明:
//
UINT8_T OLED_I2C_WriteData(OLED_IIC_HandlerType *OLEDx, UINT8_T cmd)
{
return OLED_I2C_WriteByte(OLEDx, 0x40, cmd);
}
///
//函 数:
//功 能:
//输入参数:
//输出参数:
//说 明:开启OLED显示
//
void OLED_I2C_DisplayON(OLED_IIC_HandlerType *OLEDx)
{
//---设置电荷泵
OLED_I2C_WriteCmd(OLEDx, 0x8D);
//---开启电荷泵
OLED_I2C_WriteCmd(OLEDx, 0x14);
//---OLED唤醒
OLED_I2C_WriteCmd(OLEDx, 0xAF);
}
///
//函 数:
//功 能:
//输入参数:
//输出参数:
//说 明:关闭OLED显示
//
void OLED_I2C_DisplayOFF(OLED_IIC_HandlerType *OLEDx)
{
//---设置电荷泵
OLED_I2C_WriteCmd(OLEDx, 0x8D);
//---关闭电荷泵
OLED_I2C_WriteCmd(OLEDx, 0x10);
//---OLED休眠
OLED_I2C_WriteCmd(OLEDx, 0xAE);
}
///
//函 数:
//功 能:
//输入参数:
//输出参数:
//说 明:全屏填充
//
void OLED_I2C_Fill(OLED_IIC_HandlerType *OLEDx, UINT8_T dat)
{
UINT8_T i = 0;
UINT8_T n = 0;
for (i = 0; i < OLED_PAGE_SIZE; i++)
{
//---设置页地址(0~7)
OLED_I2C_WriteCmd(OLEDx, (0xB0 + i));
//---设置显示位置—列低地址
OLED_I2C_WriteCmd(OLEDx, 0x00);
//---设置显示位置—列高地址
OLED_I2C_WriteCmd(OLEDx, 0x10);
for (n = 0; n < OLED_MAX_COL; n++)
{
//---更新显示
OLED_I2C_WriteData(OLEDx, dat);
}
}
}
///
//函 数:
//功 能:
//输入参数:
//输出参数:
//说 明:
//
void OLED_I2C_Clear(OLED_IIC_HandlerType *OLEDx)
{
OLED_I2C_Fill(OLEDx, 0x00);
}
///
//函 数:
//功 能:
//输入参数:
//输出参数:
//说 明:设置起始点坐标
//
void OLED_I2C_SetPos(OLED_IIC_HandlerType *OLEDx, UINT8_T xPos, UINT8_T yPos)
{
OLED_I2C_WriteCmd(OLEDx, (0xB0 + yPos));
OLED_I2C_WriteCmd(OLEDx, ((xPos & 0xf0) >> 4) | 0x10);
OLED_I2C_WriteCmd(OLEDx, (xPos & 0x0f) | 0x01);
}
///
//函 数:
//功 能:
//输入参数:
//输出参数:
//说 明:OLED的硬件的初始化
//
void OLED_I2C_HWInit(OLED_IIC_HandlerType *OLEDx)
{
if (OLEDx->msgRST.msgGPIOPort != NULL)
{
GPIO_OUT_1(OLEDx->msgRST.msgGPIOPort, OLEDx->msgRST.msgGPIOBit);
DelayTask_ms(100);
GPIO_OUT_0(OLEDx->msgRST.msgGPIOPort, OLEDx->msgRST.msgGPIOBit);
DelayTask_ms(100);
GPIO_OUT_1(OLEDx->msgRST.msgGPIOPort, OLEDx->msgRST.msgGPIOBit);
}
OLED_I2C_WriteCmd(OLEDx, 0xAE); //--display off
OLED_I2C_WriteCmd(OLEDx, 0x00); //---set low column address
OLED_I2C_WriteCmd(OLEDx, 0x10); //---set high column address
OLED_I2C_WriteCmd(OLEDx, 0x40); //--set start line address
OLED_I2C_WriteCmd(OLEDx, 0xB0); //--set page address
OLED_I2C_WriteCmd(OLEDx, 0x81); // contract control
OLED_I2C_WriteCmd(OLEDx, 0xFF); //--128
OLED_I2C_WriteCmd(OLEDx, 0xA1); //set segment remap
OLED_I2C_WriteCmd(OLEDx, 0xA6); //--normal / reverse
OLED_I2C_WriteCmd(OLEDx, 0xA8); //--set multiplex ratio(1 to 64)
OLED_I2C_WriteCmd(OLEDx, 0x3F); //--1/32 duty
OLED_I2C_WriteCmd(OLEDx, 0xC8); //Com scan direction
OLED_I2C_WriteCmd(OLEDx, 0xD3); //-set display offset
OLED_I2C_WriteCmd(OLEDx, 0x00); //
OLED_I2C_WriteCmd(OLEDx, 0xD5); //set osc division
OLED_I2C_WriteCmd(OLEDx, 0x80); //set divide ratio
OLED_I2C_WriteCmd(OLEDx, 0xD8); //set area color mode off
OLED_I2C_WriteCmd(OLEDx, 0x05); //
OLED_I2C_WriteCmd(OLEDx, 0xD9); //Set Pre-Charge Period
OLED_I2C_WriteCmd(OLEDx, 0xF1); //
OLED_I2C_WriteCmd(OLEDx, 0xDA); //set com pin configuartion
OLED_I2C_WriteCmd(OLEDx, 0x12); //
OLED_I2C_WriteCmd(OLEDx, 0xDB); //set Vcomh
OLED_I2C_WriteCmd(OLEDx, 0x30); //0x20,0.77xVcc
OLED_I2C_WriteCmd(OLEDx, 0x8D); //set charge pump enable
OLED_I2C_WriteCmd(OLEDx, 0x14); //
OLED_I2C_WriteCmd(OLEDx, 0xAF); //--turn on oled panel
}
///
//函 数:
//功 能:
//输入参数: x0,y0 -- 起始点坐标(x0:0~127, y0:0~7); x1,y1 -- 起点对角线(结束点)的坐标(x1:1~128,y1:1~8)
//输出参数:
//说 明:功能描述:显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7
//
void OLED_I2C_DrawBMP(OLED_IIC_HandlerType *OLEDx, UINT8_T x0Pos, UINT8_T y0Pos, UINT8_T x1Pos, UINT8_T y1Pos, UINT8_T BMP[])
{
UINT16_T j = 0;
UINT8_T x = 0;
UINT8_T y = 0;
//---判断地址是否超界限
if (x0Pos > (OLED_MAX_COL - 1))
{
x0Pos = (OLED_MAX_COL - 1);
}
if (y0Pos > (OLED_MAX_ROW - 1))
{
y0Pos = (OLED_MAX_ROW - 1);
}
if (x1Pos > (OLED_MAX_COL - 1))
{
x1Pos = (OLED_MAX_COL - 1);
}
if (y1Pos > (OLED_MAX_ROW - 1))
{
y1Pos = (OLED_MAX_ROW - 1);
}
//---判断数据位置
if (y1Pos % 8 == 0)
{
y = y1Pos / 8;
}
else
{
y = y1Pos / 8 + 1;
}
for (y = y0Pos; y < y1Pos; y++)
{
//---设置坐标
OLED_I2C_SetPos(OLEDx, x0Pos, y);
for (x = x0Pos; x < x1Pos; x++)
{
//---设置数据
OLED_I2C_WriteData(OLEDx, BMP[j++]);
}
}
}