目录
[1. 供电](#1. 供电)
[2. OLED](#2. OLED)
[1. 供电](#1. 供电)
[2. OLED](#2. OLED)
[1. 复制工程文件夹](#1. 复制工程文件夹)
[2. 清理](#2. 清理)
[3. OLED驱动函数模块](#3. OLED驱动函数模块)
[3.1 OLED.c](#3.1 OLED.c)
[3.1.1 引脚配置](#3.1.1 引脚配置)
[3.1.2 引脚初始化](#3.1.2 引脚初始化)
[3.2 OLED.h](#3.2 OLED.h)
[3.3 OLED_Font.h](#3.3 OLED_Font.h)
[4. main.c](#4. main.c)
本节课学习如何使用OLED显示屏的驱动函数模块。
一、接线图
打开STM32Project工程文件夹里的【1-1 接线图】,打开【4-1 OLED显示屏】。
OLED插在面包板的右下角,以后一直在这个位置。需要用的时候随时可以使用,而且放在右下角也不占地方。
1. 供电
在这里我们使用的是四针脚的OLED屏幕,GND接负极,VCC接正极。在OLED的下面,先插上两根线,把OLED的GND引到负极供电孔,OLED的VCC引的正极供电孔。另外这个供电孔也会同时接到STM32的PB6和PB7两个引脚。
STM32的引脚上电后,如果不初始化,默认是浮空输入的模式,在这个模式下,引脚不会输出电平,所以不会有什么影响。也可以不插这两根供电跳线,直接给PB6口输出低电平,PB7口输出高电平,用GPIO口直接给OLED供电,这个也是没问题的。因为这个OLED功率很小,所以也是可以驱动的。
不过这种用GPIO口供电不是很规范,自己玩儿的时候用就行了。要做实际项目的话,最好还是用电源供电。
2. OLED
插好供电跳线之后,再把OLED插到PB6到PB9这四个口。这样OLED就接好了,此时OLED的SCL接到PB8,SDA接到PB9。


二、连接电路
1. 供电
在面包板上插一下电路,先用跳线引一下电源,负极供电孔引到PB6的位置。正极供电孔引到PB7的位置。

2. OLED
然后拿出OLED屏幕,插到PB6到PB9的这四个孔里,这样就完成了。

三、工程文件
1. 复制工程文件夹
回到STM32Project工程文件夹,复制一下【3-4 按键控制LED】的工程文件夹,改个名字叫:【4-1 OLED显示屏】。


打开【4-1 OLED显示屏】文件夹,双击打开【Project.uvprojx】工程。

2. 清理
将main.c中,原有的代码都删掉。

右键main.c,选择【Close All But This】,将其他的选项卡都关掉。


3. OLED驱动函数模块
打开资料文件夹,在【STM32入门\程序源码\程序源码\STM32Project-有注释版】中找到【1-4 OLED驱动函数模块】。

将【1-4 OLED驱动函数模块】复制到【STM32Project】工程文件夹中。

在【STM32Project】中打开【1-4 OLED驱动函数模块】。里面有两个版本,一个是【4针脚I2C版本】,另一个是【7针脚SPI版本】。

打开【4针脚I2C版本】,全选,复制。

回到【STM32Project】,【4-1 OLED显示屏】,打开【Hardware】,粘贴。

之后打开Keil,在Hardware处右键,添加已经存在的文件。

打开Hardware,文件类型选择All files,按住CTRL选择OLED的三个文件,然后点击Add。然后点击Close。

这样就把这个OLED模块添加到工程里面来了。

3.1 OLED.c
OLED.c文件里面就是函数的主体代码,包括引脚配置、引脚初始化、I2C通信的基本时序和OLED用户调用的代码。
函数已经写好,绝大部分不需要更改。

需要更改的只有:引脚配置、引脚初始化。
3.1.1 引脚配置
引脚配置,选择的是硬件电路上,把SCL和SDA这两个引脚接在了哪两个端口上。

我们这里SCL接在PB8,那参数就是GPIOB,GPIO_Pin_8。
假如换了个端口,接在PA6上,那这个参数就要改成GPIOA,GPIO_Pin_6。
SDA引脚配置也一样,SDA接在哪个位置,就改成GPIO啥,GPIO_Pin_啥。

3.1.2 引脚初始化
引脚初始化。OLED_I2C_Init也得改,把SCL和SDA都初始化为开漏输出的模式。具体更改就是:使用到的GPIO外设都先用RCC开启一下时钟。然后下面初始化GPIOB的Pin8,再初始化GPIOB的Pin9,这样就完成了。
所以对于这个模块来说,默认用的是SCL接PB8,SDA接PB9。
如果你想修改,先把上面这两行引脚配置改一下,再把下面的端口初始化改一下。剩下的都不需要修改,就可以直接使用这个OLED驱动函数模块。

3.2 OLED.h
OLED.h文件里面是外部可调用函数的声明。

3.3 OLED_Font.h
OLED_Font.h文件里面存的是OLED的字库数据。因为这个i d显示屏是不带字库的,想要显示字符、图形,还得先定义字符的点阵数据。这里就是这些字符的点阵数据,也就是字库。
o l e d.c文件的显示函数会用到这些数据,我们需要把这个文件复制过来,放到工程里。字库也是不用我们修改的。现在复制完成,我们来试用一下。

先编译一下。


4. main.c
(1)main.c上面先加上:#include "OLED.h"。
(2)在main函数里,主循环之前,先调用OLED_Init();初始化OLED。
(3)OLED_ShowChar(1, 1, 'A');显示一个字符。

cpp
#include "stm32f10x.h" // Device header
#include "Delay.h"// 延时函数头文件
#include "OLED.h"
int main(void)
{
OLED_Init();
OLED_ShowChar(1, 1, 'A');
while(1)
{
}
}
编译。


下载。


看到OLED的一行一列显示了一个字符A。

(4)OLED_ShowString(1, 3, "Hello World!");显示字符串。

cpp
OLED_ShowString(1, 3, "Hello World!");
这里注意计算一下坐标和字符串长度。

编译。


下载。


在一行三列显示了Hello World和感叹号。

(5)OLED_ShowNum(2, 1, 12345, 5);
OLED_ShowNum(2, 1, 12345, 5);第2行第1列显示数字12345,长度为5。

cpp
OLED_ShowNum(2, 1, 12345, 5);
编译。


下载。



如果第4个参数,显示位数为:6,则前面自动补0。

cpp
OLED_ShowNum(2, 1, 12345, 6);
编译。


下载。



如果第4个参数,显示位数为:4,则切掉高位数据。

编译。


下载。


最高位的1就没有了。

这就是显示无符号十进制数字,这个只能显示无符号数。右键OLED_ShowNum转到定义。

每个函数都有注释,包含函数的作用、参数取值范围。

回到main.c中:
(6)OLED_ShowSignedNum(2, 7, -66, 2);
OLED_ShowSignedNum(2, 7, -66, 2);第2行第7列显示有符合数字-66,数字长度为2。

cpp
OLED_ShowSignedNum(2, 7, -66, 2);
编译。


下载。



如果参数是66。OLED_ShowSignedNum(2, 7, 66, 2);第2行第7列显示有符合数字+66,数字长度为2。

编译无错、下载成功。显示有符合数字+66。

(7)OLED_ShowHexNum(3, 1, 0xAA55, 4);
OLED_ShowHexNum(3, 1, 0xAA55, 4);显示十六进制数字。

cpp
OLED_ShowHexNum(3, 1, 0xAA55, 4);
编译无错、下载成功。

(8)OLED_ShowBinNum(4, 1, 0xAA55, 16);
OLED_ShowBinNum(4, 1, 0xAA55, 16);显示二进制数字。

cpp
OLED_ShowBinNum(4, 1, 0xAA55, 16);
编译无错、下载成功。

(9)OLED_Clear();
OLED_Clear();清屏函数。调用这个函数,OLED屏幕就会清空。

cpp
OLED_Clear();
编译无错、下载成功。
这时候OLED就不会显示任何东西,因为在最后OLED_Clear();把全屏都清屏了。

【拓展知识】
如果只想清除部分字符,可以用OLED_ShowString(覆盖对应位置的显存数据)在你想要清掉的地方显示空格字符就行了。
原因:显示字符时,OLED 驱动会把字符的点阵数据写入指定坐标的显存区域;空格字符(' ')的点阵数据是全 0(无点亮像素),因此用 OLED_ShowString 显示空格,相当于把对应位置的显存数据置 0,视觉上就 "清除" 了原有字符。

cpp
#include "stm32f10x.h" // Device header
#include "Delay.h"// 延时函数头文件
#include "OLED.h"
int main(void)
{
// 1. 初始显示所有内容
OLED_ShowChar(1, 1, 'A'); // 第1行第1列显示'A'
OLED_ShowString(1, 3, "Hello World!"); // 第1行第3列显示"Hello World!"
OLED_ShowNum(2, 1, 12345, 5); // 第2行第1列显示数字12345(5位)
OLED_ShowSignedNum(2, 7, 66, 2); // 第2行第7列显示有符号数66(2位)
OLED_ShowHexNum(3, 1, 0xAA55, 4); // 第3行第1列显示十六进制0xAA55(4位)
OLED_ShowBinNum(4, 1, 0xAA55, 16); // 第4行第1列显示二进制0xAA55(16位)
Delay_ms(2000); // 延时2秒,观察初始显示
// 2. 清除第1行的"Hello World!"(用空格覆盖)
// "Hello World!" 共12个字符(位置:第1行第3列 ~ 第1行第14列)
OLED_ShowString(1, 3, " "); // 显示12个空格,覆盖原有字符串
Delay_ms(2000); // 延时2秒,观察清除后的效果
// 3. 清除第2行的"+66"(用空格覆盖)
// "66" 共2个字符(位置:第2行第7列 ~ 第2行第9列)
OLED_ShowString(2, 7, " "); // 显示3个空格,覆盖原有数字
while(1)
{
}
}
OLED局部消除字符