7. OLED模块

7.1. 模块简介

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

7.2. 模块的引脚说明

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

蓝色OLED模块的引脚说明

编号

名称

说明

1

VCC

电源正

2

GND

地线

3

CLK

SPI时钟引脚

4

MOSI

主出从入引脚

5

CS

片选

6

DC

高电平时写数据,低电平时写命令

7.3. 实验现象

这里采用的是软件SPI,所以引脚可以自己根据开发板情况定义,这里以F767挑战者为例,打开例程找到OLED.h,代码如下,这里CS定义为PC2,DC定义为PI3,SDA定义为PC6,CLK定义为PC7。

OLED.h
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 //引脚定义
 /*******************************************************/
 /*CS引脚*/
 #define OLED_CS_PIN                  GPIO_PIN_2
 #define OLED_CS_GPIO_PORT            GPIOC
 #define OLED_CS_GPIO_CLK_ENABLE()    __GPIOC_CLK_ENABLE()

 /*DC引脚*/
 #define OLED_DC_PIN                  GPIO_PIN_3
 #define OLED_DC_GPIO_PORT            GPIOI
 #define OLED_DC_GPIO_CLK_ENABLE()    __GPIOI_CLK_ENABLE()

 /*MOSI引脚*/
 #define OLED_SDA_PIN                  GPIO_PIN_6
 #define OLED_SDA_GPIO_PORT            GPIOC
 #define OLED_SDA_GPIO_CLK_ENABLE()    __GPIOC_CLK_ENABLE()

 /*CLK引脚*/
 #define OLED_CLK_PIN                  GPIO_PIN_7
 #define OLED_CLK_GPIO_PORT            GPIOC
 #define OLED_CLK_GPIO_CLK_ENABLE()    __GPIOC_CLK_ENABLE()
 /************************************************************/

 // ... ...

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

oled_iic_1

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

oled_iic

7.4. 例程介绍

首先来看一下软件SPI的引脚的初始化,开启相关的引脚时钟,所有引脚的模式都设置为GPIO_MODE_OUTPUT_PP,引脚速率设置为高速模式。

OLED.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
 void OLED_GPIO_Config(void)
 {
     /*定义一个GPIO_InitTypeDef类型的结构体*/
     GPIO_InitTypeDef  GPIO_InitStruct;

     /*开启OLED相关的GPIO外设时钟*/
     OLED_CS_GPIO_CLK_ENABLE();
     OLED_DC_GPIO_CLK_ENABLE();
     OLED_SDA_GPIO_CLK_ENABLE();
     OLED_CLK_GPIO_CLK_ENABLE();

     /*选择要控制的GPIO引脚*/
     GPIO_InitStruct.Pin = OLED_CS_PIN;

     /*设置引脚的输出类型为推挽输出*/
     GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;

     /*设置引脚速率为高速 */
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

     /*调用库函数,使用上面配置的GPIO_InitStructure初始化GPIO*/
     HAL_GPIO_Init(OLED_CS_GPIO_PORT, &GPIO_InitStruct);

     /*选择要控制的GPIO引脚*/
     GPIO_InitStruct.Pin = OLED_DC_PIN;

     /*调用库函数,使用上面配置的GPIO_InitStructure初始化GPIO*/
     HAL_GPIO_Init(OLED_DC_GPIO_PORT, &GPIO_InitStruct);

     /*选择要控制的GPIO引脚*/
     GPIO_InitStruct.Pin = OLED_SDA_PIN;

     /*调用库函数,使用上面配置的GPIO_InitStructure初始化GPIO*/
     HAL_GPIO_Init(OLED_SDA_GPIO_PORT, &GPIO_InitStruct);

     /*选择要控制的GPIO引脚*/
     GPIO_InitStruct.Pin = OLED_CLK_PIN;

     /*调用库函数,使用上面配置的GPIO_InitStructure初始化GPIO*/
     HAL_GPIO_Init(OLED_CLK_GPIO_PORT, &GPIO_InitStruct);
 }

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

OLED.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
 void OLED_Init(void)
 {
     OLED_GPIO_Config();
     DelayMs(1000);
     OLED_WrCmd(0xae);
     OLED_WrCmd(0xae);//--turn off oled panel
     OLED_WrCmd(0x00);//---set low column address
     OLED_WrCmd(0x10);//---set high column address
     OLED_WrCmd(0x40);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
     OLED_WrCmd(0x81);//--set contrast control register
     OLED_WrCmd(0xcf); // Set SEG Output Current Brightness
     OLED_WrCmd(0xa1);//--Set SEG/Column Mapping     0xa0,0xa1
     OLED_WrCmd(0xc8);//Set COM/Row Scan Direction   0xc0,0xc8
     OLED_WrCmd(0xa6);//--set normal display
     OLED_WrCmd(0xa8);//--set multiplex ratio(1 to 64)
     OLED_WrCmd(0x3f);//--1/64 duty
     OLED_WrCmd(0xd3);//-set display offset  Shift Mapping RAM Counter (0x00~0x3F)
     OLED_WrCmd(0x00);//-not offset
     OLED_WrCmd(0xd5);//--set display clock divide ratio/oscillator frequency
     OLED_WrCmd(0x80);//--set divide ratio, Set Clock as 100 Frames/Sec
     OLED_WrCmd(0xd9);//--set pre-charge period
     OLED_WrCmd(0xf1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
     OLED_WrCmd(0xda);//--set com pins hardware configuration
     OLED_WrCmd(0x12);
     OLED_WrCmd(0xdb);//--set vcomh
     OLED_WrCmd(0x40);//Set VCOM Deselect Level
     OLED_WrCmd(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02)
     OLED_WrCmd(0x02);//
     OLED_WrCmd(0x8d);//--set Charge Pump enable/disable
     OLED_WrCmd(0x14);//--set(0x10) disable
     OLED_WrCmd(0xa4);// Disable Entire Display On (0xa4/0xa5)
     OLED_WrCmd(0xa6);// Disable Inverse Display On (0xa6/a7)
     OLED_WrCmd(0xaf);//--turn on oled panel
     OLED_Fill(0x00);
     OLED_SetPos(0,0);
 }

在main函数中,先初始化系统滴答定时器,初始化LED、串口、OLED。

在循环中点亮屏幕,2秒后熄灭屏幕,然后使用 OLED_16x16CN 函数显示中文,使用 OLED_6x8Str 函数测试6*8字符,使用 OLED_8x16Str函数测试8*16字符,最后只用 OLED_BMP 函数测试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
 int main(void)
 {
     uint8_t i;
     /* 配置系统时钟为216 MHz */
     SystemClock_Config();

     /* 初始化RGB彩灯 */
     LED_GPIO_Config();

     /* 初始化USART1 配置模式为 115200 8-N-1 */
     UARTx_Config();

     OLED_Init();    //初始化OLED

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

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

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

         LED_GREEN;
         for(i=0;i<4;i++)
         {
             OLED_16x16CN(22+i*16,0,i);    //测试显示中文
         }
         HAL_Delay(2000);        // 2s
         OLED_CLS();
         OLED_6x8Str(0,3,(unsigned char*)"Wildfire Tech");       //测试6*8字符
         OLED_8x16Str(0,4,(unsigned char*)"Hello wildfire");     //测试8*16字符
         HAL_Delay(2000);        // 2*100=200s
         OLED_CLS();
         OLED_BMP(0,0,128,8,(unsigned char *)BMP1);//测试BMP位图显示
         CPU_TS_Tmr_Delay_S(10); // 10s
         OLED_CLS();
     }
 }