单片机 MM32 HAL OLED c语言 代码

/* -----------------------------------------头文件-----------------------------------------*/
#include "OLED.h"
#include "hal_iic.h"
#include "Map.h"
/* -----------------------------------------宏定义-----------------------------------------*/
/* -----------------------------------------结构体定义-------------------------------------*/
const IIC_PIN  OLED_GPIO =
{
    .SCL_PORT   = IIC_SCL_GPIO_Port,
    .SCL_PIN    = IIC_SCL_Pin,
    .SDA_PORT   = IIC_SDA_GPIO_Port,
    .SDA_PIN    = IIC_SDA_Pin,
    .DelayTick  = 1,
    .ADDR       = 0x78
};
OLED_Refresh OLED_Refresh_Flag = {0};
OLED_Refresh_Word1 OLED_Refresh_Word1_Flag = {0};
OLED_Refresh_Word2 OLED_Refresh_Word2_Flag = {0};
/* -----------------------------------------全局变量定义-----------------------------------*/
uint8_t OLED_Page = 0; //0--待机界面  1--工作界面1  2--工作界面2  3--缺电界面  4--充电界面  5--温度异常界面   6--电池异常(工作)  7--电池异常(待机)
/* -----------------------------------------应用程序---------------------------------------*/

/*********************************************
函数名:OLED_init
功  能:初始化OLED 引脚及器件初始化
形  参:
返回值:
备  注:
作  者:薛建强
时  间:2019/12/23
使  用:
**********************************************/
void OLED_init(void)
{
    /*使能指定GPIO寄存器*/
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB, ENABLE);
    GPIO_InitTypeDef GPIO_InitStructure;
    /*配置OLED_EN引脚(即CS脚)*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    /*配置RESB引脚(即背光脚。备注:调节屏幕亮度需要配置为PWM,否则只能亮或不亮)*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    Oled_Open();//OLED背光引脚   0--关闭  1--打开
    IIC_Init(&OLED_GPIO);//初始化IIC通讯

    OledCS_Set();//打开OLED通讯
    OledCS_Clr();//关闭OLED通讯
    OledCS_Set();//打开OLED通讯

    /*0.96寸OLED屏数据手册--21页(厂家初始化代码)*/
    OLED_send_byte(0xae, OLED_CMD);//--关闭oled面板
    OLED_send_byte(0x00, OLED_CMD);//--设置低位列地址
    OLED_send_byte(0x10, OLED_CMD);//--设置高位列地址
    OLED_send_byte(0x40, OLED_CMD);//--设置起始行地址设置映射RAM显示起始行 (0x00~0x3F)
    OLED_send_byte(0x81, OLED_CMD);//--设置对比度控制寄存器
    OLED_send_byte(0xff, OLED_CMD);//--设置SEG输出电流亮度
    OLED_send_byte(0xa1, OLED_CMD);//--设置分段/列映射     0xa0左右反置 0xa1正常
    OLED_send_byte(0xc8, OLED_CMD);//--设置COM/行扫描方向   0xc0上下反置 0xc8正常
    OLED_send_byte(0xa6, OLED_CMD);//--设置正常显示
    OLED_send_byte(0xa8, OLED_CMD);//--设置多路复用比率(1到64)
    OLED_send_byte(0x3f, OLED_CMD);//--1/64负荷
    OLED_send_byte(0xd3, OLED_CMD);//--设置显示偏移移位映射RAM计数器(0x00~0x3F)
    OLED_send_byte(0x00, OLED_CMD);//--不偏移

    OLED_send_byte(0xd5, OLED_CMD);//--设置显示分时比/振荡器频率
    OLED_send_byte(0x80, OLED_CMD);//--设置分频比,将时钟设置为100帧/秒
    OLED_send_byte(0xd9, OLED_CMD);//--设置 预充电周期
    OLED_send_byte(0xf1, OLED_CMD);//--预充电设为15时钟,放电设为1时钟
    OLED_send_byte(0xda, OLED_CMD);//--设置com引脚硬件配置
    OLED_send_byte(0x12, OLED_CMD);
    OLED_send_byte(0xdb, OLED_CMD);//--设置 共通电位 (高)
    OLED_send_byte(0x40, OLED_CMD);//--设置VCOM取消选择级别
    OLED_send_byte(0x20, OLED_CMD);//--设置页面寻址模式(0x00/0x01/0x02)
    OLED_send_byte(0x02, OLED_CMD);//
    OLED_send_byte(0x8d, OLED_CMD);//--设置预充电 启用/禁用
    OLED_send_byte(0x14, OLED_CMD);//--set(0x10) disable

    OLED_send_byte(0xa4, OLED_CMD);// 禁用上的整个显示 (0xa4/0xa5)
    OLED_send_byte(0xa6, OLED_CMD);// 禁用反向显示打开 (0xa6/0xa7)
    OLED_cls(); //清屏
    OLED_open_BL(0, 0); //显示背光或设置光标坐标
    OLED_open_display();//打开OLED屏幕
}


/*********************************************
函数名:OLED_send_byte
功  能:向SSH1106写入一个字节
形  参:dat: 待写入的字节
        cmd: 0--命令  1--数据
返回值:无
备  注:1.3寸OLED屏数据手册--12页
作  者:薛建强
时  间:2019/12/23
使  用:
**********************************************/
void OLED_send_byte(const uint8_t dat, const uint8_t cmd)
{
    /*IIC通讯*/
    IIC_Start(&OLED_GPIO);
    IIC_WriteByte(&OLED_GPIO, OLED_GPIO.ADDR); //写命令
    IIC_Wait_ACK(&OLED_GPIO);

    if (cmd == 0)
    {
        IIC_WriteByte(&OLED_GPIO, 0x00);  //命令
    }
    else if (cmd == 1)
    {
        IIC_WriteByte(&OLED_GPIO, 0x40); //数据
    }

    IIC_Wait_ACK(&OLED_GPIO);
    IIC_WriteByte(&OLED_GPIO, dat);
    IIC_Wait_ACK(&OLED_GPIO);
    IIC_Stop(&OLED_GPIO);
}


/*********************************************
函数名:OLED_open_BL
功  能:点亮屏幕背光(清屏会导致屏幕失去背光)或 设置起始地址
形  参:
返回值:
备  注:
作  者:薛建强
时  间:2019/12/23
使  用:
**********************************************/
void OLED_open_BL(uint8_t x, uint8_t y)
{
    x += 2;  //SSH1106 要加这个
    OLED_send_byte(0xb0 + y, OLED_CMD);
    OLED_send_byte(((x & 0xf0) >> 4) | 0x10, OLED_CMD);
    OLED_send_byte((x & 0x0f) | 0x01, OLED_CMD);
}

/*********************************************
函数名:OLED_cls
功  能:OLED清屏函数
形  参:
返回值:
备  注:列低地址实际上是 0x02 + 0 = 0
        列高地址实际上是 0x10 + 0 = 0
        由上可知,起点坐标为(0,0)
        0:无点 1:有点
作  者:薛建强
时  间:2019/12/23
使  用:
**********************************************/
void OLED_cls(void)
{
    uint8_t i, n;
    for (i = 0; i < 8; i++)
    {
        OLED_send_byte(0xb0 + i, OLED_CMD);  //设置页地址(0~7)
        OLED_send_byte(0x01, OLED_CMD);      //设置显示位置—列低地址
        OLED_send_byte(0x10, OLED_CMD);      //设置显示位置—列高地址
        for (n = 0; n < 129; n++)
        {
            OLED_send_byte(0x00, OLED_DATA); //发送0,清除该点
        }
    }
}

/*********************************************
函数名:OLED_cls1
功  能:OLED清屏函数
形  参:
返回值:
备  注:列低地址实际上是 0x02 + 0 = 0
        列高地址实际上是 0x10 + 0 = 0
        由上可知,起点坐标为(0,0)
        0:无点 1:有点
作  者:薛建强
时  间:2019/12/23
使  用:
**********************************************/
void OLED_cls1(void)
{
    uint8_t i, n;
    for (i = 0; i < 8; i++)
    {
        OLED_send_byte(0xb0 + i, OLED_CMD);  //设置页地址(0~7)
        OLED_send_byte(0x01, OLED_CMD);      //设置显示位置—列低地址
        OLED_send_byte(0x10, OLED_CMD);      //设置显示位置—列高地址
        for (n = 0; n < 129; n++)
        {
            OLED_send_byte(0x00, OLED_DATA); //发送1,点亮该点
        }
    }
}

/********************************
函数:OLED_open_display
功能:打开OLED屏幕
*********************************/
void OLED_open_display(void)
{
    OLED_send_byte(0X8D, OLED_CMD); //SET DCDC命令
    OLED_send_byte(0X14, OLED_CMD); //DCDC ON
    OLED_send_byte(0XAF, OLED_CMD); //DISPLAY ON
}

/********************************
函数:OLED_open_display
功能:关闭OLED屏幕
*********************************/
void OLED_off_display(void)
{
    OLED_send_byte(0X8D, OLED_CMD); //SET DCDC命令
    OLED_send_byte(0X10, OLED_CMD); //DCDC ON
    OLED_send_byte(0XAE, OLED_CMD); //DISPLAY OFF
}




/*******************************************用户自定义区****************************************/
void OLED_Draw_BMP(const uint8_t Start_x, const uint8_t Start_y, \
                   const uint8_t Size_x,  const uint8_t Size_y, const uint8_t N, const uint8_t BMP[])
{
    uint16_t adder = N * (Size_x * Size_y) / 8;//计算图片起始地址
    uint8_t Now_X = 0, Now_Y = 0;
    for (Now_X = 0; Now_X < (Size_x / 8); Now_X++)
    {
        OLED_open_BL(Start_x, Start_y + Now_X);//设置每行原点
        for (Now_Y = 0; Now_Y < Size_y; Now_Y++)
        {
            if (N == 0xFF)
            {
                OLED_send_byte(0x00, OLED_DATA);
            }
            else
            {
                OLED_send_byte(BMP[adder], OLED_DATA);
            }
            adder += 1;
        }
    }
}

static void Draw_48X72BMP(uint8_t x, uint8_t y, uint8_t N, const uint8_t BMP[])
{
    OLED_Draw_BMP(x, y, 48, 72, N, BMP);
}
static void Draw_48X72BMP_cls(uint8_t x, uint8_t y)
{
    OLED_Draw_BMP(x, y, 48, 72, 0XFF, 0x00);
}

/******功能描述:显示8*16一组标准ASCII字符串    显示的坐标(x,y),y为页范围0~7*********/
static void OLED_P8x16Str(uint8_t x, uint8_t y, uint8_t N, const uint8_t BMP[])
{
    OLED_Draw_BMP(x, y, 8, 16, N, BMP);
}
static void OLED_P8x16Str_cls(uint8_t x, uint8_t y)
{
    OLED_Draw_BMP(x, y, 8, 16, 0XFF, 0x00);
}

//*****************功能描述:显示24*16点阵  显示的坐标(x,y),y为页范围0~7****************************/
static void OLED_P24x16Ch(uint8_t x, uint8_t y, uint8_t N, const uint8_t BMP[])
{
    OLED_Draw_BMP(x, y, 24, 16, N, BMP);
}
static void OLED_P24x16Ch_cls(uint8_t x, uint8_t y)
{
    OLED_Draw_BMP(x, y, 24, 16, 0XFF, 0x00);
}
//*****************功能描述:显示32*12点阵  显示的坐标(x,y),y为页范围0~7****************************/
static void OLED_P32x12Ch(uint8_t x, uint8_t y, uint8_t N, const uint8_t BMP[])
{
    OLED_Draw_BMP(x, y, 32, 12, N, BMP);
}
static void OLED_P32x12Ch_cls(uint8_t x, uint8_t y)
{
    OLED_Draw_BMP(x, y, 32, 12, 0XFF, 0x00);
}

/*****************功能描述:显示24*32点阵  显示的坐标(x,y),y为页范围0~7****************************/
static void OLED_P24x32Ch(uint8_t x, uint8_t y, uint8_t N, const uint8_t BMP[])
{
    OLED_Draw_BMP(x, y, 24, 32, N, BMP);
}
static void OLED_P24x32Ch_cls(uint8_t x, uint8_t y)
{
    OLED_Draw_BMP(x, y, 24, 32, 0XFF, 0x00);
}
/*****************功能描述:显示64*32点阵  显示的坐标(x,y),y为页范围0~7****************************/
static void OLED_P32x16Ch(uint8_t x, uint8_t y, uint8_t N, const uint8_t BMP[])
{
    OLED_Draw_BMP(x, y, 32, 16, N, BMP);

}
static void OLED_P16x32Ch_cls(uint8_t x, uint8_t y)
{
    OLED_Draw_BMP(x, y, 16, 32, 0XFF, 0x00);
}
/*****************功能描述:显示64*32点阵  显示的坐标(x,y),y为页范围0~7****************************/
static void OLED_P64x32Ch(uint8_t x, uint8_t y, uint8_t N, const uint8_t BMP[])
{
    OLED_Draw_BMP(x, y, 64, 32, N, BMP);
}

/*****************功能描述:显示16*16点阵  显示的坐标(x,y),y为页范围0~7****************************/
static void OLED_P16x16Ch(uint8_t x, uint8_t y, uint8_t N, const uint8_t BMP[])
{
    OLED_Draw_BMP(x, y, 16, 16, N, BMP);
}
/*****************功能描述:显示16*48点阵  显示的坐标(x,y),y为页范围0~7****************************/
static void OLED_P48x16Ch(uint8_t x, uint8_t y, uint8_t N, const uint8_t BMP[])
{
    OLED_Draw_BMP(x, y, 48, 16, N, BMP);
}
/********************************************************************************************************
**函数信息 :Draw_BMP(u8 x0,u8 y0,u8 x1,u8 y1,u8  BMP[])
**功能描述 :             显示一张图片
**输入参数 : x0 y0 x1 y1 Map[]
**输出参数 :               无
********************************************************************************************************/
void Draw_BMP(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, const uint8_t  BMP[])
{
    uint16_t j = 0;
    uint8_t  x = 0, y = 0;
    for (y = y0; y < y1; y++)
    {
        OLED_open_BL(x0, y);
        for (x = x0; x < x1; x++)
        {
            OLED_send_byte(BMP[j++], OLED_DATA);
        }
    }
}
/***********************************************************GUI绘制***************************************************************/
/*********************************************
函数名:OLED_show_Battery_Max
功  能:待机界面显示电池电量信息
形  参:
返回值:
备  注:
作  者:薛建强
时  间:2019/12/12
使  用:
**********************************************/
void OLED_show_Battery_Max(const uint8_t OnOff)
{
    if (OnOff == 1)
    {
        if (Battery_old != EG2801_RAM_DATA.StateOfCharge)
        {
            Battery_old = EG2801_RAM_DATA.StateOfCharge;
            OLED_Refresh_Flag.StandbyBattery = 1;//刷新待机界面
        }
        if (OLED_Refresh_Flag.StandbyBattery == 1)
        {
            OLED_Refresh_Flag.StandbyBattery = 0;//停止刷新待机界面
            OLED_off_display();  //关闭屏幕
            if (Battery_old == 0) //电量等于0,不开机,且显示充电标志
            {
                Draw_48X72BMP(30, 1, 0, LowBatter);                //   低电压图标
            }
            /*显示图形电量*/
            else if (Battery_old <= 25)
            {
                Draw_48X72BMP(30, 1, 2, LowBatter);                //    一格电量
            }
            else if (Battery_old > 25 && Battery_old <= 50)
            {
                Draw_48X72BMP(30, 1, 3, LowBatter);                //    二格电量
            }
            else if (Battery_old > 50 && Battery_old <= 75)
            {
                Draw_48X72BMP(30, 1, 4, LowBatter);                //    三格电量
            }
            else if (Battery_old > 75 && Battery_old <= 100)
            {
                Draw_48X72BMP(30, 1, 5, LowBatter);                //    四格电量
            }

            /*显示数字电量*/
            if (Battery_old < 100)
            {
                OLED_P8x16Str(14, 2, 11, SDigital);                //    空格
                OLED_P8x16Str(14, 3, Battery_old / 10, SDigital);
                OLED_P8x16Str(14, 4, Battery_old % 10, SDigital);  //    <= 99
            }
            else
            {
                OLED_P24x16Ch(14, 2, 0, SHundred);             //    100
            }
            OLED_P8x16Str(14, 5, 10, SDigital);                //    %

            OLED_open_display();  //   开显示
        }
    }
    else
    {
        Draw_48X72BMP_cls(30, 1);//清除
        OLED_P24x16Ch_cls(14, 2);//清除
        OLED_P8x16Str_cls(14, 5);//%
    }
}
/*********************************************
函数名:OLED_show_Battery_Charge
功  能:待机界面显示电池充电状态
形  参:
返回值:
备  注:
作  者:薛建强
时  间:2019/12/12
使  用:
**********************************************/
void OLED_show_Battery_Charge(const uint8_t OnOff)
{
    static uint8_t time = 0;
    if (OnOff == 1)
    {
        if (Battery_old != EG2801_RAM_DATA.StateOfCharge || OLED_Page != 4)
        {
            Battery_old = EG2801_RAM_DATA.StateOfCharge;
            OLED_Refresh_Flag.StandbyBattery = 1;//刷新待机界面
        }
        if (OLED_Refresh_Flag.StandbyBattery == 1)
        {
            OLED_Refresh_Flag.StandbyBattery = 0;
            /*显示图形电量*/
            if (Battery_old <= 25)
            {
                Draw_48X72BMP(30, 1, 1, LowBatter);                //    空格电量
            }
            else if (Battery_old > 25 && Battery_old <= 50)
            {
                Draw_48X72BMP(30, 1, 2, LowBatter);                //    一格电量
            }
            else if (Battery_old > 50 && Battery_old <= 75)
            {
                Draw_48X72BMP(30, 1, 3, LowBatter);                //    二格电量
            }
            else if (Battery_old > 75 && Battery_old < 100)
            {
                Draw_48X72BMP(30, 1, 4, LowBatter);                //    三格电量
            }
            else
            {
                Draw_48X72BMP(30, 1, 5, LowBatter);                //    四格电量
            }
            /*显示数字电量*/
            if (Battery_old < 100)
            {
                OLED_P8x16Str(14, 2, 11, SDigital);                //    空格
                OLED_P8x16Str(14, 3, Battery_old / 10, SDigital);
                OLED_P8x16Str(14, 4, Battery_old % 10, SDigital);  //    <= 99
            }
            else
            {
                OLED_P24x16Ch(14, 2, 0, SHundred);                 //    100
            }
            OLED_P8x16Str(14, 5, 10, SDigital);                    //    %
            OLED_open_display();  //   开显示
        }
        /*显示图形电量*/
        if (Battery_old <= 25)
        {
            if (time < 15 && ++time < 10)
            {
                if (time == 1)
                {
                    OLED_P32x12Ch(36, 2, 0, MaxBatter_lattice);//显示第一格
                }
                else if (time == 6)
                {
                    OLED_P32x12Ch_cls(36, 2);//清除第一格
                }
            }
            else
            {
                time = 0;
            }
        }
        else if (Battery_old > 25 && Battery_old <= 50)
        {
            if (time < 15 && ++time < 10)
            {
                if (time == 1)
                {
                    OLED_P32x12Ch(50, 2, 0, MaxBatter_lattice);//显示第二格
                }
                else if (time == 6)
                {
                    OLED_P32x12Ch_cls(50, 2);//清除第二格
                }
            }
            else
            {
                time = 0;
            }
        }
        else if (Battery_old > 50 && Battery_old <= 75)
        {
            if (time < 15 && ++time < 10)
            {
                if (time == 1)
                {
                    OLED_P32x12Ch(66, 2, 0, MaxBatter_lattice);//显示第三格
                }
                else if (time == 6)
                {
                    OLED_P32x12Ch_cls(66, 2);//清除第三格
                }
            }
            else
            {
                time = 0;
            }
        }
        else if (Battery_old > 75 && Battery_old < 100)
        {
            if (time < 15 && ++time < 10)
            {
                if (time == 1)
                {
                    OLED_P32x12Ch(80, 2, 0, MaxBatter_lattice);//显示第四格
                }
                else if (time == 6)
                {
                    OLED_P32x12Ch_cls(80, 2);//清除第四格
                }
            }
            else
            {
                time = 0;
            }
        }
        else
        {
            OLED_P32x12Ch(80, 2, 0, MaxBatter_lattice);//显示第四格
        }
    }
    else
    {
        Draw_48X72BMP_cls(30, 1);  //清除
        OLED_P24x16Ch_cls(14, 2);  //清除
        OLED_P8x16Str_cls(14, 5);  //%
    }
}



/*********************************************
函数名:OLED_Show_Logo
功  能:显示开机Logo
形  参:
返回值:
备  注:
作  者:薛建强
时  间:2019/12/23
使  用:
**********************************************/
void OLED_Show_Logo(void)
{
    OLED_off_display();  //关闭屏幕
    OLED_cls();
    Draw_BMP(12, 2, 124, 6, Logo); //   公司Logo显示  图片大小112*32:  宽--》124-12=112   高--》(6-2)*8
    OLED_open_display();  //开启屏幕
}



/*********************************************
函数名:OLED_Show_UpInfor
功  能:显示工作界面的上边信息   灯光类型   电池电量格
形  参:
返回值:
备  注:
作  者:薛建强
时  间:2019/12/18
使  用:
**********************************************/
void OLED_Show_UpInfor(void)
{
    static uint8_t Light_type_old = 0, Battery_Square_old = 0;
    if (OLED_Refresh_Flag.Light_type == 2)
    {
        OLED_Refresh_Flag.Light_type = 1;
        Light_type_old = SystemReg.Mode;
    }
    if (OLED_Refresh_Flag.Battery_Square == 2)
    {
        OLED_Refresh_Flag.Battery_Square = 1;
        Battery_Square_old = (EG2801_RAM_DATA.StateOfCharge / 20) + 1;
    }
    if ((EG2801_RAM_DATA.StateOfCharge / 20) + 1 > Battery_Square_old)
    {
        Battery_Square_old = (EG2801_RAM_DATA.StateOfCharge / 20) + 1;
        OLED_Refresh_Flag.Battery_Square = 1;//刷新工作界面1--上方电量方格
    }
    if (Light_type_old != SystemReg.Mode)
    {
        Light_type_old = SystemReg.Mode;
        OLED_Refresh_Flag.Light_type = 1;//刷新工作界面1--灯光类型
    }
    if (EG2801_RAM_DATA.Flags == 0xFFFF)
    {
        Battery_Square_old = 5;
        OLED_Refresh_Flag.Battery_Square = 1;
    }
    if (OLED_Refresh_Flag.Battery_Square == 1)//刷新工作界面1--上方电量方格
    {
        switch (Battery_Square_old)
        {
            case 0:
            case 1:
                OLED_P48x16Ch(110, 2, 0, BatteryCapacity); //  一格电量
                break;
            case 2:
                OLED_P48x16Ch(110, 2, 1, BatteryCapacity); //  两格电量
                break;
            case 3:
                OLED_P48x16Ch(110, 2, 2, BatteryCapacity); //  三格电量
                break;
            case 4:
                OLED_P48x16Ch(110, 2, 3, BatteryCapacity); //  四格电量
                break;
            case 5:
            case 6:
                OLED_P48x16Ch(110, 2, 4, BatteryCapacity); //  五格电量
                break;
            default:
                break;
        }
        OLED_Refresh_Flag.Battery_Square = 0;    //停止刷新
    }

    if (OLED_Refresh_Flag.Light_type == 1)   //刷新工作界面1--灯光类型
    {
        switch (Light_type_old)
        {
            case 0:
                OLED_P16x16Ch(110, 0, 1, ControlGear);                 /*  无左右  */
                break;
            case 1:
                OLED_P16x16Ch(110, 0, 2, ControlGear);                 /*   左灯   */
                break;
            case 2:
                OLED_P16x16Ch(110, 0, 3, ControlGear);                 /*   右灯   */
                break;
            case 3:
                OLED_P16x16Ch(110, 0, 4, ControlGear);                 /*   左右灯 */
                break;
            case 4:
                OLED_P16x16Ch(110, 0, 5, ControlGear);                 /*   闪烁   */
                break;
            default:
                break;
        }
        OLED_Refresh_Flag.Light_type = 0;    //停止刷新
    }
}

/*********************************************
函数名:OLED_Show_work1
功  能:显示工作界面1
形  参:
返回值:
备  注:
作  者:薛建强
时  间:2019/12/18
使  用:
**********************************************/
void OLED_Show_work1(const uint8_t ch)
{
    static uint8_t Battery_Flag = 0;//0--之前不是100   1--之前是100
    static uint8_t Battery_Err = 0; //0--无            1--之前显示电池错误
    if (ch == 0)//全部刷新
    {
        OLED_off_display();  //关闭屏幕
        OLED_cls();
        OLED_Refresh_Word1_Flag.BootBatteryVal = 1;//刷新工作界面1--电量百分比
        OLED_Refresh_Flag.Light_type     = 1;//刷新工作界面1--灯光类型
        OLED_Refresh_Flag.Battery_Square = 1;//刷新工作界面1--上方电量方格
    }
    /**********************************新旧值判定**********************************/
    if (Battery_old != EG2801_RAM_DATA.StateOfCharge)
    {
        Battery_old = EG2801_RAM_DATA.StateOfCharge;
        OLED_Refresh_Word1_Flag.BootBatteryVal = 1;//刷新工作界面1--电量百分比
    }

    /**********************************刷新图形***********************************/
    if (OLED_Refresh_Word1_Flag.BootBatteryVal == 1)//刷新工作界面1--电量百分比
    {
        /*显示数字电量*/
        if (Battery_old < 100)
        {
            if (EG2801_RAM_DATA.Flags == 0xFFFF)
            {
                Draw_48X72BMP(30, 1, 6, LowBatter);                //   电池错误2
                Battery_Err = 1;
            }
            else
            {
                if (Battery_Flag == 1) //之前是100,所以需要清除
                {
                    OLED_P64x32Ch(55, 0, 1, BHundred);             //   清除大100
                }
                if (Battery_Err == 1)//如果之前显示了电池错误,就必须清除
                {
                    Battery_Err = 0;
                    Draw_48X72BMP_cls(30, 1);
                    OLED_Refresh_Flag.Light_type      = 2;//刷新工作界面2--灯光类型
                    OLED_Refresh_Flag.Battery_Square  = 2;//刷新工作界面2--上方电量方格
                }
                OLED_P24x32Ch(55, 4, Battery_old % 10, BDigital);      //   显示百分比  十位
                OLED_P24x32Ch(55, 1, Battery_old / 10, BDigital);      //   显示百分比  个位
                Battery_Flag = 0;
            }
        }
        else
        {
            OLED_P64x32Ch(55, 0, 0, BHundred);             //   大100%
            Battery_Flag = 1;
        }
        if (EG2801_RAM_DATA.Flags != 0xFFFF)
        {
            OLED_P16x16Ch(35, 5, 0, ControlGear);          //   显示%号
        }
        if (EG2801_RAM_DATA.Flags != 0xFFFF)
        {
            OLED_Refresh_Word1_Flag.BootBatteryVal = 0;    //停止刷新
        }

    }

    OLED_Show_UpInfor();//刷新工作界面上方的信息
    OLED_open_display();  //开启屏幕
}

/*********************************************
函数名:OLED_Show_work2
功  能:显示工作界面2
形  参:
返回值:
备  注:
作  者:薛建强
时  间:2019/12/18
使  用:
**********************************************/
void OLED_Show_work2(const uint8_t ch)
{
    static uint8_t Hour_old = 0, Min_old = 0;
    static uint8_t Battery_Err = 0; //0--无            1--之前显示电池错误
    uint16_t TimeToEmpty = 0;

    if (ch == 0)//全部刷新
    {
        OLED_off_display();  //关闭屏幕
        OLED_cls();
        OLED_Refresh_Word2_Flag.Hour_Time = 1;//刷新工作界面2--电量剩余时间  小时
        OLED_Refresh_Word2_Flag.Min_Time  = 1;//刷新工作界面2--电量剩余时间  分钟
        OLED_Refresh_Flag.Light_type      = 1;//刷新工作界面2--灯光类型
        OLED_Refresh_Flag.Battery_Square  = 1;//刷新工作界面2--上方电量方格
        OLED_P32x16Ch(54, 2, 0, SignRatio);      //   昌号
    }

    /**********************************新旧值判定**********************************/
    /*根据当前档位调整剩余时间*/
    if (SystemReg.Mode != 0)
    {
        TimeToEmpty = EG2801_RAM_DATA.TimeToEmpty * (1.5 * temp_time);
    }
    else
    {
        TimeToEmpty = EG2801_RAM_DATA.TimeToEmpty;
    }
    if (Hour_old != TimeToEmpty / 60)
    {
        Hour_old = TimeToEmpty / 60;
        OLED_Refresh_Word2_Flag.Hour_Time = 1;//刷新工作界面2--电量剩余时间  小时
    }
    if (Min_old != TimeToEmpty % 60)
    {
        Min_old = TimeToEmpty % 60;
        OLED_Refresh_Word2_Flag.Min_Time  = 1;//刷新工作界面2--电量剩余时间  分钟
    }
    /**********************************刷新图形***********************************/
    if (EG2801_RAM_DATA.Flags == 0xFFFF)
    {
        if (Battery_Err == 0)
        {
            OLED_P24x32Ch_cls(72, 1);                 //   清除显示时十位
            OLED_P24x32Ch_cls(72, 4);                 //   清除显示时个钟
            OLED_P16x32Ch_cls(54, 2);                 //   清除昌号
            OLED_P24x32Ch_cls(22, 1);                 //   清除显示分十位
            OLED_P24x32Ch_cls(22, 4);                 //   清除显示分个钟
        }
        Draw_48X72BMP(30, 1, 6, LowBatter);     //电池错误2
        OLED_Refresh_Word2_Flag.Hour_Time = 0;  //停止刷新
        OLED_Refresh_Word2_Flag.Min_Time = 0;   //停止刷新
        Battery_Err = 1;
    }
    else
    {
        if (Battery_Err == 1) //如果之前显示了电池错误,就必须清除
        {
            Battery_Err = 0;
            Draw_48X72BMP_cls(30, 1);
            OLED_Refresh_Word2_Flag.Hour_Time = 1;//刷新工作界面2--电量剩余时间  小时
            OLED_Refresh_Word2_Flag.Min_Time  = 1;//刷新工作界面2--电量剩余时间  分钟
            OLED_Refresh_Flag.Light_type      = 2;//刷新工作界面2--灯光类型
            OLED_Refresh_Flag.Battery_Square  = 2;//刷新工作界面2--上方电量方格
            OLED_P32x16Ch(54, 2, 0, SignRatio);      //   昌号
        }
        if (OLED_Refresh_Word2_Flag.Hour_Time == 1) //刷新工作界面2--电量剩余时间  小时
        {
            OLED_P24x32Ch(72, 1, Hour_old / 10, BDigital);
            OLED_P24x32Ch(72, 4, Hour_old % 10, BDigital);  //   显示小时
            OLED_Refresh_Word2_Flag.Hour_Time = 0;//停止刷新
        }
        if (OLED_Refresh_Word2_Flag.Min_Time == 1) //刷新工作界面2--电量剩余时间  小时
        {
            OLED_P24x32Ch(22, 1, Min_old / 10, BDigital);
            OLED_P24x32Ch(22, 4, Min_old % 10, BDigital);   //   显示分钟
            OLED_Refresh_Word2_Flag.Min_Time = 0;//停止刷新
        }
    }

    OLED_Show_UpInfor();//刷新工作界面上方的信息
    OLED_open_display();  //开启屏幕
}


/*********************************************
函数名:OLED_Show_LowPower
功  能:显示低电量充电图形
形  参:
返回值:
备  注:
作  者:薛建强
时  间:2019/12/21
使  用:
**********************************************/
void OLED_Show_LowPower(void)
{
    if (OLED_Page != 3)
    {
        OLED_Refresh_Flag.Battery_Low = 1;
    }
    if (OLED_Refresh_Flag.Battery_Low == 1)
    {
        OLED_Refresh_Flag.Battery_Low = 0;
        OLED_off_display();  //关闭屏幕
        OLED_cls();
        Draw_48X72BMP(30, 1, 0, LowBatter);                    //   低电压图标
        OLED_open_display();  //开启屏幕
        OLED_Page = 3; //3--缺电界面
    }

}
/*****************功能描述:显示64*32点阵  显示的坐标(x,y),y为页范围0~7****************************/
void OLED_P16x32Ch_NTC(uint8_t x, uint8_t y, uint8_t N, const uint8_t BMP[])
{
    uint16_t adder = 64 * N;
    uint8_t  wm = 0, i = 0;
    for (i = 0; i < 4; i++)
    {
        OLED_open_BL(x, y + i);
        for (wm = 0; wm < 16; wm++)
        {
            OLED_send_byte(BMP[adder], OLED_DATA);
            adder += 1;

        }
    }
}
/*********************************************
函数名:OLED_Show_NTC
功  能:温度采集错误
形  参:
返回值:
备  注:
作  者:薛建强
时  间:2019/12/21
使  用:
**********************************************/
void OLED_Show_NTC(void)
{
    if (OLED_Page != 5)
    {
        OLED_Refresh_Flag.Temp_Err = 1;
    }
    if (OLED_Refresh_Flag.Temp_Err == 1 && OLED_Page != 5)
    {
        OLED_Refresh_Flag.Temp_Err = 0;
        OLED_off_display();  //关闭屏幕
        OLED_cls();
        OLED_P16x32Ch_NTC(72, 12, 0, NTC);
        OLED_P16x32Ch_NTC(56, 12, 1, NTC);
        OLED_P16x32Ch_NTC(40, 12, 2, NTC);

        OLED_P16x32Ch_NTC(88, 0, 3, NTC);
        OLED_P16x32Ch_NTC(72, 0, 4, NTC);
        OLED_P16x32Ch_NTC(56, 0, 5, NTC);
        OLED_P16x32Ch_NTC(40, 0, 6, NTC);
        OLED_P16x32Ch_NTC(24, 0, 7, NTC);
        OLED_open_display();  //开启屏幕
        OLED_Page = 5; //5--温度异常界面
    }
}

/*********************************************
函数名:OLED_Show_Battery_Err2
功  能:电池错误2(待机界面)
形  参:
返回值:
备  注:
作  者:薛建强
时  间:2019/12/21
使  用:
**********************************************/
void OLED_Show_Battery_Err2(void)
{
    if (OLED_Page != 7)
    {
        OLED_Refresh_Flag.Battery_Err2 = 1;
    }
    if (OLED_Refresh_Flag.Battery_Err2 == 1 && OLED_Page != 7)
    {
        OLED_Refresh_Flag.Battery_Err2 = 0;
        OLED_off_display();  //关闭屏幕
        OLED_cls();
        Draw_48X72BMP(30, 1, 6, LowBatter);                //   电池错误2
        OLED_open_display();  //开启屏幕
        OLED_Page = 7; //7--电池异常(待机)
    }
}

#ifndef __OLED_
#define __OLED_

#include "main.h"
#include "hal_iic.h"

extern uint8_t OLED_Page;

typedef struct
{
    uint8_t StandbyBattery       :1;      //待机界面:              0--不刷新  1--刷新
    uint8_t Light_type           :2;      //工作界面:左上角        0--不刷新  1--刷新  2--特殊刷新
    uint8_t Battery_Square       :2;      //工作界面:显示电量格    0--不刷新  1--刷新  2--特殊刷新
    uint8_t Word1                :1;      //工作界面1:             0--不刷新  1--刷新
    uint8_t Word2                :1;      //工作界面2:             0--不刷新  1--刷新
    uint8_t Temp_Err             :1;      //温度错误:              0--不刷新  1--刷新
    uint8_t Battery_Err1         :1;      //电池错误1(工作界面):   0--不刷新  1--刷新
    uint8_t Battery_Err2         :1;      //电池错误2(待机界面):   0--不刷新  1--刷新
    uint8_t Battery_Low          :1;      //缺电界面:              0--不刷新  1--刷新
} OLED_Refresh;
extern OLED_Refresh OLED_Refresh_Flag;

typedef struct
{
    uint8_t BootBatteryVal       :1;      //工作界面1:显示电量值    0--不刷新  1--刷新
} OLED_Refresh_Word1;
extern OLED_Refresh_Word1 OLED_Refresh_Word1_Flag;


typedef struct
{
    uint8_t Hour_Time       :1;          //工作界面2:显示剩余时间 小时    0--不刷新  1--刷新
    uint8_t Min_Time        :1;          //工作界面2:显示剩余时间 分钟    0--不刷新  1--刷新
} OLED_Refresh_Word2;
extern OLED_Refresh_Word2 OLED_Refresh_Word2_Flag;

#define OLED_CMD  0	//写命令
#define OLED_DATA 1	//写数据
#define MAX_COLUMNC	132 //OLED屏幕最大边界

extern const unsigned char Battery[];
extern const unsigned char logo[];

#define OledCS_Clr()   HAL_GPIO_WritePin(GPIOB,GPIO_Pin_1,GPIO_PIN_RESET)  // 关闭OLED通讯
#define OledCS_Set()   HAL_GPIO_WritePin(GPIOB,GPIO_Pin_1,GPIO_PIN_SET)    // 打开OLED通讯

#define Oled_Close()  HAL_GPIO_WritePin(GPIOA,GPIO_Pin_5,GPIO_PIN_RESET)  // 关闭OLED背光
#define Oled_Open()   HAL_GPIO_WritePin(GPIOA,GPIO_Pin_5,GPIO_PIN_SET)    // 打开OLED背光

void OLED_init(void);
void OLED_send_byte(const uint8_t dat, const uint8_t cmd);
void OLED_open_BL(uint8_t x, uint8_t y);
void OLED_cls(void);
void OLED_cls1(void);
void OLED_open_display(void);
void OLED_off_display(void);
void OLED_show_char(uint8_t x, uint8_t y, uint8_t str, uint8_t size);
void OLED_show_str(uint8_t x, uint8_t y, uint8_t *str, uint8_t size);
void OLED_show_BMP(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t BMP[]);
void OLED_cls_BMP(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1);



void OLED_Show_Logo(void);
void OLED_Show_work1(const uint8_t ch);
void OLED_Show_work2(const uint8_t ch);

void OLED_show_Battery(uint8_t x0, uint8_t y0, uint8_t Nom,uint8_t size);
void OLED_show_Battery_Max(const uint8_t OnOff);
void OLED_show_Battery_Charge(const uint8_t OnOff);
void OLED_Show_LowPower(void);
void OLED_Show_NTC(void);
void OLED_Show_Battery_Err2(void);
#endif

猜你喜欢

转载自blog.csdn.net/qq_29246181/article/details/105480954