文章目录[隐藏]
目录
一、SPI协议
1、SPI 协议简介
SPI 协议是由摩托罗拉公司提出的通讯协议 (Serial Peripheral Interface),即串行外围设备接口,是 一种高速全双工的通信总线。它被广泛地使用在 ADC、LCD 等设备与 MCU 间,要求通讯速率 较高的场合。 学习本章时,可与 I2C 章节对比阅读,体会两种通讯总线的差异以及 EEPROM 存储器与 FLASH 存储器的区别。下面我们分别对 SPI 协议的物理层及协议层进行讲解。
2、SPI 物理层
SPI 通讯设备之间的常用连接方式如下图所示
SPI 通讯使用 3 条总线及片选线,3 条总线分别为 SCK、MOSI、MISO,片选线为 SS
(1) SS*(* Slave Select):从设备选择信号线,常称为片选信号线,也称为 NSS、CS,以下用 NSS 表示。
(2)SCK (Serial Clock):时钟信号线,用于通讯数据同步。
(3) MOSI (Master Output,Slave Input):主设备输出/从设备输入引脚。
(3) MOSI (Master Output,Slave Input):主设备输出/从设备输入引脚。
2、协议层
与 I2C 的类似,SPI 协议定义了通讯的起始和停止信号、数据有效性、时钟同步等环节。
2.1、 SPI 基本通讯过程
SPI 通讯的通讯时序,如下图所示
3、STM32 的 SPI 外设简介
STM32 的 SPI 外设可用作通讯的主机及从机,支持最高的 SCK 时钟频率为 fpclk/2 (STM32F103 型 号的芯片默认 f:sub:pclk1 为 72MHz,fpclk2 为 36MHz),完全支持 SPI 协议的 4 种模式,数据帧长 度可设置为 8 位或 16 位,可设置数据 MSB 先行或 LSB 先行。它还支持双线全双工 (前面小节说 明的都是这种模式)、双线单向以及单线模式。其中双线单向模式可以同时使用 MOSI 及 MISO 数 据线向一个方向传输数据,可以加快一倍的传输速度。而单线模式则可以减少硬件接线,当然这 样速率会受到影响。我们只讲解双线全双工模式。
通讯引脚
SPI 的所有硬件架构都从图 24‑5 中左侧 MOSI、MISO、SCK 及 NSS 线展开的。STM32 芯片有多 个 SPI 外设,它们的 SPI 通讯信号引出到不同的 GPIO 引脚上,使用时必须配置到这些指定的引 脚,见表 24‑2。关于 GPIO 引脚的复用功能,可查阅《STM32F4xx 规格书》,以它为准。
时钟控制逻辑
SCK 线的时钟信号,由波特率发生器根据“控制寄存器 CR1”中的 BR[0:2] 位控制,该位是对 fpclk 时钟的分频因子,对 fpclk 的分频结果就是 SCK 引脚的输出时钟频率,
数据控制逻辑
SPI 的 MOSI 及 MISO 都连接到数据移位寄存器上,数据移位寄存器的数据来源及目标接收、发 送缓冲区以及 MISO、MOSI 线。当向外发送数据的时候,数据移位寄存器以“发送缓冲区”为 数据源,把数据一位一位地通过数据线发送出去;当从外部接收数据的时候,数据移位寄存器把 数据线采样到的数据一位一位地存储到“接收缓冲区”中。通过写 SPI 的“数据寄存器 DR”把 数据填充到发送 F 缓冲区中,通讯读“数据寄存器 DR”,可以获取接收缓冲区中的内容。其中数 据帧长度可以通过“控制寄存器 CR1”的“DFF 位”配置成 8 位及 16 位模式;配置“LSBFIRST 位”可选择 MSB 先行还是 LSB 先行。
整体控制逻辑
整体控制逻辑负责协调整个 SPI 外设,控制逻辑的工作模式根据我们配置的“控制寄存器 (CR1/CR2)”的参数而改变,基本的控制参数包括前面提到的 SPI 模式、波特率、LSB 先行、主 从模式、单双向模式等等。在外设工作时,控制逻辑会根据外设的工作状态修改“状态寄存器 (SR)”,我们只要读取状态寄存器相关的寄存器位,就可以了解 SPI 的工作状态了。除此之外,控 制逻辑还根据要求,负责控制产生 SPI 中断信号、DMA 请求及控制 NSS 信号线。 实际应用中,我们一般不使用 STM32 SPI 外设的标准 NSS 信号线,而是更简单地使用普通的 GPIO,软件控制它的电平输出,从而产生通讯起始和停止信号。
二、使用OLED显示屏显示数据
实验工具和材料
软件:keil
硬件:PC机,STM32开发板,0.96寸OLED显示屏,AHT20 芯片,下载器
运行厂家给出的Demo程序
程序下载链接:
选择与自己平台相同的实例文件。
然后对其中部分代码进行修改,来完成以下任务。
1、显示自己的名字和学号
1.1获取汉字字模
因为OLED 上可以直接显示数字和英文,我们想要在 OLED 上显示汉字,需要对其进行编码成阵获取汉字字模。
取模得软件需要自行下载。
打开软件后我们输入想要的汉字生成字模。注意(将选项中的自定义格式改为c51格式)
因为OLED是竖屏显示所以需要将输入的文字进行左旋90度、垂直翻转。
1.2代码实现
用keil打开厂家的代码进行修改,打开代码后打开user下的gui.c再打开gui.c下面的oledfont.h文件,
将 cfont16[] 数组
内的内容修改成自己的中文文字点阵。
接下来再去修改显示函数,将 test.c
里 void TEST_MainPage(void)
函数中的不跟删掉,添加自己的执行语句。
修改之后我们再修改main.c函数,将main.c中的 while函数里除l了 TEST_MainPage()
以外的语句全部删掉。
修改完成后,将生成的hex文件烧录进芯片,连接OLED芯片进行显示。
OLED与stm32连接
OLED stm32
VCC 3.3V
GND GND
D0 PB13
D1 PB15
DC PB10
CS PB11
RES PB12
结果显示
2、 OLED 显示温湿度
2.1添加汉字字模
首先还是进行字模获取,之后在代码中修改,具体的流程参考上一步。
2.2代码实现
我们需要先添加4个文件,bsp_i2c.h
、bsp_i2c.c
、sys.h
(更改名称为 AHT20_sys.h,不然会重名);sys.c
(更改名称为 AHT20_sys.c,不然会重名);
然后再修改bsp_i2c.c文件如下
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);
}
将整个程序进行编译生成hex文件,将其烧录进芯片进行显示。
最终结果显示
3、OLED 滑动显示汉字
1、添加字模
获取我们想要的汉字,获取字模,同第一步一样将其换进代码中,这里就不再多加赘述。
2.代码实现
将test.c
里 void TEST_MainPage(void)
函数修改如下
void TEST_MainPage(void)
{
GUI_ShowCHinese(10,16,16,"天灰灰会不会让我忘了你是谁",1);
//GUI_ShowCHinese(40,16,16,"王石石石",1);
//GUI_ShowString(16,32,"631907030523",16,1);
delay_ms(1500);
delay_ms(1500);
}
再修改mian.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);
}
然后将整个程序进行编译,再将程序烧录进芯片进行显示
结果显示
三、总结
在本次实验当中,我了解学习了SPI协议,具体的显示实现需要对厂家提供的代码进行修改,在当中参考了不少大佬的文章进行完成,本人也是初学者对于SPI协议并不精通,请各位大佬多多指正。
四、参考资料
https://blog.csdn.net/qq_45237293/article/details/111712565
https://blog.csdn.net/qq_43279579/article/details/111414037
https://blog.csdn.net/m0_58892312/article/details/121410862?spm=1001.2014.3001.5501
版权声明:本文为CSDN博主「Tilldark」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_57841179/article/details/121549660
暂无评论