3. OLED模块

3.1. 模块简介

野火0.96寸黄蓝双色OLED模块通讯方式为IIC,分辨率为128*64。

3.2. 模块的引脚说明

该模块使用IIC通讯,管脚定义如下,

黄蓝双色OLED模块的引脚说明

编号

名称

说明

1

VCC

电源正

2

GND

地线

3

SCL

IIC时钟引脚

4

SDA

IIC数据引脚

3.3. 实验现象

这里不管你是用的野火哪款开发板,请打开对应的开发板LOED例程,打开 OLED_I2C.h,就可以看到I2C的引脚定义,这里以STM32F103霸道开发板为例,

可以看到,I2C的SCL引脚为PB6,SDA引脚为PB7。

OLED_I2C.h
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
 /*I2C接口*/
 #define OLED_I2C                          I2C1
 #define OLED_I2C_CLK                      RCC_APB1Periph_I2C1
 #define OLED_I2C_CLK_INIT                 RCC_APB1PeriphClockCmd

 #define OLED_I2C_SCL_PIN                  GPIO_Pin_6
 #define OLED_I2C_SCL_GPIO_PORT            GPIOB
 #define OLED_I2C_SCL_GPIO_CLK             RCC_AHB1Periph_GPIOB
 #define OLED_I2C_SCL_SOURCE               GPIO_PinSource6
 #define OLED_I2C_SCL_AF                   GPIO_AF_I2C1

 #define OLED_I2C_SDA_PIN                  GPIO_Pin_7
 #define OLED_I2C_SDA_GPIO_PORT            GPIOB
 #define OLED_I2C_SDA_GPIO_CLK             RCC_AHB1Periph_GPIOB
 #define OLED_I2C_SDA_SOURCE               GPIO_PinSource7
 #define OLED_I2C_SDA_AF                   GPIO_AF_I2C1

将OLED与开发板按照上面定义的方式连接,再用USB线连接开发板与电脑,打开电脑上的野火多功能上位机助手,与开发板进行连接,然后将程序下载到开发板, 上位机会打印如下信息,

oled_iic_1

同时,OLED上会显示如下内容,

oled_iic

3.4. 例程介绍

首先来看一下IIC的初始化,这里将SCL、SDA引脚都设置为开漏模式,将IIC设置为快速模式,代码如下,

OLED_I2C.c
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 void I2C_Configuration(void)
 {
     I2C_InitTypeDef  I2C_InitStructure;
     GPIO_InitTypeDef  GPIO_InitStructure;

     OLED_I2C_CLK_INIT(OLED_I2C_CLK,ENABLE);
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

     GPIO_InitStructure.GPIO_Pin = OLED_I2C_SCL_PIN;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;         // 开漏输出
     GPIO_Init(OLED_I2C_SCL_GPIO_PORT, &GPIO_InitStructure);

     GPIO_InitStructure.GPIO_Pin = OLED_I2C_SDA_PIN;
     GPIO_Init(OLED_I2C_SDA_GPIO_PORT, &GPIO_InitStructure);

     I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
     I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;// 高电平数据稳定,低电平数据变化 SCL 时钟线的占空比
     I2C_InitStructure.I2C_OwnAddress1 = OLED_ADDRESS; // OLED的I2C地址
     I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;       // ACK使能
     I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;// I2C的寻址模式
     I2C_InitStructure.I2C_ClockSpeed = I2C_Speed;     // 设置为快捷模式

     I2C_Init(I2C1, &I2C_InitStructure);               // I2C1 初始化
     I2C_Cmd(I2C1, ENABLE);                            // 使能 I2C1
 }

再来看一下OLED的初始化,这里是对OLED的寄存器进行操作,这些参数不需要去了解,默认也不需要修改。

OLED_I2C.c
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 void OLED_Init(void)
 {
     Delay_s(1);             // 1s,这里的延时很重要,上电后延时,没有错误的冗余设计

     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
 }

最后来看一下main函数,在这里需要先初始化LED和串口,用于调试,初始化系统滴答定时器,用于调用延时函数, 再初始化IIC的配置及OLED。

在循环中点亮全屏,再息屏,然后用 OLED_ShowCN 函数在OLED上显示中文,用 OLED_ShowStr函数显示字符串,用 OLED_DrawBMP函数显示BMP位图。

main.c
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 int main(void)
 {
     unsigned char i;
     /*初始化LED、串口*/
     LED_GPIO_Config();
     USART_Config();
     LED_BLUE;

     printf("\r\n 欢迎使用野火 F103-霸道 STM32 开发板 \r\n");
     printf("\r\n 这是一个I2C外设OLED测试例程! \r\n");

     SysTick_Init();   //初始化延迟函数
     I2C_Configuration();//配置CPU的硬件I2C
     OLED_Init();    //初始化OLED

     printf("\r\n OLED初始化成功,OLED正在工作! \r\n");

     while(1)
     {
         OLED_Fill(0xFF);//全屏点亮
         Delay_s(2);         // 2s

         OLED_Fill(0x00);//全屏灭
         Delay_s(2);         // 2s

         LED_GREEN;
         for(i=0;i<4;i++)
         {
             OLED_ShowCN(22+i*16,0,i);                          //测试显示中文
         }
         Delay_s(2);          // 2s
         OLED_ShowStr(0,3,(unsigned char*)"Wildfire Tech",1);   //测试6*8字符
         OLED_ShowStr(0,4,(unsigned char*)"Hello wildfire",2);  //测试8*16字符
         Delay_s(200);       // 2*100=200s
         OLED_CLS();         // 清屏
         OLED_OFF();         // 测试OLED休眠
         Delay_s(2);         // 2s
         OLED_ON();//测试OLED休眠后唤醒
         OLED_DrawBMP(0,0,128,8,(unsigned char *)BMP1);//测试BMP位图显示
         Delay_s(200);       // 2*100=200s
     }
 }

3.5. 汉字取模方法

3.5.1. 第一步

打开屏幕附赠资料里面的“PCtoLCD2002.exe”取模软件,软件路径如下 “3-配套软件128x64取字软件”。然后点击设置按钮,将字模选项设置成截图里面的样子

取模软件字模设置

3.5.2. 第二步

把想要生成的字模的文字输入在下面的输入框里面,然后点击生成字模

取模软件生成字模

3.5.3. 第三步

复制字模输出框里面的字模数据并替换掉工程目录下codetab.h头文件里面F16x16数组里面的原本的字模数据,如下图所示。

取模软件使用方法

替换后的效果

取模软件使用方法2

3.5.4. 第四步

编译下载程序,观察到实验现象如下图所示

OLED显示

3.6. 汉字显示函数分析

OLED_ShowCN函数
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 /**
   * @brief  OLED_ShowCN,显示codetab.h中的汉字,16*16点阵
   * @param  x,y: 起始点坐标(x:0~127, y:0~7);
   *                                 N:汉字在codetab.h中的索引
   * @retval 无
   */
 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;
   }
 }

从函数里面可以看出,显示一个汉字总共分为两步,第一步先设置汉字的显示位置,注意这里的y坐标的范围是 0-7 ,整个屏幕的一共有64行,也就是说一个y坐标是以8行为一个单位的。 第一个for循环是显示汉字的上半部分,每调用一次 WriteDat();函数之后,就会显示汉字的一列像素点,同时x坐标自动加1。显示完汉字的上半部分之后将x坐标归位同时y坐标加1, 继续显示汉字的下半部分之后就完成了显示一个汉字的整个过程。