打印
[USB芯片]

【CH32X035评估板测评】快速驱动OLED细节

[复制链接]
3577|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dvacos|  楼主 | 2023-10-7 22:04 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
IIC驱动屏幕详解
本文使用模拟IIC来驱动 0.91  寸OLED,因为使用模拟IIC在任何平台上都可以快速的驱动屏幕,点亮一个屏幕的只需要 导入3个.c 和对应 .h 文件(共6个文件),需要提供delay 函数 和 翻转IO接口即可点亮屏幕!!十分的方便!!
驱动OLED屏幕本质上其实还是点灯,只不过是整齐排列在基板上的灯!但是我们的MCU不可能提供那么多IO去控制每一颗屏幕上的灯,所以需要有个芯片帮忙,这个屏幕驱动IC会按照代码取控制每一颗LED,显示出代码传输过去的图案信息!
所以驱动代码是发送给屏幕驱动IC的,我们想要显示的字、图案都需要取模软件转化为像素信息,并且按照代码初始化时我们告诉驱动IC的规则(从左到右、从上到小的规则或者其他)发送后,驱动IC就会按照数据,去控制OLED屏幕!!

简介:
此驱动时模拟IIC驱动,只需要延时 和 翻转IO即可,并且只要替换几个API和宏即可完成驱动实现快速的驱动屏幕,这可以作为快速验证硬件+软件的环境,再刷屏内容多且复杂时可以将驱动部分替换为硬件IIC即可。

移植准备
文件介绍
相关文件有以下三个
analog_iic.c    analog_iic.h          模拟IIC相关代码
oled.c             oled.h                   OLED初始化接口 和 基本操作函数
gui.c               gui.h                    画点、画线、显示文字的接口

API准备
1、毫秒级的延时函数,不用太准确差不都即可,我使用的时工程内已有的API  Delay_Ms接口。
2、IO的翻转(拉高或拉低)GPIO_WriteBit接口

IIC引脚定义
#define OLED_SDA       GPIO_Pin_1
#define OLED_SCL       GPIO_Pin_3
#defineOLED_SDA_SET()  GPIO_WriteBit(GPIOA, OLED_SDA, 1)
#defineOLED_SDA_CLR()  GPIO_WriteBit(GPIOA, OLED_SDA, 0)
#defineOLED_SCL_SET()  GPIO_WriteBit(GPIOA, OLED_SCL, 1)
#defineOLED_SCL_CLR()  GPIO_WriteBit(GPIOA, OLED_SCL, 0)

初始化IIC引脚
voidiic_io_init(void){
GPIO_InitTypeDef GPIO_InitStructure = {0};
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}

analog_iic.c
由于是屏幕是主控给它发送数据,驱动IC只管接收数据即可,主控不需要去读取数据,所以我们主要关注IIC_Write函数即可。
我们需要留意的有三点
1、IIC_SLAVE_ADDR 从机地址
2、需要确认写命令 和 数据
3、确认模拟IIC的引脚
以上1、2两点可以从规格书中得知。
IIC_SLAVE_ADDR  0x78
写命令需要在发送从机地址后,发送0x00,而数据是0x40,所以IIC写命令可以进一步封装为以下代码。
void Write_IIC_Command( u8 IIC_Command ){
    IIC_Start();
    Write_IIC_Byte( IIC_SLAVE_ADDR );          //Slave address,SA0=0
    IIC_Wait_Ack();
    Write_IIC_Byte( 0x00 );         //write command
    IIC_Wait_Ack();
    Write_IIC_Byte( IIC_Command );
    IIC_Wait_Ack();
    IIC_Stop();
}

void Write_IIC_Data( u8 IIC_Data ){
    IIC_Start();
    Write_IIC_Byte( IIC_SLAVE_ADDR );       //D/C#=0; R/W#=0
    IIC_Wait_Ack();
    Write_IIC_Byte( 0x40 );         //write data
    IIC_Wait_Ack();
    Write_IIC_Byte( IIC_Data );
    IIC_Wait_Ack();
    IIC_Stop();
}

屏幕初始化
以上发送的初始化参数都是需要屏厂、商家提供的,只是这一款屏幕用的人太多太多了,可以在网上找,如果不对是不能正确初始化屏幕的,后面的显示更不用说了,肯定有问题!
//  OLED_Display_Off(); //power off
    OLED_WR_Byte( 0xAE, OLED_CMD ); //--display off
    OLED_WR_Byte( 0x40, OLED_CMD ); //---set low column address
    OLED_WR_Byte( 0xB0, OLED_CMD ); //---set high column address
    OLED_WR_Byte( 0xC8, OLED_CMD ); //-not offset
    OLED_WR_Byte( 0x81, OLED_CMD ); // contract control
    OLED_WR_Byte( 0xFF, OLED_CMD ); //--128
    OLED_WR_Byte( 0xA1, OLED_CMD ); //set segment remap
     OLED_WR_Byte( 0xA6, OLED_CMD ); //--normal / reverse
    OLED_WR_Byte( 0xA8, OLED_CMD ); //--set multiplex ratio(1 to 64)
     OLED_WR_Byte( 0x1F, OLED_CMD );
     OLED_WR_Byte( 0xD3, OLED_CMD ); //-set display offset
    OLED_WR_Byte( 0x00, OLED_CMD );
    OLED_WR_Byte( 0xD5, OLED_CMD ); //set osc division
    OLED_WR_Byte( 0xF0, OLED_CMD );
    OLED_WR_Byte( 0xD9, OLED_CMD ); //Set Pre-Charge Period
    OLED_WR_Byte( 0x22, OLED_CMD );
    OLED_WR_Byte( 0xDA, OLED_CMD ); //set com pin configuartion
    OLED_WR_Byte( 0x02, OLED_CMD );
    OLED_WR_Byte( 0xDB, OLED_CMD ); //set Vcomh
    OLED_WR_Byte( 0x49, OLED_CMD );
    OLED_WR_Byte( 0x8D, OLED_CMD ); //set charge pump enable
    OLED_WR_Byte( 0x14, OLED_CMD );
    OLED_WR_Byte( 0xAF, OLED_CMD ); //--turn on oled panel
那么如何判断屏幕有没有初始换成功呢?

正确使用IIC发送,正确的初始化参数、并且不发送清屏,OLED屏幕就会这样显示!!

实际代码实验
注意1:
添加文件的方法,不然会编译报错。


注意2
While里不能放显示数据的函数,里面用了Dealy,会导致PD出现不断复位的情况

本文附件为此实验的代码,默认选择PDO报文的第四档,并且显示2023年9月19号 15点30分的实际 和 PDO报文第四档的电压和电流(取决于使用的充电器)。

USBPD_SNK+OLED.zip (633.14 KB)

使用特权

评论回复
沙发
tpgf| | 2024-6-3 13:08 | 只看该作者
快速驱动和普通的驱动之间大概相差多少呢

使用特权

评论回复
板凳
heimaojingzhang| | 2024-6-3 13:54 | 只看该作者
延时函数如果使用定时器中断会不会好点

使用特权

评论回复
评论
dvacos 2024-6-3 16:16 回复TA
@dvacos :时间有点久了,乱了。。。后面回忆一下 
dvacos 2024-6-3 16:05 回复TA
不是一直在初始化屏幕,上电的时候初始化一次就可以了,没什么影响的 
地板
wakayi| | 2024-6-3 14:39 | 只看该作者
oled屏幕是只能显示数字而不能显示文字是吗

使用特权

评论回复
5
dvacos|  楼主 | 2024-6-3 16:00 | 只看该作者
wakayi 发表于 2024-6-3 14:39
oled屏幕是只能显示数字而不能显示文字是吗

可以啊,OLED就是一堆LED点阵,怎么显示是软件的事情而已,用软件去取字模(将字体转化为二进制点阵字节)就好了

使用特权

评论回复
6
renzheshengui| | 2024-6-3 21:20 | 只看该作者
使用oled屏的话 是不是比较耗费引脚的数目呢

使用特权

评论回复
7
paotangsan| | 2024-6-3 21:51 | 只看该作者
快速驱动oled是不是就意味着刷新速度也会变快呢

使用特权

评论回复
8
keaibukelian| | 2024-6-3 22:22 | 只看该作者
为什么有时候程序会在delay函数里边死循环呢

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

19

主题

105

帖子

1

粉丝