Oled实现动图显示——篮球少年

Oled实现动图显示——篮球少年

Oled显示模块,用char定义清除界面会导致画面屏雪花;如果用char i,j;有符号,表示从-128——127,会导致某些数被吞掉,用int或者unsigned char(表示无符号)

设备:51开发板和0.96寸4针Oled 显示模块。

动图显示说白了就是把GIF图分离成一帧一帧的图片显示一张图片和显示一张图片差不多。

第一步:提取分离图片推荐用Gifsplitter

在这里插入图片描述

第二步:降低画质,图片改为是bmp格式,大小调成128×64(可以在软件内部调也可以用Windows画图应用调)具体如下:

在这里插入图片描述

第三步:对图片取模(最繁琐的一步,哪里有一键取模软件迫切希望告知)我这里用的是CopyLeft Bu Horse2000,建议使用PCtolCD

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

取模完成把数组添加到其中具体代码如下:

#include "reg52.h"
#include "intrins.h"

sbit scl = P0^1;
sbit sda = P0^3;


void IIC_Start()
{
    scl = 0;
    sda = 1;
    scl = 1;
    _nop_();
    sda = 0;
    _nop_();
}

void IIC_Stop()
{
    scl = 0;
    sda = 0;
    scl = 1;
    _nop_();
    sda = 1;
    _nop_();
}

char IIC_ACK()
{
    char flag;
    sda = 1;//就在时钟脉冲9期间释放数据线
    _nop_();
    scl = 1;
    _nop_();
    flag = sda;
    _nop_();
    scl = 0;
    _nop_();

    return flag;
}

void IIC_Send_Byte(char dataSend)
{
    int i;

    for(i = 0; i<8; i++) {
        scl = 0;//scl拉低,让sda做好数据准备
        sda = dataSend & 0x80;//1000 0000获得dataSend的最高位,给sda
        _nop_();//发送数据建立时间
        scl = 1;//scl拉高开始发送
        _nop_();//数据发送时间
        scl = 0;//发送完毕拉低
        _nop_();//
        dataSend = dataSend << 1;
    }
}

void Oled_Write_Cmd(char dataCmd)
{
    //	1. start()
    IIC_Start();
    //
    //	2. 写入从机地址  b0111 1000 0x78
    IIC_Send_Byte(0x78);
    //	3. ACK
    IIC_ACK();
    //	4. cotrol byte: (0)(0)000000 写入命令   (0)(1)000000写入数据
    IIC_Send_Byte(0x00);
    //	5. ACK
    IIC_ACK();
    //6. 写入指令/数据
    IIC_Send_Byte(dataCmd);
    //7. ACK
    IIC_ACK();
    //8. STOP
    IIC_Stop();
}

void Oled_Write_Data(char dataData)
{
    //	1. start()
    IIC_Start();
    //
    //	2. 写入从机地址  b0111 1000 0x78
    IIC_Send_Byte(0x78);
    //	3. ACK
    IIC_ACK();
    //	4. cotrol byte: (0)(0)000000 写入命令   (0)(1)000000写入数据
    IIC_Send_Byte(0x40);
    //	5. ACK
    IIC_ACK();
    ///6. 写入指令/数据
    IIC_Send_Byte(dataData);
    //7. ACK
    IIC_ACK();
    //8. STOP
    IIC_Stop();
}


void Oled_Init(void) {
    Oled_Write_Cmd(0xAE);//--display off
    Oled_Write_Cmd(0x00);//---set low column address
    Oled_Write_Cmd(0x10);//---set high column address
    Oled_Write_Cmd(0x40);//--set start line address
    Oled_Write_Cmd(0xB0);//--set page address
    Oled_Write_Cmd(0x81); // contract control
    Oled_Write_Cmd(0xFF);//--128
    Oled_Write_Cmd(0xA1);//set segment remap
    Oled_Write_Cmd(0xA6);//--normal / reverse
    Oled_Write_Cmd(0xA8);//--set multiplex ratio(1 to 64)
    Oled_Write_Cmd(0x3F);//--1/32 duty
    Oled_Write_Cmd(0xC8);//Com scan direction
    Oled_Write_Cmd(0xD3);//-set display offset
    Oled_Write_Cmd(0x00);//

    Oled_Write_Cmd(0xD5);//set osc division
    Oled_Write_Cmd(0x80);//
    
    Oled_Write_Cmd(0xD8);//set area color mode off
    Oled_Write_Cmd(0x05);//
    
    Oled_Write_Cmd(0xD9);//Set Pre-Charge Period
    Oled_Write_Cmd(0xF1);//
    
    Oled_Write_Cmd(0xDA);//set com pin configuartion
    Oled_Write_Cmd(0x12);//
    
    Oled_Write_Cmd(0xDB);//set Vcomh
    Oled_Write_Cmd(0x30);//
    
    Oled_Write_Cmd(0x8D);//set charge pump enable
    Oled_Write_Cmd(0x14);//
    
    Oled_Write_Cmd(0xAF);//--turn on oled panel
}

void Oled_Clear(void) {
    int i,j;
    Oled_Write_Cmd (0x20);                    //set memory addressing mode
    Oled_Write_Cmd (0x02);                    //page addressing mode

    for(i=0; i<8; i++) {
        Oled_Write_Cmd(0xB0+i);               //ÉèÖÃÒ³µØÖ·£¨0~7£©
        Oled_Write_Cmd(0x00);                 //ÉèÖÃÏÔʾλÖáªÁе͵ØÖ·
        Oled_Write_Cmd(0x10);                 //ÉèÖÃÏÔʾλÖáªÁиߵØÖ·
        for(j=0; j<128; j++) {
            Oled_Write_Data(0);
        }
    }
}






void Oled_Show_Image(unsigned char *image) {
    unsigned char i;
    unsigned int j;

    for(i=0; i<8; i++) {
        Oled_Write_Cmd(0xB0+i); //page0 ——page7
    
        Oled_Write_Cmd(0x00); //每个page从第0列开始
        Oled_Write_Cmd(0x10);
    
        for(j=128*i; j<128*(i+1); j++) {
            Oled_Write_Data(image[j]);
        }
    }
}
void main()
{
    //1. OLED初始化
    Oled_Init();
    //2. 选择一个位置
    //2.1 确认页寻址模式
    Oled_Write_Cmd(0x20);
    Oled_Write_Cmd(0x02);
    Oled_Clear();
    //Oled_Show_Image(bmpImager);
    while(1) {//取模代码太多就不写出来了

        Oled_Show_Image(bmpImager41);
        _nop_();
        Oled_Show_Image(bmpImager42);
        _nop_();
        Oled_Show_Image(bmpImager43);
        _nop_();
        Oled_Show_Image(bmpImager44);
        _nop_();
        Oled_Show_Image(bmpImager45);
        _nop_();
        Oled_Show_Image(bmpImager46);
        _nop_();
    }

}

这个代码会使Oled显示帧率有点问题,应该是延时函数过多,代码冗余或是其他问题,欢迎交流解决。
效果演示

学习

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值