/******************************************************************************
**文 件 名: OLED_I2C.c
**作 者: sdc
**生成日期: 2018年9月13日
**功能描述: 0.96寸(128 * 64)OLED屏驱动
******************************************************************************/
#include "esp_misc.h"
#include "i2c_driver.h"
#include "OLED_I2C.h"
#include "codetab.h"
#define OLED_I2C_WR 0 /* 写控制bit */
#define OLED_I2C_RD 1 /* 读控制bit */
/*****************************************************************************
**函 数 名: __OLED_Check_Device
**输入参数: UINT8 _Address:设备的I2C总线地址
**输出参数: 无
**返 回 值: 0:检测到OLED
1:未检测到
**功能描述: 检测I2C总线设备,CPU向发送设备地址,然后读取设备应答来判断该设备是否存在
**作 者: sdc
*****************************************************************************/
static UINT8 __OLED_Check_Device(UINT8 _Address)
{
UINT8 ucAck;
I2c_Start(); /* 发送启动信号 */
I2c_Send_Byte(_Address|OLED_I2C_WR);/* 发送设备地址 */
ucAck = I2c_Wait_Ack(); /* 检测设备的ACK应答 */
I2c_Stop(); /* 发送停止信号 */
return ucAck;
}
/*****************************************************************************
**函 数 名: __I2C_Write_Byte
**输入参数: UINT8 addr:寄存器地址
UINT8 data:要写入的数据
**输出参数: 无
**返 回 值:
**功能描述: 向OLED寄存器地址写一个byte的数据
**作 者: sdc
*****************************************************************************/
static void __I2C_Write_Byte(UINT8 addr,UINT8 data)
{
I2c_Start();//开启I2C总线
/* 发送设备地址+读写控制bit(0 = w, 1 = r) bit7 先传 */
I2c_Send_Byte(OLED_ADDRESS | OLED_I2C_WR);
/*等待ACK */
if (I2c_Wait_Ack() != 0)
{
goto cmd_fail; /* OLED器件无应答 */
}
I2c_Send_Byte(addr);//发送寄存器地址
/*等待ACK */
if (I2c_Wait_Ack() != 0)
{
goto cmd_fail; /* OLED器件无应答 */
}
I2c_Send_Byte(data);//发送数据
/*等待ACK */
if (I2c_Wait_Ack() != 0)
{
goto cmd_fail; /* OLED器件无应答 */
}
/* 发送I2C总线停止信号 */
I2c_Stop();
cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 */
/* 发送I2C总线停止信号 */
I2c_Stop();
}
/*****************************************************************************
**函 数 名: __OLED_Write_Cmd
**输入参数: UINT8 I2C_Command:命令代码
**输出参数: 无
**返 回 值:
**功能描述: 向OLED写入命令
**作 者: sdc
*****************************************************************************/
static void __OLED_Write_Cmd(UINT8 I2C_Command)
{
__I2C_Write_Byte(0x00, I2C_Command);
}
/*****************************************************************************
**函 数 名: __OLED_Write_Data
**输入参数: UINT8 I2C_Data:需要写入的数据
**输出参数: 无
**返 回 值:
**功能描述: 向OLED写入数据
**作 者: sdc
*****************************************************************************/
void __OLED_Write_Data(UINT8 I2C_Data)
{
__I2C_Write_Byte(0x40, I2C_Data);
}
/*****************************************************************************
**函 数 名: __OLED_Clear_Page
**输入参数: UINT8 page:页码(0~7)
**输出参数: 无
**返 回 值: static
**功能描述: 清空某一页(8行)的显示内容
**作 者: sdc
*****************************************************************************/
static void __OLED_Clear_Page(UINT8 page)
{
UINT16 i = 0;
if(7 < page)
{
return;
}
__OLED_Write_Cmd(0xb0 + page);
__OLED_Write_Cmd(0x10); /*列地址高4位*/
__OLED_Write_Cmd(0x00); /*列地址低4位*/
for(i = 0; i < 128; i++)
{
__OLED_Write_Data(00);
}
}
/*****************************************************************************
**函 数 名: OLED_Set_Pos
**输入参数: UINT8 x:光标x位置,行位置
UINT8 y:光标y位置,列位置
**输出参数: 无
**返 回 值:
**功能描述: 设置光标位置
**作 者: sdc
*****************************************************************************/
void OLED_Set_Pos(UINT8 x, UINT8 y)
{
__OLED_Write_Cmd(0xb0 + y); /*页地址(行地址)*/
__OLED_Write_Cmd(((x & 0xf0) >> 4) | 0x10); /*列地址高4位*/
__OLED_Write_Cmd((x & 0x0f) | 0x01); /*列地址低4位*/
}
/*****************************************************************************
**函 数 名: OLED_Fill
**输入参数: UINT8 fill_Data:要填充的数据
**输出参数: 无
**返 回 值:
**功能描述: 填充整个屏幕
**作 者: sdc
*****************************************************************************/
void OLED_Fill(UINT8 fill_Data)
{
UINT8 i = 0;
UINT8 j = 0;
for(i = 0; i< 8; i++)
{
__OLED_Write_Cmd(0xb0 + i); //page0-page1
__OLED_Write_Cmd(0x00); //low column start address
__OLED_Write_Cmd(0x10); //high column start address
for(j = 0; j < 128; j++)
{
__OLED_Write_Data(fill_Data);
}
}
}
/*****************************************************************************
**函 数 名: OLED_Clear
**输入参数: void
**输出参数: 无
**返 回 值:
**功能描述: 清屏
**作 者: sdc
*****************************************************************************/
void OLED_Clear(void)
{
OLED_Fill(0x00);
}
/*****************************************************************************
**函 数 名: OLED_On
**输入参数: void
**输出参数: 无
**返 回 值:
**功能描述: 将OLED从休眠中唤醒
**作 者: sdc
*****************************************************************************/
void OLED_On(void)
{
__OLED_Write_Cmd(0X8D); //设置电荷泵
__OLED_Write_Cmd(0X14); //开启电荷泵
__OLED_Write_Cmd(0XAF); //OLED唤醒
}
/*****************************************************************************
**函 数 名: OLED_Off
**输入参数: void
**输出参数: 无
**返 回 值:
**功能描述: 让OLED休眠 -- 休眠模式下,OLED功耗需要测试
**作 者: sdc
*****************************************************************************/
void OLED_Off(void)
{
__OLED_Write_Cmd(0X8D); //设置电荷泵
__OLED_Write_Cmd(0X10); //关闭电荷泵
__OLED_Write_Cmd(0XAE); //OLED休眠
}
/*****************************************************************************
**函 数 名: OLED_Display_String
**输入参数: UINT8 x:起始点坐标(x:0~127, y:0~7);
UINT8 y
UINT8 *ch:要显示的字符串
UINT8 TextSize:字符大小(1:6*8 ; 2:8*16)
**输出参数: 无
**返 回 值:
**功能描述: 显示codetab.h中的ASCII字符,有6*8和8*16可选择
**作 者: sdc
*****************************************************************************/
void OLED_Display_String(UINT8 x, UINT8 y, UINT8 *ch, UINT8 TextSize)
{
UINT8 c = 0;
UINT8 i = 0;
UINT8 j = 0;
switch(TextSize)
{
case 1:
__OLED_Clear_Page(y);
while(ch[j] != '\0')
{
c = ch[j] - 32;
if(x > 126)
{
x = 0;
y++;
}
OLED_Set_Pos(x,y);
for(i = 0; i < 6; i++)
{
__OLED_Write_Data(F6x8[c][i]);
}
x += 6;
j++;
}
break;
case 2:
__OLED_Clear_Page(y);
__OLED_Clear_Page(y + 1);
while(ch[j] != '\0')
{
c = ch[j] - 32;
if(x > 120)
{
x = 0;
y++;
}
OLED_Set_Pos(x, y);
for(i = 0; i < 8; i++)
{
__OLED_Write_Data(F8X16[c*16+i]);
}
OLED_Set_Pos(x, y + 1);
for(i = 0; i < 8; i++)
{
__OLED_Write_Data(F8X1