你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

快速驱动0.91 寸OLED

[复制链接]
dvacos 发布时间:2023-9-1 18:04

本文使用模拟IIC来驱动 0.91 寸OLED,因为使用模拟IIC在任何平台上都可以快速的驱动屏幕,点亮一个屏幕的只需要 导入3个.c 和对应 .h 文件(共6个文件),需要提供delay 函数 和 翻转IO接口即可点亮屏幕!!十分的方便!!

驱动OLED屏幕本质上其实还是点灯,只不过是整齐排列在基板上的灯!但是我们的MCU不可能提供那么多IO去控制每一颗屏幕上的灯,所以需要有个芯片帮忙,这个屏幕驱动IC会按照代码取控制每一颗LED,显示出代码传输过去的图案信息! 所以驱动代码是发送给屏幕驱动IC的,我们想要显示的字、图案都需要取模软件转化为像素信息,并且按照代码初始化时我们告诉驱动IC的规则(从左到右、从上到小的规则或者其他)发送后,驱动IC就会按照数据,去控制OLED屏幕!!

这是之前测评WB55时驱动的OLED屏幕方法的总结!再次谢谢ST论坛给的开发板!

移植准备

文件介绍

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

API准备

1、毫秒级的延时函数,不用太准确差不都即可,我使用的时HAL_Delay接口 2、IO的翻转(拉高或拉低)

移植中&代码简介

main.c

以下初始化屏幕 并 显示时间的代码,如果需要显示时间,只要保留OLED_Init即可,在while填写想要显示数值 和 文字即可(先要显示的文字和数字都要先取模)


time_t now;
struct tm *ts;
static char str_time[80];
uint32_t timestamp=0;

int main(void){
        ....
        MX_GPIO_Init();
        ....
        MX_APPE_Init();
        OLED_Init();
        now=1688628481;

        ts = localtime( &now );

        sprintf(str_time,"%04d-%02d-%02d %02d:%02d:%02d",

                    ts->tm_year+1900,

                    ts->tm_mon+1,

                    ts->tm_mday,

                    ts->tm_hour+8, //时区要加8

                    ts->tm_min,

                    ts->tm_sec );

  while (1)
  {

        MX_APPE_Process();

    GUI_ShowString(0,0,(u8*)str_time,8,1);

    ...
  }
}

初始化GPIO

void MX_GPIO_Init(void){
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  /* GPIO Ports Clock Enable */

  __HAL_RCC_GPIOC_CLK_ENABLE();

  __HAL_RCC_GPIOB_CLK_ENABLE();

  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */

  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2|GPIO_PIN_11, GPIO_PIN_SET);

  /*Configure GPIO pins : PB2 PB11 */

  GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_11;

  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

  GPIO_InitStruct.Pull = GPIO_PULLUP;

  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

analog_iic.c

由于是屏幕是主控给它发送数据,驱动IC只管接收数据即可,主控不需要去读取数据,所以我们主要关注IIC_Write函数即可。 我们需要留意的有三点 1、IIC_SLAVE_ADDR 从机地址 2、需要确认写命令 和 数据 3、确认模拟IIC的引脚

以上1、2两点可以从规格书中得知。 IIC_SLAVE_ADDR 0x78 写命令需要在发送从机地址后,发送0x00,而数据是0x40。

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();
}

模拟IIC引脚定义

//--------------IIC总线引脚定义-----------------------

#define OLED_SDA       GPIO_PIN_2  //OLED屏IIC数据信号

#define OLED_SCL       GPIO_PIN_11 //OLED屏IIC时钟信号

//--------------IIC端口操作定义---------------------

#define OLED_SDA_SET()      HAL_GPIO_WritePin(GPIOB, OLED_SDA, GPIO_PIN_SET)

#define OLED_SDA_CLR()      HAL_GPIO_WritePin(GPIOB, OLED_SDA, GPIO_PIN_RESET)

#define OLED_SCL_SET()      HAL_GPIO_WritePin(GPIOB, OLED_SCL, GPIO_PIN_SET)    

#define OLED_SCL_CLR()      HAL_GPIO_WritePin(GPIOB, OLED_SCL, GPIO_PIN_RESET)

oled.c

其中最重要的代码就是OLED_Init

void OLED_Init( void ){
    HAL_Delay( 200 );
    /**************初始化SSD1306*****************/

//  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

//  OLED_Display_On(); // power on
    OLED_Clear( 0 ); //清屏
}

以上发送的初始化参数都是需要屏厂、商家提供的,只是这一款屏幕用的人太多太多了,可以在网上找,如果不对是不能正确初始化屏幕的,后面的显示更不用说了,肯定有问题!

那么如何判断屏幕有没有初始换成功呢? 456bf1a6d396191bb218fa736ae1049.jpg 正确使用IIC发送,正确的初始化参数、并且不发送清屏,OLED屏幕就会这样显示!!

经过以上几步后,只要编译没有报错后,就可以烧录,接线测试了

移植后&实验

如果接线没问题的情况请仔细检查数据是否和填写的代码一致!!

问题

我列一下我在实验时遇到的一个十分难搞的问题

问题:在我将IO配置为 推挽、上拉输出后,我接逻辑分析仪,确认数据全部发送正确,但是接到屏幕后发现数据时错乱的!

解决方法: 将屏幕的SDA SCL都接上10K的上拉,必须确保在连接屏幕后,逻辑分析仪抓获的数据也要和代码里填写的一致!!

相关代码 ↓

IIC_Code.zip

1 收藏 评论9 发布时间:2023-9-1 18:04

举报

9个回答
dvacos 回答时间:2023-9-1 18:11:55

研究了一下,不知道怎么上传压缩包附件,发个百度云分享,压缩后14k,限不限速都一样,

链接:https://pan.baidu.com/s/1lSzNwBCNLoV74Y8I0GgoIA?pwd=yxl4 提取码:yxl4

无极考拉 回答时间:2023-9-4 09:00:42

学习一下

STMCU-管管 回答时间:2023-9-5 11:56:07
dvacos 发表于 2023-9-1 18:11
[md]研究了一下,不知道怎么上传压缩包附件,发个百度云分享,压缩后14k,限不限速都一样,

链接:https:/ ...

有一个长得像回形针的图标就是传附件的哈
电子烂人 回答时间:2023-9-6 09:24:26

学到了

向明月 回答时间:2023-9-7 14:40:56

点赞

meiyao 回答时间:2023-9-7 21:27:35

厉害,使用GUI能这样玩,画点画线

高迪的教堂 回答时间:2023-9-12 09:45:47
学习一下
onebyte 回答时间:2023-9-15 08:42:36

正要用0.91寸的屏,这次省事了

dvacos 回答时间:2023-9-15 13:00:50

编译应该会报错

在analog_iic.h 找到 IIC_SLAVE_ADDR ,赋值为0x78 即可,如下

define IIC_SLAVE_ADDR 0x78

文件的中文注释使用GB2312编码

所属标签

相似分享

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版