STM32 软件IIC 控制OLED 显示屏

这篇具有很好参考价值的文章主要介绍了STM32 软件IIC 控制OLED 显示屏。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 硬件IIC 实在是太难用了,各种卡死,各种发不出来数据,没那么多时间折腾了,还是用软件IIC 先吧,初始化

void OLED_Software_IIC_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;

    RCC_AHBPeriphClockCmd(OLED_SOFTWARE_IIC_PORT_B | OLED_SOFTWARE_IIC_AF_CLOCK, ENABLE);

    GPIO_InitStruct.GPIO_Pin = OLED_IIC_SDA_PIN_B11 | OLED_IIC_SCL_PIN_B10;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_40MHz;
    GPIO_Init(GPIOB, &GPIO_InitStruct); // PB11 - SDA, PB10 - SCL

    GPIO_SetBits(GPIOB, OLED_IIC_SDA_PIN_B11 | OLED_IIC_SCL_PIN_B10);

    OLED_IIC_Stop();
}

2. 一些宏定义,带FreeRTOS 实时操作系统,系统节拍设置为1ms,系统主频设置为32Mhz

#define OLED_USE_SOFTWARE_IIC

#define OLED_SOFTWARE_IIC_PORT_B    RCC_AHBPeriph_GPIOB // SCL - PB10, SDA -PB11
#define OLED_SOFTWARE_IIC_AF_CLOCK    RCC_APB1Periph_I2C2

#define IIC_TIMEOUT_COUNTER    0x2000 // iic transmit timeout

#define OLED_IIC_SCL_PIN_B10    GPIO_Pin_10
#define OLED_IIC_SDA_PIN_B11    GPIO_Pin_11
#define OLED_SCL_H()    GPIO_SetBits(GPIOB, OLED_IIC_SCL_PIN_B10)
#define OLED_SCL_L()    GPIO_ResetBits(GPIOB, OLED_IIC_SCL_PIN_B10)

#define OLED_ADDRESS    0x78 // 0x78: device address + write, 0x79 - device address + read
#define IIC_CMD_LEN    2

#define OLED_SDA_H()    GPIO_SetBits(GPIOB, OLED_IIC_SDA_PIN_B11)
#define OLED_SDA_L()    GPIO_ResetBits(GPIOB, OLED_IIC_SDA_PIN_B11)

#define OLED_SDA_READ()    GPIO_ReadInputDataBit(GPIOB, OLED_IIC_SDA_PIN_B11)

3. 延时函数,CPU 阻塞,空转

static void IIC_Delay(void)
{
   uint8_t temp;

   for (temp = 0; temp < 10; temp++)
   {
       // do nothing
   }
}

4. 起始信号

static void OLED_IIC_Start(void)
{
    OLED_SDA_H();
    OLED_SCL_H();

    IIC_Delay();
    OLED_SDA_L();
    IIC_Delay();
    OLED_SCL_L();
    IIC_Delay();
}

5. 停止信号

static void OLED_IIC_Stop(void)
{
   OLED_SDA_L();
   OLED_SCL_H();
   IIC_Delay();
   OLED_SDA_H();
   IIC_Delay();
}

6. 发送一个字节的数据

static void OLED_IIC_SendByte(uint8_t data)
{
   uint8_t index;
   GPIO_InitTypeDef GPIO_InitStruct;

   for (index = 0; index < 8; index++) // send one byte data, first send MSB (bit[7]), send LSB at the last (bit[0])
   {
       if (data & 0x80)
       {
           OLED_SDA_H(); // send 1
       }
       else
       {
           OLED_SDA_L(); // send 0
       }
       IIC_Delay();
       OLED_SCL_H();
       IIC_Delay();
       OLED_SCL_L();
       data <<= 1; // send next bit (MSB -> LSB)
       IIC_Delay();
   }
//    OLED_SDA_H();
   GPIO_InitStruct.GPIO_Pin = OLED_IIC_SDA_PIN_B11;
   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
   GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;

   GPIO_Init(GPIOB, &GPIO_InitStruct);

   IIC_Delay();
}

7. 发送一个字节数据后等待从机回复一个ACK 信号

uint8_t OLED_IIC_WaitAck(void)
{
   uint8_t ret;

   OLED_SCL_H();
   if (OLED_SDA_READ())
   {
       ret = 1; // not received ACK signal, wait fail
   }
   else
   {
       ret = 0; // received ACK signal, wait success
   }
   IIC_Delay();
   OLED_SCL_L();
   IIC_Delay();

   return ret;
}

8. GPIO 重新初始化

static void OLED_SoftwareIIC_SDA_Resume(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;

    GPIO_InitStruct.GPIO_Pin = OLED_IIC_SDA_PIN_B11;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_40MHz;
    GPIO_Init(GPIOB, &GPIO_InitStruct); // PB11 - SDA
}

9. 模仿HAL库写的一个自己的函数,实现功能,发送设备地址+读写控制,再发送0x00,表示发的是命令,再发一个字节数据,具体的内容,数据,共发了三个字节的数据,加了超时退出机制

/*
 * imitate the stm32 HAL library, achieve myself's software i2c send function
 * deviceAddr: 0x78 - device address and write operation, 0x79 - device address and read operation
 */
static void HAL_I2C_Master_Transmit(I2C_TypeDef *I2Cx, uint8_t deviceAddr, uint8_t buff[], uint16_t buffLen, uint32_t timeout)
{
    uint32_t temp;
    uint16_t index;

    temp = timeout;

    OLED_IIC_Start();

    IIC_Delay();
    OLED_IIC_SendByte(deviceAddr); // device address and write bit

    while (OLED_IIC_WaitAck())
    {
        temp--;
        if (0 == temp)
        {
            return;
        }
        IIC_Delay();
    }

    OLED_SoftwareIIC_SDA_Resume();
    for (index = 0; index < buffLen; index++)
    {
        OLED_IIC_SendByte(buff[index]);
        IIC_Delay();
        while (OLED_IIC_WaitAck())
        {
            temp--;
            if (0 == temp)
            {
                return;
            }
            IIC_Delay();
        }
        OLED_SoftwareIIC_SDA_Resume();
        IIC_Delay();
    }

    OLED_IIC_Stop();
}

10. 向OLED 发送指令函数

static void OLED_SendCmd(uint8_t cmd)
{
    uint8_t sendBuff[2];

    sendBuff[0] = 0x00;
    sendBuff[1] = cmd;

    HAL_I2C_Master_Transmit(I2C2, OLED_ADDRESS, sendBuff, IIC_CMD_LEN, IIC_TIMEOUT_COUNTER);
}

11. OLED 初始化函数,OLED 用的龙科显示公式的产品,控制IC 用的是CH1116G,他们给我发是资料却是SH1106的

void OLED_Init(void)
{
    delay_xms(200); // oled startup slowly than stm32l151c8t6
    INFO_LOG("[OLED_Init] init start\r\n");

    OLED_SendCmd(0xAE); // display off

    OLED_SendCmd(0x02); // set colum start address, low 4-bits
    OLED_SendCmd(0x10); // set colum end address, high 4-bits

    OLED_SendCmd(0x40); // set start line (first row)
    OLED_SendCmd(0xB0); // set page address

    delay_xms(5);
    OLED_SendCmd(0x81); // set contrast ratio (对比度)
    delay_xms(5);
    OLED_SendCmd(0xCF); // 128
    delay_xms(5);

    OLED_SendCmd(0xA1); // set segment remapping, from right to left

    OLED_SendCmd(0xA6); // forward display, normal or reverse

    OLED_SendCmd(0xA8); // multiple reuse rate, multiple ratio (多路复用率)
    OLED_SendCmd(0x3F); // duty = 1 / 64

    OLED_SendCmd(0xAD); // set charge pump enable
    OLED_SendCmd(0x8B); // enable DC-DC

    OLED_SendCmd(0x33); // set VPP = 10V

    OLED_SendCmd(0xC8); // set output scan direction, COM[N - 1] to COM[0], COM scan direction

    OLED_SendCmd(0xD3); // set display offset
    OLED_SendCmd(0x00); // 0x00

    OLED_SendCmd(0xD5); // set internal clock frequence, set osc frequency
    OLED_SendCmd(0xC0);

    OLED_SendCmd(0xD9); // set pre-charge period
    OLED_SendCmd(0x1F); // 0x22

    OLED_SendCmd(0xDA); // set COM pins, pin layout
    OLED_SendCmd(0x12);

    OLED_SendCmd(0xDB); // set electrical level, set VCOMH
    OLED_SendCmd(0x40);

    OLED_SendCmd(0xAF); // enable display, display on

    INFO_LOG("[OLED_Init][alfred01] init complete\r\n");
    INFO_LOG("[OLED_Init] init complete\r\n");
}

12. OLED 测试函数

void OLED_Test(void)
{
    OLED_SendCmd(0xB0); // page 0
    OLED_SendCmd(0x02); // colume 0, low 4-bits
    OLED_SendCmd(0x10); // colume 0, high 4-bits

    uint8_t sendBuff[] = {0x40, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};
    HAL_I2C_Master_Transmit(I2C2, OLED_ADDRESS, sendBuff, sizeof(sendBuff), IIC_TIMEOUT_COUNTER);
}

13. OLED 初步显示效果,表示控制驱动是OK的了,其它的就是慢慢细调了

STM32 软件IIC 控制OLED 显示屏,stm32,单片机,嵌入式硬件,OLED

14. OLED 规格书,控制芯片用的CH1116G,这是硬件发给我,和厂家给的不一致,厂家说是兼容的,那我就直接上手调了

STM32 软件IIC 控制OLED 显示屏,stm32,单片机,嵌入式硬件,OLED

15. 看这三个引脚接的是高电平还是低电平,怎么组合的,就知道用的什么接口,需要看原理图了

STM32 软件IIC 控制OLED 显示屏,stm32,单片机,嵌入式硬件,OLED
需要看原理图了
STM32 软件IIC 控制OLED 显示屏,stm32,单片机,嵌入式硬件,OLED
STM32 软件IIC 控制OLED 显示屏,stm32,单片机,嵌入式硬件,OLED

16. 逻分仪抓的OLED 初始化时序图

STM32 软件IIC 控制OLED 显示屏,stm32,单片机,嵌入式硬件,OLED文章来源地址https://www.toymoban.com/news/detail-697445.html

到了这里,关于STM32 软件IIC 控制OLED 显示屏的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32-OLED显示屏

    *本文采用的OLED显示屏为4针脚IIC显示屏,4针脚分别为GND,VCC,SCL,SDA OLED.C OLED_Font.h main.c

    2024年02月05日
    浏览(22)
  • STM32——OLED显示屏(4)

    目录 一、调试方式 二、OLED简介 三、OLED硬件电路 四、OLED驱动函数 五、OLED显示屏使用 1、硬件接线图 2、添加OLED驱动函数 3、程序 4、实物展示  六、Keil软件自带调试模式         对于单片机的编程而言,经常会遇到一个很大的问题,就是程序调试,单片机不像电脑,电

    2024年02月03日
    浏览(20)
  • 【正点原子STM32】OLED实验(OLED显示屏、ATK_OLED模块,OLED驱动原理、SSD1306工作时序(8080时序),OLED驱动芯片,字符显示原理、字模生成软件,OLED基本驱动步骤)

    一、OLED显示屏介绍 1.1、ATK_OLED模块介绍 1.2、ATK_OLED模块引脚说明(8080并口模式) 1.3、OLED模块硬件连接 二、OLED驱动原理 2.1、SSD1306工作时序(8080时序) 2.2、SSD1306工作时序(8080时序)–写时序 三、OLED驱动芯片简介 3.1、什么是GRAM? 3.2、什么是页地址模式? 3.3、解决显示覆盖问题

    2024年03月13日
    浏览(23)
  • STM32F103驱动oled显示屏

    oled显示屏和其他显示屏类似,不过他只有0.96英寸,屏幕较小,但是使用起来比较方便。有二种驱动方式,分别为IIC,和SPI驱动。驱动方式比较简单。IIC驱动的话只需要4根线,电源,地线,数据线,和时钟线。 我这里使用的是IIC协议驱动oled显示屏,如果想了解IIC协议的可以看

    2024年02月11日
    浏览(23)
  • 5、江科大stm32视频学习笔记——OLED显示屏

    目录 1、OLED简介  2、OLED硬件电路 3、OLED驱动函函数简介和应用 4、用keil进行调试 4引脚OLED SCL和SDA是I2C通信引脚,需要接在I2C通信的引脚上 实验中用的模块是GPIO口模拟的I2C通信,故SCL和SDA两个端口可以接在任意的GPIO口上 7引脚OLED 右边5个引脚是SPI通信协议的引脚 如果是GPI

    2024年02月14日
    浏览(15)
  • STM32单片机(四)第二节:OLED显示屏

    ❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 :适用于想要从零基础开始学习入门单片机,且有一定C语言基础的的童鞋

    2024年02月16日
    浏览(19)
  • 基于HAL库的stm32的OLED显示屏显示(模拟I2C,四脚,0.96寸)

    参考视频:江科大oled程序移植stm32hal库,freertos学习,cpu使用率_哔哩哔哩_bilibili ​ STM32入门教程-2023持续更新中_哔哩哔哩_bilibili 高速和低速晶振均选择为陶瓷晶振即可。 不需更改初始化配置,因为模拟I2C初始化时会设置这两个引脚的电平 step1、step2完成后生成工程即可。 代

    2024年02月06日
    浏览(22)
  • STM32 F103C8T6学习笔记8:0.96寸单色OLED显示屏显示字符

    使用STM32F103 C8T6 驱动0.96寸单色OLED显示屏: OLED显示屏的驱动,在设计开发中OLED显示屏十分常见,因此今日学习一下。一篇文章从程序到显示都讲通。 文章提供源码、原理解释、测试工程下载,测试效果图展示。   目录 OLED驱动原理—IIC通信: SSD1306 单色 0.96 OLED 显示屏特性

    2024年02月12日
    浏览(18)
  • 【STM32】SPI通讯控制ILI9341显示屏

    ILI9341是一款分辨率为 240x320 分辨率 的a- tft液晶显示单片SOC驱动,由720通道源驱动、320通道门驱动、 172800字节GRAM (240RGBx320点位图形显示数据)和电源电路组成。 ILI9341支持并行8-/9-/16-/18位数据总线MCU接口,6-/16-/18位数据总线RGB接口和3 /4线串行外围接口 SPI通讯 。通过窗口地址函

    2024年01月21日
    浏览(19)
  • STM32 F103C8T6学习笔记9:0.96寸单色OLED显示屏—自由取模显示—显示汉字与图片

    今日学习0.96寸单色OLED显示屏的自由取模显示: 宋体汉字比较复杂,常用字符可以直接复制存下来,毕竟只有那么几十个字母字符,但汉字实在太多了,基本不会全部放在单片机里存着,一般用到多少个字就取几个字的模,因此汉字放在这里与自由取模一起讲。 文章提供源码

    2024年02月11日
    浏览(18)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包