打印
[STM32C0]

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

[复制链接]
421|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 聪聪哥哥 于 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;
/***********************************************************************************************
  * [url=home.php?mod=space&uid=247401]@brief[/url]   static unsigned char OLED_send_byteS(unsigned char *data, unsigned char length)
  * @param    data:输入的数据  length:长度值,使用硬件IIC底层驱动函数
  * @retval  无
  * [url=home.php?mod=space&uid=187600]@author[/url]  聪聪哥哥
  * @version V1.1.0
  * [url=home.php?mod=space&uid=212281]@date[/url]     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;
}

/***********************************************************************************************
  * [url=home.php?mod=space&uid=247401]@brief[/url]   static void I2C_WriteByte(uint8_t addr, uint8_t value)
  * @param    addr:IIC模块的地址,value :写入的数据
  * @retval  无
  * [url=home.php?mod=space&uid=187600]@author[/url]  聪聪哥哥
  * @version V1.1.0
  * [url=home.php?mod=space&uid=212281]@date[/url]     25-5-2025
*************************************************************************************************/
static void I2C_WriteByte(uint8_t addr, uint8_t value)
{
        unsigned char dta[2] = {0};
        dta[0] = addr;
        dta[1] = value;
        OLED_send_byteS(dta, 2);
}

/***********************************************************************************************
  * [url=home.php?mod=space&uid=247401]@brief[/url]   void WriteCmd(unsigned char I2C_Command)
  * @param    I2C_Command : IIC的命令
  * @retval  无
  * [url=home.php?mod=space&uid=187600]@author[/url]  聪聪哥哥
  * @version V1.1.0
  * [url=home.php?mod=space&uid=212281]@date[/url]     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[chr1][i];}//调用16*16字体
                                else if(size1==24)
                                                {temp=Hzk2[chr1][i];}//调用24*24字体
                                else if(size1==32)      
                                                {temp=Hzk3[chr1][i];}//调用32*32字体
                                else if(size1==64)
                                                {temp=Hzk4[chr1][i];}//调用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没有?

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

使用特权

评论回复
地板
qintian0303| | 2025-5-27 14:01 | 只看该作者
这不是单色的看着效果更好了   

使用特权

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

本版积分规则

66

主题

178

帖子

1

粉丝