• STM32实现0.96寸OLED显示模拟IIC和IIC四种实现(标准库和HAL库)


    目录

    本文通过四种方法实现OLED显示

    设备选择

    OLED介绍

    接线表设计

    OLED应用

    1.标准库模拟IIC实现OLED显示

    2.标准库IIC实现OLED显示

    3.HAL库模拟IIC实现OLED显示

    4.HAL库IIC实现OLED显示

    实现效果

    代码下载


    本文通过四种方法实现OLED显示

    设备选择

    1.单片机:STM32F103

    2.0.96寸OLED显示屏 

    OLED介绍

    OLED (Organic Light-Emitting Diode):有机发光二极管又称为有机电激光显示,OLED显示技术具有自发光的特性,采用薄的有机材料涂层和玻璃基板,当有电流通过时,这些有机材料就会发光,而且OLED显示屏幕可视角度大,功耗低。OLED由于同时具备自发光、不需背光源(只上电是不会亮的,驱动程序和接线正确才会点亮)、对比度高、厚度薄、视角广、反应速度快、可用于挠曲面板、使用温度范围广、结构及制程简单等优异之特性。最先接触的12864屏都是LCD的,需要背光,功耗较高,而OLED的功耗低,更加适合小系统;由于两者发光材料的不同,在不同的环境中,OLED的显示效果较佳。模块供电可以是3.3V也可以是5V,不需要修改模块电路,OLED屏具有多个控制指令,可以控制OLED的亮度、对比度、开关升压电路等指令。操作方便,功能丰富,可显示汉字、ASCII、图案等。
     

    接线表设计

    序号激光测距模块单片机STM32
    1VCC3.3V/5V
    2SCLPB6
    3SDAPB7
    4GNDGND

    OLED应用

    这里选用0.96寸OLED显示屏,它支持IIC通信,因此代码将以IIC展开。

    整个实现过程,分为四种方式实现。

    1.标准库模拟IIC实现OLED显示

    1. /**************************************************/
    2. /* IIC Start */
    3. /**************************************************/
    4. void IIC_Start()
    5. {
    6. OLED_GPIO(OLED_SDA,1);
    7. OLED_GPIO(OLED_CLK,1);
    8. OLED_GPIO(OLED_SDA,0);
    9. OLED_GPIO(OLED_CLK,0);
    10. }
    11. /**************************************************/
    12. /* IIC Stop */
    13. /**************************************************/
    14. void IIC_Stop()
    15. {
    16. OLED_GPIO(OLED_CLK,1);
    17. OLED_GPIO(OLED_SDA,0);
    18. OLED_GPIO(OLED_CLK,1);
    19. OLED_GPIO(OLED_SDA,1);
    20. OLED_GPIO(OLED_CLK,1);
    21. }
    22. void IIC_Wait_Ack() //检测应答
    23. {
    24. OLED_GPIO(OLED_SDA,0);
    25. OLED_GPIO(OLED_CLK,1);
    26. OLED_GPIO(OLED_CLK,0);
    27. }
    28. /**************************************************/
    29. /* IIC Write byte */
    30. /**************************************************/
    31. void Write_IIC_Byte(uint8_t IIC_Byte)
    32. {
    33. uint8_t i;
    34. uint8_t m,da;
    35. da=IIC_Byte;
    36. OLED_GPIO(OLED_CLK,0);
    37. for(i=0;i<8;i++)
    38. {
    39. m=da;
    40. // OLED_SCLK_Clr();
    41. m=m&0x80;
    42. if(m==0x80)
    43. {
    44. OLED_GPIO(OLED_SDA,1);
    45. }
    46. else
    47. OLED_GPIO(OLED_SDA,0);
    48. da=da<<1;
    49. OLED_GPIO(OLED_CLK,1);
    50. OLED_GPIO(OLED_CLK,0);
    51. }
    52. }
    53. /*********************************************/
    54. /* IIC Write Command */
    55. /*********************************************/
    56. void Write_IIC_Command(uint8_t IIC_Command) //写命令
    57. {
    58. IIC_Start();
    59. Write_IIC_Byte(0x78); // OLED的I2C地址(禁止修改)
    60. IIC_Wait_Ack();
    61. Write_IIC_Byte(0x00); // OLED 指令(禁止修改)
    62. IIC_Wait_Ack();
    63. Write_IIC_Byte(IIC_Command);
    64. IIC_Wait_Ack();
    65. IIC_Stop();
    66. }
    67. /*********************************************/
    68. /* IIC Write Data */
    69. /*********************************************/
    70. void Write_IIC_Data(uint8_t IIC_Data) //写数据
    71. {
    72. IIC_Start();
    73. Write_IIC_Byte(0x78); // OLED的I2C地址(禁止修改)
    74. IIC_Wait_Ack();
    75. Write_IIC_Byte(0x40); // OLED 数据(禁止修改)
    76. IIC_Wait_Ack();
    77. Write_IIC_Byte(IIC_Data);
    78. IIC_Wait_Ack();
    79. IIC_Stop();
    80. }
    81. void OLED_WR_Byte(uint8_t dat,uint8_t cmd)
    82. {
    83. if(cmd)
    84. {
    85. Write_IIC_Data(dat);
    86. }
    87. else
    88. {
    89. Write_IIC_Command(dat);
    90. }
    91. }

    2.标准库IIC实现OLED显示

    1. /**
    2. * @brief I2C_Configuration,初始化硬件IIC引脚
    3. * @param 无
    4. * @retval 无
    5. */
    6. void I2C_Configuration(void)
    7. {
    8. I2C_InitTypeDef I2C_InitStructure;
    9. GPIO_InitTypeDef GPIO_InitStructure;
    10. /*I2C1外设时钟使能 */
    11. OLED_I2C_CLK_INIT(OLED_I2C_CLK,ENABLE);
    12. /*I2C1外设GPIO时钟使能 */
    13. RCC_APB2PeriphClockCmd(OLED_I2C_SCL_GPIO_CLK | OLED_I2C_SDA_GPIO_CLK,ENABLE);
    14. /* I2C_SCL、I2C_SDA*/
    15. GPIO_InitStructure.GPIO_Pin = OLED_I2C_SCL_PIN;
    16. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    17. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; // 开漏输出
    18. GPIO_Init(OLED_I2C_SCL_GPIO_PORT, &GPIO_InitStructure);
    19. GPIO_InitStructure.GPIO_Pin = OLED_I2C_SDA_PIN;
    20. GPIO_Init(OLED_I2C_SDA_GPIO_PORT, &GPIO_InitStructure);
    21. /* I2C 配置 */
    22. I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    23. I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; /* 高电平数据稳定,低电平数据变化 SCL 时钟线的占空比 */
    24. I2C_InitStructure.I2C_OwnAddress1 =0x10; //主机的I2C地址.和其它设备不重复即可
    25. I2C_InitStructure.I2C_Ack = I2C_Ack_Enable ;
    26. I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; /* I2C的寻址模式 */
    27. I2C_InitStructure.I2C_ClockSpeed = I2C_Speed; /* 通信速率 */
    28. I2C_Init(OLED_I2C, &I2C_InitStructure); /* I2C1 初始化 */
    29. I2C_Cmd(OLED_I2C, ENABLE); /* 使能 I2C1 */
    30. }
    31. /**
    32. * @brief I2C_WriteByte,向OLED寄存器地址写一个byte的数据
    33. * @param addr:寄存器地址
    34. * data:要写入的数据
    35. * @retval 无
    36. */
    37. void I2C_WriteByte(uint8_t addr,uint8_t data)
    38. {
    39. while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
    40. I2C_GenerateSTART(I2C1, ENABLE);//开启I2C1
    41. while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));/*EV5,主模式*/
    42. I2C_Send7bitAddress(I2C1, OLED_ADDRESS, I2C_Direction_Transmitter);//器件地址 -- 默认0x78
    43. while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
    44. I2C_SendData(I2C1, addr);//寄存器地址
    45. while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    46. I2C_SendData(I2C1, data);//发送数据
    47. while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    48. I2C_GenerateSTOP(I2C1, ENABLE);//关闭I2C1总线
    49. }
    50. /**
    51. * @brief WriteCmd,向OLED写入命令
    52. * @param I2C_Command:命令代码
    53. * @retval 无
    54. */
    55. void WriteCmd(unsigned char I2C_Command)//写命令
    56. {
    57. I2C_WriteByte(0x00, I2C_Command);
    58. }
    59. /**
    60. * @brief WriteDat,向OLED写入数据
    61. * @param I2C_Data:数据
    62. * @retval 无
    63. */
    64. void WriteDat(unsigned char I2C_Data)//写数据
    65. {
    66. I2C_WriteByte(0x40, I2C_Data);
    67. }
    68. /**
    69. * @brief OLED_Init,初始化OLED
    70. * @param 无
    71. * @retval 无
    72. */
    73. void OLED_Init(void)
    74. {
    75. delay_ms(1000); // 1s,这里的延时很重要,上电后延时,没有错误的冗余设计
    76. WriteCmd(0xAE); //display off
    77. WriteCmd(0x20); //Set Memory Addressing Mode
    78. WriteCmd(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
    79. WriteCmd(0xb0); //Set Page Start Address for Page Addressing Mode,0-7
    80. WriteCmd(0xc8); //Set COM Output Scan Direction
    81. WriteCmd(0x00); //---set low column address
    82. WriteCmd(0x10); //---set high column address
    83. WriteCmd(0x40); //--set start line address
    84. WriteCmd(0x81); //--set contrast control register
    85. WriteCmd(0xff); //亮度调节 0x00~0xff
    86. WriteCmd(0xa1); //--set segment re-map 0 to 127
    87. WriteCmd(0xa6); //--set normal display
    88. WriteCmd(0xa8); //--set multiplex ratio(1 to 64)
    89. WriteCmd(0x3F); //
    90. WriteCmd(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
    91. WriteCmd(0xd3); //-set display offset
    92. WriteCmd(0x00); //-not offset
    93. WriteCmd(0xd5); //--set display clock divide ratio/oscillator frequency
    94. WriteCmd(0xf0); //--set divide ratio
    95. WriteCmd(0xd9); //--set pre-charge period
    96. WriteCmd(0x22); //
    97. WriteCmd(0xda); //--set com pins hardware configuration
    98. WriteCmd(0x12);
    99. WriteCmd(0xdb); //--set vcomh
    100. WriteCmd(0x20); //0x20,0.77xVcc
    101. WriteCmd(0x8d); //--set DC-DC enable
    102. WriteCmd(0x14); //
    103. WriteCmd(0xaf); //--turn on oled panel
    104. }

    3.HAL库模拟IIC实现OLED显示

    1. static void OLED_GPIO_Init(void)
    2. {
    3. GPIO_InitTypeDef GPIO_Struct;
    4. /* GPIO Ports Clock Enable */
    5. __HAL_RCC_GPIOB_CLK_ENABLE();
    6. GPIO_Struct.Pin = GPIO_PIN_7| GPIO_PIN_6;
    7. GPIO_Struct.Mode = GPIO_MODE_OUTPUT_PP;
    8. GPIO_Struct.Speed = GPIO_SPEED_FREQ_LOW;
    9. HAL_GPIO_Init(GPIOB, &GPIO_Struct);
    10. }
    11. void OLED_GPIO(uint8_t add,uint8_t date)
    12. {
    13. if(add==0)
    14. {
    15. if(date==1) HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
    16. else if(date==0)HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
    17. }
    18. else if(add==1)
    19. {
    20. if(date==1) HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
    21. else if(date==0)HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
    22. }
    23. }
    24. /**************************************************/
    25. /* IIC Start */
    26. /**************************************************/
    27. void IIC_Start()
    28. {
    29. OLED_GPIO(OLED_SDA,1);
    30. OLED_GPIO(OLED_CLK,1);
    31. OLED_GPIO(OLED_SDA,0);
    32. OLED_GPIO(OLED_CLK,0);
    33. }
    34. /**************************************************/
    35. /* IIC Stop */
    36. /**************************************************/
    37. void IIC_Stop()
    38. {
    39. OLED_GPIO(OLED_CLK,1);
    40. OLED_GPIO(OLED_SDA,0);
    41. OLED_GPIO(OLED_CLK,1);
    42. OLED_GPIO(OLED_SDA,1);
    43. OLED_GPIO(OLED_CLK,1);
    44. }
    45. void IIC_Wait_Ack() //检测应答
    46. {
    47. OLED_GPIO(OLED_SDA,0);
    48. OLED_GPIO(OLED_CLK,1);
    49. OLED_GPIO(OLED_CLK,0);
    50. }
    51. /**************************************************/
    52. /* IIC Write byte */
    53. /**************************************************/
    54. void Write_IIC_Byte(uint8_t IIC_Byte)
    55. {
    56. uint8_t i;
    57. uint8_t m,da;
    58. da=IIC_Byte;
    59. OLED_GPIO(OLED_CLK,0);
    60. for(i=0;i<8;i++)
    61. {
    62. m=da;
    63. // OLED_SCLK_Clr();
    64. m=m&0x80;
    65. if(m==0x80)
    66. {
    67. OLED_GPIO(OLED_SDA,1);
    68. }
    69. else
    70. OLED_GPIO(OLED_SDA,0);
    71. da=da<<1;
    72. OLED_GPIO(OLED_CLK,1);
    73. OLED_GPIO(OLED_CLK,0);
    74. }
    75. }
    76. /*********************************************/
    77. /* IIC Write Command */
    78. /*********************************************/
    79. void Write_IIC_Command(uint8_t IIC_Command) //写命令
    80. {
    81. IIC_Start();
    82. Write_IIC_Byte(0x78); // OLED的I2C地址(禁止修改)
    83. IIC_Wait_Ack();
    84. Write_IIC_Byte(0x00); // OLED 指令(禁止修改)
    85. IIC_Wait_Ack();
    86. Write_IIC_Byte(IIC_Command);
    87. IIC_Wait_Ack();
    88. IIC_Stop();
    89. }
    90. /*********************************************/
    91. /* IIC Write Data */
    92. /*********************************************/
    93. void Write_IIC_Data(uint8_t IIC_Data) //写数据
    94. {
    95. IIC_Start();
    96. Write_IIC_Byte(0x78); // OLED的I2C地址(禁止修改)
    97. IIC_Wait_Ack();
    98. Write_IIC_Byte(0x40); // OLED 数据(禁止修改)
    99. IIC_Wait_Ack();
    100. Write_IIC_Byte(IIC_Data);
    101. IIC_Wait_Ack();
    102. IIC_Stop();
    103. }
    104. void OLED_WR_Byte(uint8_t dat,uint8_t cmd)
    105. {
    106. if(cmd)
    107. {
    108. Write_IIC_Data(dat);
    109. }
    110. else
    111. {
    112. Write_IIC_Command(dat);
    113. }
    114. }

    4.HAL库IIC实现OLED显示

    1. //写命令
    2. void OLED_WR_CMD(uint8_t cmd)
    3. {
    4. HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x00,I2C_MEMADD_SIZE_8BIT,&cmd,1,0x100);
    5. }
    6. //写数据
    7. void OLED_WR_DATA(uint8_t data)
    8. {
    9. HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x40,I2C_MEMADD_SIZE_8BIT,&data,1,0x100);
    10. }
    11. void WriteCmd()
    12. {
    13. HAL_Delay(1000); // 1s,这里的延时很重要,上电后延时,没有错误的冗余设计
    14. OLED_WR_CMD(0xAE); //display off
    15. OLED_WR_CMD(0x20); //Set Memory Addressing Mode
    16. OLED_WR_CMD(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
    17. OLED_WR_CMD(0xb0); //Set Page Start Address for Page Addressing Mode,0-7
    18. OLED_WR_CMD(0xc8); //Set COM Output Scan Direction
    19. OLED_WR_CMD(0x00); //---set low column address
    20. OLED_WR_CMD(0x10); //---set high column address
    21. OLED_WR_CMD(0x40); //--set start line address
    22. OLED_WR_CMD(0x81); //--set contrast control register
    23. OLED_WR_CMD(0xff); //亮度调节 0x00~0xff
    24. OLED_WR_CMD(0xa1); //--set segment re-map 0 to 127
    25. OLED_WR_CMD(0xa6); //--set normal display
    26. OLED_WR_CMD(0xa8); //--set multiplex ratio(1 to 64)
    27. OLED_WR_CMD(0x3F); //
    28. OLED_WR_CMD(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
    29. OLED_WR_CMD(0xd3); //-set display offset
    30. OLED_WR_CMD(0x00); //-not offset
    31. OLED_WR_CMD(0xd5); //--set display clock divide ratio/oscillator frequency
    32. OLED_WR_CMD(0xf0); //--set divide ratio
    33. OLED_WR_CMD(0xd9); //--set pre-charge period
    34. OLED_WR_CMD(0x22); //
    35. OLED_WR_CMD(0xda); //--set com pins hardware configuration
    36. OLED_WR_CMD(0x12);
    37. OLED_WR_CMD(0xdb); //--set vcomh
    38. OLED_WR_CMD(0x20); //0x20,0.77xVcc
    39. OLED_WR_CMD(0x8d); //--set DC-DC enable
    40. OLED_WR_CMD(0x14); //
    41. OLED_WR_CMD(0xaf); //--turn on oled panel
    42. }

    实现效果

     由于频闪的原因,拍不全。

    从代码上可以发现,IIC实现比模拟IIC实现起来要简单不少。

    代码下载

    创作不易,下面提供下载链接,涉及以上四种实现方法源码。

    如有问题或需求可私信交流

    源码下载地址:

    STM32实现0.96寸OLED显示模拟IIC和IIC四种实现(标准库和HAL库)-C文档类资源-CSDN文库

    吾芯电子工作室

  • 相关阅读:
    极客日报:腾讯推出员工退休待遇方案;​百度高管称自动驾驶并非100%无事故;美国悬赏1500万美元通缉黑客
    git简单命令
    怎么清理mac电脑垃圾文件 怎么清理mac电脑垃圾软件 清洁mac系统 cleanmymac软件卸载 mac软件卸载 卸载mac应用程序
    第十一章 信号(一)- 概念
    【虚拟语气练习题】对过去的虚拟
    chatgpt赋能python:Python如何快速取出所有元素?
    单商户商城系统功能拆解26—营销中心—限时秒杀
    如何安装 Wnmp 并结合内网穿透实现外网访问内网Wnmp 服务
    DevSecOps:软件安全捍卫者
    上线项目问题——无法加载响应数据
  • 原文地址:https://blog.csdn.net/XiaoCaiDaYong/article/details/127907499