实验目的
理解OLED屏显和汉字点阵编码原理,使用STM32F103的SPI或IIC接口实现以下功能:
- 显示自己的学号和姓名;
- 显示AHT20的温度和湿度;
- 上下或左右的滑动显示长字符。
实验材料
软件
- KEIL5
- 字模软件
- FlyMcu
硬件
- STM32F103C8T6最小开发板
- 面包板
- CH340模块
- 杜邦线若干
- AHT20温湿度传感器
- OLED显示屏
实验原理
跟SPI有关的代码,本实验中已经被厂家写好,只是实现实验现象的话不需要过深地了解SPI。但是要理解它的源码,就必须了解SPI。
什么是SPI
SPI(Serial Peripheral Interface)就是串行外围设备接口,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚。SPI 是一个环形总线结构,由 ss(cs)、sck、sdi、sdo 构成,时序主要是在 sck 的控制下,两个双向移位寄存器进行数据交换。
sdi与sdo是收发数据的通道,ss是片选线。主机有多个ss口,要跟某个设备通信时,将对应的ss口输出低电平即可。
上升沿发送、下降沿接收、高位先发送。
上升沿到来的时候,sdo 上的电平将被发送到从设备的寄存器中。
下降沿到来的时候,sdi 上的电平将被接收到主设备的寄存器中。
更多内容请参考《【野火®】零死角玩转STM32—F103指南者》
项目制作
模板标准库项目制作
制作标准库项目过程较为复杂,野火的资料库提供了项目模板。我也写好了一个模板在这个链接里面,可以下载好后根据文本文件里面的提示进行构建。
导入AHT20模块与OLED模块
对于AHT20的使用,笔者的这篇文章里面已经讲解过,这里不再赘述。
对于OLED模块,可以参考这个网址,里面给出了相关资料以及实例代码。给出的各个示例代码中并没有C8T6的,但是经过测试,资料包中RCT6的示例代码也可以在C8T6中运行。我们使用RCT6的模块。
下载好程序后,将gui.c,oled.c,spi.c,delay.c,sys.c和他们的头文件复制到USER文件组下,再将它们添加进项目。
实例代码中的test.c文件与main.c文件介绍了如何使用OLED屏显示数据。在它的main函数主循环之前是一些配置代码,我们原封不动地搬到自己的主循环前:
test.c是厂家打印数据的一些示例函数,我们可以当作参考。
模块导入完毕后,进行下一步。
修改主函数,显示温湿度数据
前面已经导入了AHT20模块,我们按照前文提到的博客中所说的方法,将AHT20官方的读取代码写到主函数中。
在之前的博客中,我们使用的是串口发送温湿度数据到串口助手,现在我们是使用OLED屏显示。
因此在读取到湿度c1与温度t1之后,我们使用OLED官方的库函数:
void OLED_Clear(unsigned dat)//清屏,参数写0
//输出中文,需要准备好字模,前面两个参数是显示位置,第三个是大小,第四个是字符串,最后一个写1
void GUI_ShowCHinese(u8 x,u8 y,u8 hsize,u8 *str,u8 mode)
void GUI_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size,u8 mode)//输出字符
void GUI_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 Size,u8 mode)//输出数字
我们在读取到湿度c1与温度t1之后添加下面的代码:
uint8_t c2 = c1%10;
c1 /= 10;
uint8_t t2 = t1%10;
t1 /= 10;//拆分温湿度数据的整数与小数
//显示数据
OLED_Clear(0);
GUI_ShowCHinese(0,16,16,"温度",1);
GUI_ShowChar(32,16,':',16,1);
GUI_ShowNum(48,16,t1,2,16,1);
GUI_ShowChar(64,16,'.',16,1);
GUI_ShowNum(80,16,t2,1,16,1);
GUI_ShowCHinese(0,32,16,"湿度",1);
GUI_ShowChar(32,32,':',16,1);
GUI_ShowNum(48,32,c1,2,16,1);
GUI_ShowChar(64,32,'.',16,1);
GUI_ShowNum(80,32,c2,1,16,1);
最后一步,添加汉字字模。
汉字不能直接输出在OLED显示屏上,要先使用字模软件获取字模,再把字模添加到oledfont.h的字模数组中。
我使用到的字模如下:
"温",0x00,0x00,0x23,0xF8,0x12,0x08,0x12,0x08,0x83,0xF8,0x42,0x08,0x42,0x08,0x13,0xF8,
0x10,0x00,0x27,0xFC,0xE4,0xA4,0x24,0xA4,0x24,0xA4,0x24,0xA4,0x2F,0xFE,0x00,0x00,/*"温",0*/
"湿",0x00,0x00,0x27,0xF8,0x14,0x08,0x14,0x08,0x87,0xF8,0x44,0x08,0x44,0x08,0x17,0xF8,
0x11,0x20,0x21,0x20,0xE9,0x24,0x25,0x28,0x23,0x30,0x21,0x20,0x2F,0xFE,0x00,0x00,/*"湿",0*/
"度",0x01,0x00,0x00,0x80,0x3F,0xFE,0x22,0x20,0x22,0x20,0x3F,0xFC,0x22,0x20,0x22,0x20,
0x23,0xE0,0x20,0x00,0x2F,0xF0,0x24,0x10,0x42,0x20,0x41,0xC0,0x86,0x30,0x38,0x0E,/*"度",0*/
这样,OLED显示温湿度的代码就写好了。
修改主函数,显示滚动字符串
这里仅使用到OLED模块,将要现实的字模添加到字模数组中。
"古",0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xFF,0xFE,0x01,0x00,0x01,0x00,0x01,0x00,0x1F,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10,/*"古",0*/
"今",0x01,0x00,0x01,0x00,0x02,0x80,0x04,0x40,0x08,0x20,0x12,0x10,0x21,0x08,0xC1,0x06,0x00,0x00,0x1F,0xF0,0x00,0x10,0x00,0x20,0x00,0x20,0x00,0x40,0x00,0x80,0x01,0x00,/*"今",1*/
"多",0x02,0x00,0x02,0x00,0x07,0xF0,0x08,0x20,0x38,0x40,0x04,0x80,0x03,0x40,0x0C,0x80,0x71,0xF8,0x02,0x08,0x0C,0x10,0x32,0x20,0x01,0x40,0x01,0x80,0x0E,0x00,0x70,0x00,/*"多",2*/
"少",0x01,0x00,0x01,0x00,0x01,0x00,0x09,0x20,0x09,0x10,0x11,0x08,0x11,0x04,0x21,0x14,0x41,0x10,0x01,0x20,0x00,0x40,0x00,0x80,0x01,0x00,0x02,0x00,0x0C,0x00,0x70,0x00,/*"少",3*/
"事",0x01,0x00,0x01,0x00,0xFF,0xFE,0x01,0x00,0x3F,0xF8,0x21,0x08,0x3F,0xF8,0x01,0x00,0x3F,0xF8,0x01,0x08,0xFF,0xFE,0x01,0x08,0x3F,0xF8,0x01,0x00,0x05,0x00,0x02,0x00,/*"事",4*/
"都",0x08,0x00,0x08,0xBE,0x7E,0xA2,0x09,0x24,0x0A,0x24,0xFF,0xE8,0x08,0x24,0x10,0x24,0x3F,0x22,0x61,0x22,0xA1,0x22,0x3F,0x34,0x21,0x28,0x21,0x20,0x3F,0x20,0x21,0x20,/*"都",5*/
"付",0x08,0x10,0x08,0x10,0x08,0x10,0x10,0x10,0x17,0xFE,0x30,0x10,0x30,0x10,0x50,0x10,0x91,0x10,0x10,0x90,0x10,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x50,0x10,0x20,/*"付",6*/
"笑",0x10,0x40,0x10,0x40,0x3F,0x7E,0x28,0x90,0x45,0x08,0x80,0xF0,0x3F,0x00,0x01,0x00,0x01,0x00,0xFF,0xFE,0x01,0x00,0x02,0x80,0x04,0x40,0x08,0x20,0x30,0x18,0xC0,0x06,/*"笑",7*/
"谈",0x00,0x40,0x22,0x44,0x12,0x44,0x14,0x48,0x00,0xA0,0x01,0x10,0xF6,0x08,0x10,0x44,0x10,0x40,0x12,0x48,0x12,0x48,0x14,0x50,0x18,0xA0,0x11,0x10,0x02,0x08,0x0C,0x06,/*"谈",8*/
"中",0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x3F,0xF8,0x21,0x08,0x21,0x08,0x21,0x08,0x21,0x08,0x21,0x08,0x3F,0xF8,0x21,0x08,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,/*"中",9*/
",",0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x10,0x00,0x20,0x00,0x00,0x00/*",",0*/
然后修改主函数,为了实现循环,要先发送一些指令:
int main()
{
OLED_WR_Byte(0x2E,OLED_CMD); //关闭滚动
OLED_WR_Byte(0x26,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); //虚拟字节
GUI_ShowCHinese(0,20,16,"古今多少事,都付笑谈中",1);
delay_ms(1500);
delay_ms(1500);
OLED_WR_Byte(0x2F,OLED_CMD); //开启滚动
while(1){}
}
代码完成。
器件连接
AHT20的连接,可以看我之前的博客。
实验现象
连接好硬件,并烧录程序后,OLED屏显示出各种数据。
显示温湿度数据:
显示滚动字符串:
总结
本实验基于stm32标准库模板,导入AHT20模块与OLED模块,实现了对温湿度数据与滚动字符串的显示。
参考资料
- 《零死角玩转STM32——F103指南者》
- 《AHT20产品手册》
- http://www.lcdwiki.com/zh/0.96inch_SPI_OLED_Module