文章内容
:
理解 OLED 屏显和汉字点阵编码原理,使用 STM32F103 的 SPI 或 IIC 接口实现以下功能:
- 显示自己的学号和姓名;
- 显示 AHT20 的温度和湿度;
- 上下或左右的滑动显示长字符,或者一段歌词或诗词(最好使用硬件刷屏模式)。
SPI 协议是由摩托罗拉公司提出的通讯协议,即串行外设接口(Serial Peripheral Interface),是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便。它被广泛地使用在 ADC、LCD 等设备与 MCU 间,要求通讯速率较高的场合。
SPI 和 I2C 的通信 2 种总线的异同点可以参看这篇博客:I2C和SPI总线对比。
SPI 协议层
这是一个主机的通讯时序。NSS、SCK、MOSI 信号都由主机控制产生,而 MISO 的信号由从机产生,主机通过该信号线读取从机的数据。MOSI 与 MISO 的信号只在 NSS 为低电平的时候才有效,在 SCK 的每个时钟周期 MOSI 和 MISO 传输一位数据。
更多的 SPI 协议内容可以查看资料:《零死角玩转STM32—F103指南者.pdf》。
硬件工具:
软件工具:
需要下载 0.96 寸 OLED 显示屏厂家给出的 Demo 程序。
程序下载链接:
0.96 寸 SPI_OLED 模块配套资料包。
0.96inch_SPI_OLED_Module_SSD1306_MSP096X_V1.0\1-Demo\Demo_STM32\0.96inch_OLED_Demo_STM32F103RCT6_Software_4-wire_SPI
”。添加字模
打开上面下载的工程文件“0.96inch_OLED_Demo_STM32F103RCT6_Software_4-wire_SPI\PROJECT\OLED.uvprojx
”,打开 gui.c
下的 oledfont.h
头文件,将 cfont16[] 数组
内的内容修改成自己的中文文字点阵即可。
这里面是我存入的一些需要的字模,代码设计的只会从cfont16[] 数组
内读取数据,所以需要将字模数据存取其中。
修改显示函数
将 test.c
里 void TEST_MainPage(void)
函数中的语句注释掉,添加自己的执行语句,如下:
//主界面显示测试
void TEST_MainPage(void)
{
//GUI_ShowString(28,0,"OLED TEST",16,1);
//GUI_ShowString(12,16,"0.96\" SSD1306",16,1);
//GUI_ShowString(40,32,"64X128",16,1);
//GUI_ShowString(4,48,"www.lcdwiki.com",16,1);
GUI_ShowCHinese(40,16,16,"刘同学",1);
GUI_ShowString(16,32,"631907030513",16,1);
delay_ms(1500);
delay_ms(1500);
}
函数说明:
① GUI_ShowString() 函数各参数分别对应:
X 坐标
、Y 坐标
、字符串
(ASCLL码中的)、bit
(表示字符显示格式,这里我用的 16 ,和汉字一样高)、显示样式
(1:白字黑底;0:黑字白底)。
② GUI_ShowChinese() 函数各参数分别对应:
X 坐标
、Y 坐标
、汉字点阵大小
(这里使用的是 16×16 的,参数应该是 16)、要显示的汉字
、显示样式
(1:白字黑底;0:黑字白底)。
gui.c
下的 oledfont.h
头文件里的 cfont16[] 数组
内的添加中文文字点阵即可。test.c
里 void TEST_MainPage(void)
函数中不用的语句注释掉,添加自己的想要显示的字符,如下:void TEST_MainPage(void)
{
//GUI_ShowString(28,0,"OLED TEST",16,1);
//GUI_ShowString(12,16,"0.96\" SSD1306",16,1);
//GUI_ShowString(40,32,"64X128",16,1);
//GUI_ShowString(4,48,"www.lcdwiki.com",16,1);
GUI_ShowCHinese(10,16,16,"欢迎阅读此文章",1);
//GUI_ShowCHinese(40,16,16,"刘同学",1);
//GUI_ShowString(16,32,"631907030513",16,1);
delay_ms(1500);
delay_ms(1500);
}
main.c
代码中的 while
函数注释掉,再添加如下代码://从左到右滑动( OLED 屏的滚屏命令)
OLED_WR_Byte(0x2E,OLED_CMD); //关闭滚动
OLED_WR_Byte(0x27,OLED_CMD); //水平向左或者右滚动 26/27
OLED_WR_Byte(0x00,OLED_CMD); //虚拟字节
OLED_WR_Byte(0x00,OLED_CMD); //起始页 0
OLED_WR_Byte(0x07,OLED_CMD); //滚动时间间隔
OLED_WR_Byte(0x07,OLED_CMD); //终止页 7
OLED_WR_Byte(0x00,OLED_CMD); //虚拟字节
OLED_WR_Byte(0xFF,OLED_CMD); //虚拟字节
TEST_MainPage();
OLED_WR_Byte(0x2F,OLED_CMD); //开启滚动
OLED 屏的滚屏命令:
本 OLED 屏的芯片类型是 SSD1306,其详细命令的介绍,可以参考下面链接去了解
https://wlink.blog.csdn.net/article/details/81329770
2.4.3.3 编译烧录
注意按照上面 2.3 部分的硬件连接说明将电路连接正确,并将编译的 hex 文件成功烧录到开发板上。
2.4.3.4 滑动显示效果
可以看到,文字内容已经在 OLED 上滑动显示。
gui.c
下的 oledfont.h
头文件里的 cfont16[] 数组
内的添加中文文字点阵即可。bsp_i2c.h
、bsp_i2c.c
、sys.h
(移植后更改了名称为 AHT20_sys.h,不然会重名)、sys.c
(移植后更改了名称为 AHT20_sys.c,不然会重名);bsp_i2c.c
文件中的串口发送改为 OLED 显示 void Show_OLED(void)
即可。void Show_OLED(void)
{
/*---
------
---*/
GUI_ShowCHinese(28,10,16,"当前温湿度",1);
GUI_ShowCHinese(20,32,16,"温度:",1);
GUI_ShowString(60,32,strTemp1,16,1);
GUI_ShowString(68,32,strTemp2,16,1);
GUI_ShowString(76,32,".",16,1);
GUI_ShowString(84,32,strTemp3,16,1);
GUI_ShowCHinese(92,32,16,"℃",1);
GUI_ShowCHinese(20,48,16,"湿度:",1);
GUI_ShowString(60,48,strHumi1,16,1);
GUI_ShowString(68,48,strHumi2,16,1);
GUI_ShowString(76,48,".",16,1);
GUI_ShowString(84,48,strHumi3,16,1);
GUI_ShowCHinese(92,48,16,"%",1);
}
main.c
代码中不用的函数注释掉,再修改代码,之后的结果如下:#include "bsp_i2c.h" //注意添加头文件
int main(void)
{
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
OLED_Init(); //初始化OLED
IIC_Init(); //初始化IIC
OLED_Clear(0); //清屏(全黑)
while(1)
{
read_AHT20_once(); //读取温度并显示
OLED_Clear(0); //清屏(全黑)
delay_ms(1500);
}
要注意添加头文件,调用温湿度读取并显示函数。
这里为大家提供一下我修改完的温湿度 OLED 显示工程文件:
链接:https://pan.baidu.com/s/1Dbg6Z-TkixAvsvip0SA9NQ
提取码:luha
2.4.4.3 编译烧录
注意按照上面 2.3 部分的硬件连接说明将电路连接正确,并将编译的 hex 文件成功烧录到开发板上。
2.4.4.4 温湿度显示效果
可以看到,成功采集了温湿度数据并显示了温湿度信息,当用手捂住 AHT20 芯片,温湿度都升高了。
文篇文章对 SPI 协议进行了简单介绍,并通过使用 SPI 通信方式对汉字和温湿度进行了显示,和上篇博客(利用 I2C 协议通信串口显示温湿度)比较,可见利用 SPI 总线传输速度明显更快。上面实现任务的代码,只是对已有代码的修改而已,没有更深入的理解 SPI 协议,如果需要了解详细的 SPI 协议应用,还需要继续学习。我也是 SPI 初学者,文章如有疑问,敬请读者指正。