STM32F103VE基于STM32CubeMX 配置I2C驱动0.96/1.3 OLED显示

Posted perseverance52

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32F103VE基于STM32CubeMX 配置I2C驱动0.96/1.3 OLED显示相关的知识,希望对你有一定的参考价值。

STM32F103VE基于STM32CubeMX 配置I2C驱动0.96/1.3 OLED显示


  • 📺STM32CubeMX配置I2C内容演示:

📜驱动I2C主要是勾选上I2C1功能,当然如果I2C1引脚被占用可以勾选I2C2,其他都什么功能可以根据需求自行添加。

  • 📢本工程支持同类型芯片极海APM32F103VC
  • 🌼0.96寸屏幕
  • 🌻1.3寸屏幕

本示例可以驱动0.96寸屏幕也可以驱动1.3寸屏幕,具体看下面的屏幕类型说明。

  • 🌼取模软件和方式

⛳屏幕类型说明

  • 🍁驱动0.96寸屏幕和1.3寸屏幕有2处需要调整:

在oled.c文件中OLED_Init()函数:


WriteCmd(0x02); //-设置低位列地址set low column address 注意:0.96屏幕从0x00开始写数据,1.3寸屏幕从0x02开始写数据
WriteCmd(0x10); //---set high column address
WriteCmd(0x40); //--set start line address
  • LED_Fill清屏函数:
void OLED_Fill(unsigned char fill_Data)//全屏填充

    unsigned char m,n;
    for(m=0;m<8;m++)
    
        WriteCmd(0xb0+m);       //page0-page1
        WriteCmd(0x00);     //	//low  column start address1.3寸屏幕发送地址是从0x02开始的,0.96屏幕是从0x00地址开始的特别注意个地方!!!
        WriteCmd(0x10);     //high column start address
        for(n=0;n<128;n++)
            
                WriteDat(fill_Data);
            
    

📝OLED屏幕驱动和显示函数

🔖屏幕驱动显示资料可以在网上找,一般购买OLED屏幕厂家都会提供例程。

  • oled.h
#ifndef __OLED_H
#define __OLED_H     

#include "i2c.h"
 
 #define u8 uint8_t
 #define u32 uint32_t
//    一些使用例子
//      OLED_ShowStr(0, 0, "hello world", 2);//显示字符串
//    OLED_ShowStr(0, 2, "hello world", 1);//显示字符串
//    OLED_ShowCN_STR(0, 4 , 0 , 8);
//      sprintf(num_temp_buffer,"show num:%0.2f",num);
//      OLED_ShowStr(0, 6, num_temp_buffer, 2);//显示字符串
//      OLED_CLS();
//      OLED_DrawBMP(0,0,128,7,BMP2);

#define OLED0561_ADD    0x78  // OLED的I2C地址(禁止修改)
#define COM             0x00  // OLED 指令(禁止修改)
#define DAT             0x40  // OLED 数据(禁止修改)

void WriteCmd(unsigned char I2C_Command);//写命令
void WriteDat(unsigned char I2C_Data);//写数据
void OLED_Init(void);//初始化
void OLED_SetPos(unsigned char x, unsigned char y);
void OLED_Fill(unsigned char fill_Data);//全屏填充
void OLED_CLS(void);
void OLED_ON(void);
void OLED_OFF(void);
void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize);//显示字符串
void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N);//显示汉字
void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[]);//显示图片(取模:阴,列行,逆,输出索引,精简)

void OLED_ShowCN_STR(u8 x , u8 y , u8 begin , u8 num);  //自己写的输出中文字符串

void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size);
u32 oled_pow(u8 m,u8 n);
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size2);//size2(16|12)

#endif
  • oled.c
#include "oled.h"
#include "ascii.h"
#include "main.h"
void WriteCmd(unsigned char I2C_Command)//写命令
 
    HAL_I2C_Mem_Write(&hi2c1,OLED0561_ADD,COM,I2C_MEMADD_SIZE_8BIT,&I2C_Command,1,100);
 
       
void WriteDat(unsigned char I2C_Data)//写数据
 
        HAL_I2C_Mem_Write(&hi2c1,OLED0561_ADD,DAT,I2C_MEMADD_SIZE_8BIT,&I2C_Data,1,100);
  
    void OLED_Init(void)

    HAL_Delay(100); //这里的延时很重要
   
    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


void OLED_SetPos(unsigned char x, unsigned char y) //设置起始点坐标

    WriteCmd(0xb0+y);
    WriteCmd(((x&0xf0)>>4)|0x10);
    WriteCmd((x&0x0f)|0x01);


void OLED_Fill(unsigned char fill_Data)//全屏填充

    unsigned char m,n;
    for(m=0;m<8;m++)
    
        WriteCmd(0xb0+m);       //page0-page1
        WriteCmd(0x00);     //low column start address
        WriteCmd(0x10);     //high column start address
        for(n=0;n<128;n++)
            
                WriteDat(fill_Data);
            
    



void OLED_CLS(void)//清屏

    OLED_Fill(0x00);


void OLED_ON(void)

    WriteCmd(0X8D);  //设置电荷泵
    WriteCmd(0X14);  //开启电荷泵
    WriteCmd(0XAF);  //OLED唤醒


void OLED_OFF(void)

    WriteCmd(0X8D);  //设置电荷泵
    WriteCmd(0X10);  //关闭电荷泵
    WriteCmd(0XAE);  //OLED休眠


// Parameters     : x,y -- 起始点坐标(x:0~127, y:0~7); ch[] -- 要显示的字符串; TextSize -- 字符大小(1:6*8 ; 2:8*16)
// Description    : 显示codetab.h中的ASCII字符,有6*8和8*16可选择
void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize)

    unsigned char c = 0,i = 0,j = 0;
    switch(TextSize)
    
        case 1:
        
            while(ch[j] != '\\0')
            
                c = ch[j] - 32;
                if(x > 126)
                
                    x = 0;
                    y++;
                
                OLED_SetPos(x,y);
                for(i=0;i<6;i++)
                    WriteDat(F6x8[c][i]);
                x += 6;
                j++;
            
        break;
        case 2:
        
            while(ch[j] != '\\0')
            
                c = ch[j] - 32;
                if(x > 120)
                
                    x = 0;
                    y++;
                
                OLED_SetPos(x,y);
                for(i=0;i<8;i++)
                    WriteDat(F8X16[c*16+i]);
                OLED_SetPos(x,y+1);
                for(i=0;i<8;i++)
                    WriteDat(F8X16[c*16+i+8]);
                x += 8;
                j++;
            
        break;
    


// Parameters     : x,y -- 起始点坐标(x:0~127, y:0~7); N:汉字在.h中的索引
// Description    : 显示ASCII_8x16.h中的汉字,16*16点阵
void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)

    unsigned char wm=0;
    unsigned int  adder=32*N;
    OLED_SetPos(x , y);
    for(wm = 0;wm < 16;wm++)
    
        WriteDat(F16x16[adder]);
        adder += 1;
    
    OLED_SetPos(x,y + 1);
    for(wm = 0;wm < 16;wm++)
    
        WriteDat(F16x16[adder]);
        adder += 1;
    


// 这是自己写的显示中文字符串的函数,要先把中文字符串“共阴——列行式——逆向输出”取字模后存入ascll.h相应的位置(连续存入)
//传入参数分别为:x:起始横坐标  
//                              y:纵坐标(填入0-7)  
//                              begin:填入的中文字符串的第一个字在我们ascll.c字库里面的序号  
//                num:我们要填写几个字
//                比如要填“测试”,取完字模存入后这两个字在字库中序号为0,1,横坐标0,纵坐标第二行,就填:x:0,y:2,begin:0,num:2
void OLED_ShowCN_STR(u8 x , u8 y , u8 begin , u8 num)

    u8 i;
    for(i=0;i<num;i++)OLED_ShowCN(i*16+x,y,i+begin);    //OLED显示标题


// Parameters     : x0,y0 -- 起始点坐标(x0:0~127, y0:0~7); x1,y1 -- 起点对角线(结束点)的坐标(x1:1~128,y1:1~8)
// Description    : 显示BMP位图
void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[])

    unsigned int j=0;
    unsigned char x,y;

  if(y1%8==0)
        y = y1/8;
  else
        y = y1/8 + 1;
    for(y=y0;y<y1;y++)
    
        OLED_SetPos(x0,y);
    for(x=x0;x<x1;x++)
        
            WriteDat(BMP[j++]);
        
    


void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size)
      
    unsigned char c=0,i=0; 
        c=chr-' ';//得到偏移后的值          
        if(x>128-1)x=0;y=y+2;
        if(Char_Size ==16)
            
            OLED_SetPos(x,y);  
            for(i=0;i<8;i++)
            WriteDat(F8X16[c*16+i]);
            OLED_SetPos(x,y+1);
            for(i=0;i<8;i++)
            WriteDat(F8X16[c*16+i+8]);
            
            else  
                OLED_SetPos(x,y);
                for(i=0;i<6;i++)
                WriteDat(F6x8[c][i]);
               
            

u32 oled_pow(u8 m,u8 n)

    u32 result=1;    
    while(n--)result*=m;    
    return result;
  
//显示2个数字
//x,y :起点坐标  
//len :数字的位数
//size:字体大小
//mode:模式   0,填充模式;1,叠加模式
//num:数值(0~4294967295);          
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size2)
          
    u8 t,temp;
    u8 enshow=0;                           
    for(t=0;t<len;t++)
    
        temp=(num/oled_pow(10,len-t-1))%10;
        if(enshow==0&&t<(len-1))
        
            if(temp==0)
            
                OLED_ShowChar(x+(size2/2)*t,y,' ',size2);
                continue;
            else enshow=1;
        
        OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2);
    



  • ascii.h
#ifndef __ASCII_H
#define __ASCII_H    


/***************************16*16的点阵字体取模方式:共阴——列行式——逆向输出*********/

unsigned char  F16x16[] =

// 好(0) 好(1) 学(2) 习(3) 天(4) 天(5) 向(6) 上(7)

0x10,0x10,0xF0,0x1F,0x10,0xF0,0x00,0x80,0x82,0x82,0xE2,0x92,0x8A,0x86,0x80,0x00,
0x40,0x22,0x15,0x08,0x16,0x61,0x00,0x00,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,/*"好",0*/

0x10,0x10,0xF0,0x1F,以上是关于STM32F103VE基于STM32CubeMX 配置I2C驱动0.96/1.3 OLED显示的主要内容,如果未能解决你的问题,请参考以下文章

STM32学习笔记 二基于STM32F103C8T6和STM32CubeMX实现UART串口通信数据收发

STM32F103VET6基于STM32CubeMX利用EXTI外部中断测量PWM频率

STM32学习笔记 一基于STM32F103C8T6最小系统板和STM32CubeMX实现板载LED灯循环闪烁

STM32F103VET6基于STM32CubeMX RTC时钟报警中断使用示例

三实战小例程 基于STM32F103C8T6最小系统板和STM32CubeMX驱动WS2812B光立方

三实战小例程 基于STM32F103C8T6最小系统板和STM32CubeMX驱动WS2812B光立方