文章目录
一. SPI协议
1. 简介
SPI 协议是由摩托罗拉公司提出的通讯协议(Serial Peripheral Interface),即串行外围设 备接口,是一种高速全双工的通信总线。它被广泛地使用在 ADC、LCD 等设备与 MCU 间, 要求通讯速率较高的场合。
SPI是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,以主从方式工作,这种模式通常有一个主设备和一个或多个从设备,需要至少4根线,事实上3根也可以(单向传输时)。也是所有基于SPI的设备共有的,它们是MISO(数据输入),MOSI(数据输出),SCLK(时钟),CS(片选)。
2. 连接方式
- SS( Slave Select):从设备选择信号线,常称为片选信号线。
- SCK (Serial Clock):时钟信号线,用于通讯数据同步。
- MOSI (Master Output, Slave Input):主设备输出/从设备输入引脚。
- MISO(Master Input,,Slave Output):主设备输入/从设备输出引脚。
3. 通讯过程
这是一个主机的通讯时序。NSS、SCK、MOSI 信号都由主机控制产生,而 MISO 的信 号由从机产生,主机通过该信号线读取从机的数据。MOSI 与 MISO 的信号只在 NSS 为低 电平的时候才有效,在 SCK 的每个时钟周期 MOSI 和 MISO 传输一位数据。
标号 1 处,NSS 信号线由高变低,是 SPI 通讯的起始信号。NSS 是每个从机各自独占的信号线,当从机在自己的 NSS 线检测到起始信号后,就知道自己被主机选 中了,开始准备与主机通讯。
标号 6 处,NSS 信号由低变高,是 SPI 通讯的停止信号,表示本次通讯结束,从机的选中状态被取消。
标号 2 3 4 5 处,MOSI 及 MISO 的数据在 SCK 的上升沿期间变化输出,在 SCK 的下降沿时被采样。即在 SCK 的下降沿时刻,MOSI 及 MISO 的数据有效,高电平时 表示数据“1”,为低电平时表示数据“0”。在其它时刻,数据无效,MOSI及 MISO 为下 一次表示数据做准备。
4. 工作模式
为方便说明,在此引入时钟极性 CPOL 和 时钟相位 CPHA 的概念。
- 时钟极性 CPOL 是指 SPI 通讯设备处于空闲状态时,SCK 信号线的电平信号(即 SPI 通讯开始前、 NSS 线为高电平时 SCK 的状态)。CPOL=0 时, SCK 在空闲状态时为低电平,CPOL=1 时,则相反。
- 时钟相位 CPHA 是指数据的采样的时刻,当 CPHA=0 时,MOSI 或 MISO 数据线上的信号将会在 SCK 时钟线的“奇数边沿”被采样。当 CPHA=1 时,数据线在 SCK 的“偶数边沿”采样。
根据 CPOL 及 CPHA 的不同状态,SPI 分成了四种模式,见下图,主机与从机需要工作在相同的模式下才可以正常通讯,实际中采用较多的是“模式 0”与“模式 3”。
5. 优缺点
- SPI 优点
支持全双工通信
通信简单
数据传输速率块
- SPI 缺点
没有指定的流控制,没有应答机制确认是否接收到数据,所以跟IIC总线协议比较在数据
可靠性上有一定的缺陷。
二. OLED
OLED显示屏介绍:0.96inch SPI OLED Module - LCD wiki
你可以在该链接中下载相关手册及配套程序
我使用的是 0.96寸 7针OLED显示屏,此次实验都是在OLED配套程序上进行添加修改。
三. OLED显示
7针OLED显示屏接线。我使用的是 stmf103c8t6芯片 ,也是按这个接线。
其它芯片查看文档:0.96inch_OLED_SPI_Module_MSP096X_User_Manual_CN.pdf (lcdwiki.com)
也可以查看自己下载的配套程序的主文件 main.c 中 有接线方法
1. 显示姓名学号
调用函数即可。
//显示姓名学号
void showNameID()
{
GUI_ShowString(28,10,"631900022222",8,1);
GUI_ShowCHinese(28,30,16,"缔宇",1); //这里使用 16*16 的矩阵
}
由于我们要显示汉字,所以先要进行汉字取模。
软件也是可以在前面OLED显示屏链接中下载 。
汉字取模软件 PCtoLCD2002 :
http://www.lcdwiki.com/res/software/PCtoLCD2002.zip
打开软件,点击 选项
将生成的字模放入配套程序中的 oledfont.h
文件相关函数中
我汉字取得是 16*16 ,所以放入图中的函数
最后效果
2. 显示AHT20的温度和湿度
这里更改配套相关示例函数。
这里通过 I2C协议读取 AHT20 的温度湿度。
AHT20以及I2C协议的代码,OLED配套代码是没有的,需要自己编写或引入。
这一块的代码可以参考:基于I2C通信协议的温湿度采集_不#曾&轻听的博客-CSDN博客
文末我会给出完整代码。
//显示AHT20的温度湿度
void showAHT20()
{
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,"2021-11-23",8,1);
GUI_ShowString(74,1,"Tuesday",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);
}
最后效果:
有一点黑屏效果是使用摄像头录制导致的,实际是看不出的。
3. 上下或左右的滑动显示长字符
如果将你在 main函数的while循环中调用此函数,你需要添加代码中的延时。在while循环外调用,可以去掉延时。
要显示汉字,所以需要进行汉字取模,前面显示姓名学号部分已经有示例了,就不再示范。
//水平向左滚动显示数据
void showScroll()
{
GUI_ShowCHinese(10,30,16,"欢迎来到信息科学与工程学院",1);
OLED_horizontal_scroll(); //这个需要根据OLED内置芯片手册自己写
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
}
滚动函数:
可以查看我的另一篇博客进行编写:OLED显示屏滚动函数编写_diyu-CSDN博客
也可以自己根据手册写:SSD1780 (lcdwiki.com)
//OLED水平滚动
void OLED_horizontal_scroll()
{
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); //滚动间隔 2帧
OLED_WR_Byte(0x07,OLED_CMD); //终止页 7
OLED_WR_Byte(0x00,OLED_CMD); //虚拟字节
OLED_WR_Byte(0xFF,OLED_CMD); //虚拟字节
OLED_WR_Byte(0x2F,OLED_CMD); //开启滚动
}
最后效果:
有一点黑屏效果是使用摄像头录制导致的,实际是看不出的。
四.逻辑分析仪分析协议波形
打开逻辑分析仪。选择协议
- I2C协议波形
- SPI协议波形
- 串口波形
五. 总结
总体而言,还是不难的,基本就是查看手册以及调用现有函数。
六. 全部代码
资源免费下载: 0.96_OLED_SPI.zip-嵌入式文档类资源-CSDN文库
不过我后来才发现,只有会员才可以下载
因此,我补上gitee链接
https://gitee.com/diyugreat/stm32.git
下载后 文件夹名为 0.96_OLED_SPI 的则为此次工程代码。
参考资料:
-
《零死角玩转STM32—F103指南者.pdf》