基于SPI协议下的OLED显示

一、SPI简介

SPI 是英语 Serial Peripheral interface 的缩写,顾名思义就是串行外围设备接口。是 Motorola 首先在其 MC68HCXX 系列处理器上定义的。SPI 接口主要应用在 EEPROM,FLASH,实时时钟,AD 转换器,还有数字信号处理器和数字信号解码器之间。SPI,是一种高速的,全双工, 同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为 PCB 的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议。

  • 看 SPI 的内部简明图(图 24.1.1)
    在这里插入图片描述
    SPI接口一般使用4条线通信:
  • MISO 主设备数据输入,从设备数据输出。
  • MOSI 主设备数据输出,从设备数据输入。
  • SCLK 时钟信号,由主设备产生。
  • CS 从设备片选信号,由主设备控制。

SPI 总线有四种工作方式 ,SPI 模块为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置,时钟极性(CPOL)对传输协议没有重大的影响,不同时钟相位下的总线数据传输时序如图所示:
在这里插入图片描述

二、OLED显示

1、任务要求

  1. 显示自己的学号和姓名;
  2. 显示AHT20的温度和湿度;
  3. 上下或左右的滑动显示长字符;

2、实验器材

① STM32最小核心板(STM32F103C8T6)
②0.96寸7针基于SPI的OLED屏幕(SSD1306驱动)
③奥松AHT21B温湿度传感器
④USB转TTL(ch340芯片)
⑤ IDE:keil5

3、实验过程

(1)显示自己的学号和姓名

  • 首先我们下载店铺所给的OLED显示例程,下载地址:http://www.lcdwiki.com/zh/0.96inch_SPI_OLED_Module
    在这里插入图片描述
  • 打开硬件4线SPI的工程文件,按照图中的提示将OLED与与stm32相连
    在这里插入图片描述
  • 然后我们将例程烧录进单片机就能看到OLED屏幕正常显示
  • 接下来修改成我们所想要显示的文字,要想显示特定的汉字字,我们首先需要进行汉字取模
    1、打开下载的资料包里的汉字取模软件PCtoLCD2002,模式选为字符模式,进行相关设置
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 然后在主界面输入想要显示的文字,点击生成字模(注意不能有空格
  • 接下来打开例程,进入到oledfont.h文件,找到16×16的字模库,将生成的字模粘贴进去,并改成图中格式
    在这里插入图片描述
  • 然后我们直接修改例程里显示汉字的函数TEST_Chinese
void TEST_Chinese(void)
{	u8 i;
	for(i=0;i<5;i++)
	{
	GUI_ShowString(35,5,"631807030212",8,1);
	GUI_ShowCHinese(20,15,16,"通信二班",1);	
	GUI_ShowCHinese(32,41,16,"XXX(改成自己的名字)",1);	
    delay_ms(500);
	}
	OLED_Clear(0);
}

代码解析:

GUI_ShowCHinese(X坐标,Y坐标,字体大小,显示内容,显示样式)
GUI_ShowString(X坐标,Y坐标,显示内容,字体大小,显示样式) OLED_Clear(0):清屏

PS:由于例程里已经有了ASCII字符集,我们不需要再次对字母或数字进行取模,直接用即可。
这里我加了一个循环延时,主要是为了让这些信息显示得更久一些。

  • 在main函数里调用TEST_Chinese即可显示
    在这里插入图片描述

(2) 显示AHT20的温度和湿度

void AHT20(void)
{
	u32 CT_data[2];
    volatile int  c1=0,t1=0;    
	srand(123456);
	delay_ms(40);
	AHT20_Read_CTdata(CT_data);       //不经过CRC校验,直接读取AHT20的温度和湿度数据    推荐每隔大于1S读一次
	c1 = CT_data[0]*100*10/1024/1024;    //湿度
    t1 = CT_data[1]*200*10/1024/1024-500; //温度
	
	GUI_DrawLine(0, 10, WIDTH-1, 10,1);
	GUI_DrawLine(WIDTH/2-1,11,WIDTH/2-1,HEIGHT-1,1);
	GUI_DrawLine(WIDTH/2-1,10+(HEIGHT-10)/2-1,WIDTH-1,10+(HEIGHT-10)/2-1,1);
	
	GUI_ShowString(0,1,"2020-12-26",8,1);
	GUI_ShowString(70,1,"Staurday",8,1);
	GUI_ShowString(14,HEIGHT-1-10,"Cloudy",8,1);
	GUI_ShowString(WIDTH/2+1,13,"TEMP",8,1);
	GUI_DrawCircle(WIDTH-20, 25, 1,2);
	GUI_ShowString(WIDTH-15,20,"C",16,1);
	GUI_ShowNum(WIDTH/2+8,20,t1/10,2,16,1);
	GUI_ShowString(WIDTH-41,26,".",8,1);
	GUI_ShowNum(WIDTH-35,20,t1%10,1,16,1);
	
	GUI_ShowString(WIDTH/2+1,39,"HUM",8,1);
	GUI_ShowNum(WIDTH/2+8,46,c1/10,2,16,1);
	GUI_ShowString(WIDTH-41,52,".",8,1);
	GUI_ShowNum(WIDTH-35,46,c1%10,1,16,1);
	GUI_ShowString(WIDTH-21,46,"%",16,1);
	GUI_DrawBMP(6,16,51,32, BMP5, 1);
	delay_ms(1000);
}

代码解析:

GUI_DrawLine(起点X坐标,起点Y坐标,终点X坐标,终点Y坐标,显示颜色),作用是画一条直线
GUI_DrawCircle(圆心X坐标,圆心Y坐标,颜色,半径),作用是画一个圆
GUI_ShowNum(X坐标,Y坐标,要显示的数字,长度,大小,显示模式) ,作用是显示数字(变量)

  • 在main函数里调用TEST_Menu2即可显示AHT20读取的温湿度
    在这里插入图片描述

(3)上下或左右的滑动显示长字符(SSD1306驱动)

  • 在test.c里新建一个函数Movestring(),在test.h里声明该函数
void Movestring(void)
{
	OLED_WR_Byte(0x2e,OLED_CMD);//关滚动
    OLED_WR_Byte(0x2A,OLED_CMD);//29向右,2a向左
    OLED_WR_Byte(0x00,OLED_CMD);//A:空字节
    OLED_WR_Byte(0x00,OLED_CMD);//B:水平起始页
    OLED_WR_Byte(0x00,OLED_CMD);//C:水平滚动速度
    OLED_WR_Byte(0x00,OLED_CMD);//D:水平结束页
    OLED_WR_Byte(0x01,OLED_CMD);//E:每次垂直滚动位移
	OLED_WR_Byte(0x2f,OLED_CMD);//开滚动
}
  • 在main函数里调用该函数
    注意:该函数不能放在While循环里,在开始滚动前先显示要滚动的内容

在这里插入图片描述

  • main.c
#include "delay.h"
#include "sys.h"
#include "oled.h"
#include "gui.h"
#include "test.h"
#include "AHT20tem.h"

int main(void)
{			  
	u8 i;
	delay_init();	    	       //延时函数初始化	  
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    AHT20tem_init();    
	OLED_Init();			         //初始化OLED  
	OLED_Clear(0);             //清屏(全黑)   
	GUI_ShowCHinese(10,20,16,"欢迎来到",1);
    GUI_ShowString(74,20,"XX",16,1);		
	GUI_ShowCHinese(90,20,16,"大学",1);	
	Movestring();              //开启滚动
	for(i=0;i<18;i++)
	{
		delay_ms(500);
	}
	OLED_WR_Byte(0x2e,OLED_CMD);  //关闭滚动
	OLED_Clear(0); 
	while(1) 
	{	
		TEST_Chinese();          //学号、姓名班级显示
		OLED_Clear(0); 
	for(i=0;i<8;i++)
	{
		AHT20();            //AHT20温湿度显示
		delay_ms(500);
	}
		OLED_Clear(0); 
 
	}
}

三、总结

虽然是基于SPI协议的OLED显示,但实际上SPI的初始化以及相关函数的调用别人已经写好了,我们在修改函数的过程中并没有直接触及到SPI相关函数,这其实是违背了做这个实验的初衷。对于SPI的代码解析在下载的资源里有,想要真正的了解SPI通信协议,还是需要花费时间去看一下。

四、参考资料

1、0.96寸OLED屏驱动ssd1306 一些不常用的命令用法和效果
2、STM32F103最小系统板开发指南-库函数版本_V1.1
3、0.96寸SPI_OLED模块配套资料包

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值