聪聪哥哥 发表于 2025-5-26 15:56

【STM32C092RC 测评】+10使用硬件IIC驱动OLED屏幕

本帖最后由 聪聪哥哥 于 2025-5-26 16:44 编辑

一:OLED知识分享OLED,即有机发光二极管(Organic Light-Emitting Diode),又称为有机电激光显示(Organic Electroluminesence Display, OELD)。因为具备轻薄、省电等特性,因此从 2003 年开始,这种显示设备在 MP3 播放器上得到了广泛应用,而对于同属数码类产品的 DC 与手机,此前只是在一些展会上展示过采用 OLED 屏幕的工程样品。自 2007 年后,寿命得 到很大提高,具备了许多 LCD 不可比拟的优势。
GND:电源地 VCC:2.2V~5.5V SCL(D0):CLK 时钟 (高电平 2.2V~5.5V) SDA(D1):MOSI 数据(高电平 2.2V~5.5V) RST:复位(高电平 2.2V~5.5V) D/C:数据/命令(高电平 2.2V~5.5V) 兼容 3.3V 和 5V 控制芯片的 I/O 电平(无需任何设置,直接兼容)。

实物图片如下:

二:字符建立过程:

这里参考上图对字库进行配置就可以了
三:STM32 cube MX 的配置过程

这里我使用的引脚是 PB8,PB9,也是为STM32C092绘制了一个拓展版,方便对其进行测试,
直接好似用硬件的IIC即可。
注意使能硬件IIC

四:软件代码编写:
底层驱动的编写函数
extern I2C_HandleTypeDef hi2c1;
/***********************************************************************************************
* @brief   static unsigned char OLED_send_byteS(unsigned char *data, unsigned char length)
* @param    data:输入的数据length:长度值,使用硬件IIC底层驱动函数
* @retval无
* @author聪聪哥哥
* @version V1.1.0
* @date   25-5-2025
*************************************************************************************************/
static unsigned char OLED_send_byteS(unsigned char *data, unsigned char length)
{
      if (HAL_I2C_Master_Transmit(&hi2c1, 0x78, data, length, 2) != HAL_OK)
      {
                return 0;
      }
      return 1;
}

/***********************************************************************************************
* @brief   static void I2C_WriteByte(uint8_t addr, uint8_t value)
* @param    addr:IIC模块的地址,value :写入的数据
* @retval无
* @author聪聪哥哥
* @version V1.1.0
* @date   25-5-2025
*************************************************************************************************/
static void I2C_WriteByte(uint8_t addr, uint8_t value)
{
      unsigned char dta = {0};
      dta = addr;
      dta = value;
      OLED_send_byteS(dta, 2);
}

/***********************************************************************************************
* @brief   void WriteCmd(unsigned char I2C_Command)
* @param    I2C_Command : IIC的命令
* @retval无
* @author聪聪哥哥
* @version V1.1.0
* @date   25-5-2025
*************************************************************************************************/
void WriteCmd(unsigned char I2C_Command)
{
      I2C_WriteByte(0x00, I2C_Command);
}

/***********************************************************************************************
* @brief   void WriteDat(unsigned char I2C_Data)
* @param    I2C_Data : IIC的数据
* @retval无
* @author聪聪哥哥
* @version V1.1.0
* @date   25-5-2025
*************************************************************************************************/
void WriteDat(unsigned char I2C_Data)//写数据
{
      I2C_WriteByte(0x40, I2C_Data);
}显示部分函数如下所示:
void OLED_ShowChinese(uint8_t x,uint8_t y,uint8_t num,uint8_t size1)
{
      uint8_t i,m,n=0,temp,chr1;
      uint8_t x0=x,y0=y;
      uint8_t size3=size1/8;
      while(size3--)
      {
                chr1=num*size1/8+n;
                n++;
                        for(i=0;i<size1;i++)
                        {
                              if(size1==16)
                                                {temp=Hzk1;}//调用16*16字体
                              else if(size1==24)
                                                {temp=Hzk2;}//调用24*24字体
                              else if(size1==32)      
                                                {temp=Hzk3;}//调用32*32字体
                              else if(size1==64)
                                                {temp=Hzk4;}//调用64*64字体
                              else return;
                                                      
                                                for(m=0;m<8;m++)
                                                      {
                                                                if(temp&0x01)
                                                                {OLED_DrawPoint(x,y);}
                                                                temp>>=1;
                                                                y++;
                                                      }
                                                      x++;
                                                      if((x-x0)==size1)
                                                      {x=x0;y0=y0+8;}
                                                      y=y0;
                         }
      }
}


void OLED_Fill(unsigned char fill_Data)//全屏填充
{
      unsigned char m,n;
      for(m=0;m<8;m++)
      {
                WriteCmd(0xb0+m);                //page0-page1
                WriteCmd(0x02);                //low column start address
                WriteCmd(0x10);                //high column start address
                for(n=0;n<128;n++)
                        {
                              WriteDat(fill_Data);
                        }
      }
}初始化屏幕的驱动代码:
void OLED_Init(void)
{
      WriteCmd(0xAE); //display off
      WriteCmd(0x20);      //Set Memory Addressing Mode      
      WriteCmd(0x10);      //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
      WriteCmd(0xb0);      //Set Page Start Address for Page Addressing Mode,0-7
      WriteCmd(0xc8);      //Set COM Output Scan Direction
      WriteCmd(0x00); //---set low column address
      WriteCmd(0x10); //---set high column address
      WriteCmd(0x40); //--set start line address
      WriteCmd(0x81); //--set contrast control register
      WriteCmd(0xff); //亮度调节 0x00~0xff
      WriteCmd(0xa1); //--set segment re-map 0 to 127
      WriteCmd(0xa6); //--set normal display
      WriteCmd(0xa8); //--set multiplex ratio(1 to 64)
      WriteCmd(0x3F); //
      WriteCmd(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
      WriteCmd(0xd3); //-set display offset
      WriteCmd(0x00); //-not offset
      WriteCmd(0xd5); //--set display clock divide ratio/oscillator frequency
      WriteCmd(0xf0); //--set divide ratio
      WriteCmd(0xd9); //--set pre-charge period
      WriteCmd(0x22); //
      WriteCmd(0xda); //--set com pins hardware configuration
      WriteCmd(0x12);
      WriteCmd(0xdb); //--set vcomh
      WriteCmd(0x20); //0x20,0.77xVcc
      WriteCmd(0x8d); //--set DC-DC enable
      WriteCmd(0x14); //
      WriteCmd(0xaf); //--turn on oled panel
      OLED_Fill(0xff);//全屏填充
      OLED_ON();
}
主函数部分如下所示:
OLED_Init();
      OLED_ColorTurn(0);//0?????????1 ??????
OLED_DisplayTurn(0);//0??????? 1 ?????????
      OLED_Refresh();
      OLED_Clear();

      OLED_ShowCN(16, 0, 0);
      OLED_ShowCN(32, 0, 1);
      OLED_ShowCN(48, 0, 2);
      OLED_ShowCN(64, 0, 3);

      OLED_ShowCN(16, 2, 4);
      OLED_ShowCN(32, 2, 4);

      OLED_ShowCN(48, 2, 5);
      OLED_ShowCN(64, 2, 5);


      OLED_ShowStr(40, 4, (uint8_t *)test_str, 2);
      OLED_ShowStr(40, 6, (uint8_t *)test_str1, 2);测试图片如下所示:

daichaodai 发表于 2025-5-26 19:18

硬件IIC稳定吗?还有bug没有?

聪聪哥哥 发表于 2025-5-26 19:43

daichaodai 发表于 2025-5-26 19:18
硬件IIC稳定吗?还有bug没有?

{:titter:},只是显示个数据,我一般不使用软件模拟的,时序调不好,影响太大了,还只能是延时函数。

qintian0303 发表于 2025-5-27 14:01

这不是单色的看着效果更好了   

t60yz 发表于 2025-5-31 23:41

初始化时需正确发送指令序列,建议使用成熟驱动库(如 u8g2 / Adafruit_SSD1306 / HAL 驱动)
页: [1]
查看完整版本: 【STM32C092RC 测评】+10使用硬件IIC驱动OLED屏幕