IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 基于 SPI 协议用 0.96 寸 OLED 显示汉字及温湿度数据 -> 正文阅读

[嵌入式]基于 SPI 协议用 0.96 寸 OLED 显示汉字及温湿度数据

目录

一、SPI协议

1、简介

2、SPI物理层

3、协议层

4、STM32的SPI特性及架构

二、oled显示

1、文字取模

?2、代码改写

3、接线方式

?4、将生成的hex文件烧录后运行结果

三、OLED 滑动显示字符

1、添加字模

2、修改显示函数

3、修改主函数

4、连线方式

5、效果展示?

四、OLED 显示温湿度数据

1、添加字模

2、修改代码

3、运行结果?

五、总结

六、参考文献


一、SPI协议

1、简介

SPI协议是由摩托罗拉公司提出的通讯协议(SerialPeripheralInterface),即串行外围设备接口,是 一种高速全双工的通信总线。它被广泛地使用在 ADC、LCD 等设备与 MCU 间,要求通讯速率 较高的场合。?

2、SPI物理层

?SPI通讯使用3条总线及片选线,3条总线分别为SCK、MOSI、MISO,片选线为SS,它们的作 用介绍如下:

(1) SS*(*SlaveSelect):从设备选择信号线,常称为片选信号线,也称为NSS、CS,以下用NSS 表示。当有多个 SPI 从设备与 SPI 主机相连时,设备的其它信号线 SCK、MOSI 及 MISO 同时并联到相同的SPI总线上,即无论有多少个从设备,都共同只使用这3条总线;而每 个从设备都有独立的这一条NSS信号线,本信号线独占主机的一个引脚,即有多少个从设 备,就有多少条片选信号线。I2C协议中通过设备地址来寻址、选中总线上的某个设备并与?其进行通讯;而SPI协议中没有设备地址,它使用NSS信号线来寻址,当主机要选择从设 备时,把该从设备的NSS信号线设置为低电平,该从设备即被选中,即片选有效,接着主 机开始与被选中的从设备进行SPI通讯。所以SPI通讯以NSS线置低电平为开始信号,以 NSS线被拉高作为结束信号。

(2) SCK(SerialClock):时钟信号线,用于通讯数据同步。它由通讯主机产生,决定了通讯的速 率,不同的设备支持的最高时钟频率不一样,如STM32的SPI时钟频率最大为fpclk/2,两 个设备之间通讯时,通讯速率受限于低速设备。

(3) MOSI(MasterOutput,SlaveInput):主设备输出/从设备输入引脚。主机的数据从这条信号线 输出,从机由这条信号线读入主机发送的数据,即这条线上数据的方向为主机到从机。

(4) MISO(MasterInput,,SlaveOutput):主设备输入/从设备输出引脚。主机从这条信线读入数据, 从机的数据由这条信号线输出到主机,即在这条线上数据的方向为从机到主机。

3、协议层

与I2C的类似,SPI协议定义了通讯的起始和停止信号、数据有效性、时钟同步等环节。

这是一个主机的通讯时序。NSS、SCK、MOSI 信号都由主机控制产生,而 MISO 的信号由从机 产生,主机通过该信号线读取从机的数据。MOSI与MISO的信号只在NSS为低电平的时候才有 效,在SCK的每个时钟周期MOSI和MISO传输一位数据。?

4、STM32的SPI特性及架构

STM32的SPI外设可用作通讯的主机及从机,支持最高的SCK时钟频率为fpclk/2(STM32F103型 号的芯片默认f:sub:pclk1为72MHz,fpclk2 为36MHz),完全支持SPI协议的4种模式,数据帧长 度可设置为8位或16位,可设置数据MSB先行或LSB先行。它还支持双线全双工(前面小节说 明的都是这种模式)、双线单向以及单线模式。其中双线单向模式可以同时使用MOSI及MISO数 据线向一个方向传输数据,可以加快一倍的传输速度。而单线模式则可以减少硬件接线,当然这 样速率会受到影响。

二、oled显示

1、文字取模

利用取模软件将需要显示的文字用十六进制表示出来

需要用到的取模软件

PCtoLCD2002

软件初始设置

?在文字输入区输入目标文字,点击生成字模,得到结果如下图

?2、代码改写

修改test.c文件下的内容显示函数TEST_MainPage(void)

void TEST_MainPage(void)
{	
	GUI_ShowCHinese(28,20,16,"黄三金",1);
	GUI_ShowString(4,48,"6319xxxxxxx8",16,1);
	//GUI_ShowString(4,48,"www.lcdwiki.com",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:黑字白底)。

修改oledfont.h文件下的文字存储typFNT_GB16 cfont16[]函数,将上述文字取模中的16进制按下述形式复制进去。

const typFNT_GB16 cfont16[] = 
{
  "黄",0x04,0x40,0x3F,0xF8,0x04,0x40,0x04,0x40,0xFF,0xFE,0x01,0x00,0x1F,0xF0,0x11,0x10,
0x11,0x10,0x1F,0xF0,0x11,0x10,0x11,0x10,0x1F,0xF0,0x04,0x40,0x08,0x20,0x10,0x10,/*"黄",0*/
  "三",0x00,0x00,0x00,0x00,0x7F,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF8,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFE,0x00,0x00,0x00,0x00,/*"三",1*/
  "金",0x01,0x00,0x01,0x00,0x02,0x80,0x04,0x40,0x08,0x20,0x10,0x10,0x2F,0xE8,0xC1,0x06,
0x01,0x00,0x3F,0xF8,0x01,0x00,0x11,0x10,0x09,0x10,0x09,0x20,0xFF,0xFE,0x00,0x00,/*"金",2*/

};

修改main.c文件中的while循环如下

int main(void)
{	
	delay_init();	    	       //延时函数初始化	  
	NVIC_Configuration(); 	   //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 	
	OLED_Init();			         //初始化OLED  
	OLED_Clear(0);             //清屏(全黑)
	while(1) 
	{	
		TEST_MainPage();         //主界面显示测试
		
	}
}

3、接线方式

?4、将生成的hex文件烧录后运行结果

三、OLED 滑动显示字符

1、添加字模

跟上述方法一样,获取字模后,向?gui.c?下的?oledfont.h?头文件里的?cfont16[] 数组内的添加中文文字点阵即可。

这里我添加的是莫说相公痴,更有痴似相公者

2、修改显示函数

同上,在?test.c?里?void TEST_MainPage(void)?函数中不添加自己的想要显示的字符,如下:

void TEST_MainPage(void)
{	
	GUI_ShowCHinese(28,20,16,"莫说相公痴,更有痴似相公者",1);
	//GUI_ShowCHinese(28,20,16,"黄三金",1);
	//GUI_ShowString(4,48,"6319xxxxxxx8",16,1);
	//GUI_ShowString(4,48,"www.lcdwiki.com",16,1);
	delay_ms(1500);		
	delay_ms(1500);
}

3、修改主函数

?main.c?代码中的?while?函数删除,再添加如下代码:

我设置的是左右移动

int main(void)
{	
	delay_init();	    	       //延时函数初始化	  
	NVIC_Configuration(); 	   //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 	
	OLED_Init();			         //初始化OLED  
	OLED_Clear(0);             //清屏(全黑)
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);        //虚拟字节
OLED_WR_Byte(0x2F,OLED_CMD);        //开启滚动
TEST_MainPage();
OLED_WR_Byte(0x2F,OLED_CMD); 

}

注:水平左右移动

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);        //虚拟字节
OLED_WR_Byte(0x2F,OLED_CMD);        //开启滚动

注:垂直和水平滚动

OLED_WR_Byte(0x2e,OLED_CMD);        //关闭滚动
OLED_WR_Byte(0x29,OLED_CMD);        //水平垂直和水平滚动左右 29/2a
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);        //终止页 1
OLED_WR_Byte(0x01,OLED_CMD);        //垂直滚动偏移量
OLED_WR_Byte(0x2F,OLED_CMD);        //开启滚动

4、连线方式

这一步如上面一样

5、效果展示?

四、OLED 显示温湿度数据

1、添加字模

跟上述方法一样,获取需要显示的字的字模后,向?gui.c?下的?oledfont.h?头文件里的?cfont16[] 数组内的添加中文文字点阵即可。
我这里添加了“当、前、温、湿、度”这 5 个字的点阵。

2、修改代码

然后我们从这篇博客中移植部分代码(以下四个文件)。

基于 I2C 协议使用 AHT20 温湿度传感器采集数据_ssj925319的博客-CSDN博客

bsp_i2c.h

bsp_i2c.c

sys.h(移植后更改了名称为 AHT20_sys.h,不然会重名)

sys.c(移植后更改了名称为 AHT20_sys.c,不然会重名)

具体移植过程和修改可以参考这篇博客:基于 SPI 协议在 0.96 寸 OLED上【平滑显示汉字】及【温湿度数据采集显示】_ssj925319的博客-CSDN博客

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);
	}	

具体的工程文件如下

链接:https://pan.baidu.com/s/1YGvasonWqI_ss0XTAoRulA?
提取码:4vvf

3、运行结果?

?

五、总结

其实说实话,这个实验从头到尾,对于这个 SPI 协议并没有了解多少,入门小白,出门还是小白,整个文章的过程就是调用函数,修改变量而已,就好比学会了怎么吃饭,却不知道怎么做饭,对于嵌入式开发的同志们,这是极大的弊端,要深入分析,由于我还是大学生,时间不太多,就不花费时间写文章分析代码了,注释都很全,慢慢学,只要头发没掉光,你就还没学到头!
?

六、参考文献

基于 SPI 协议在 0.96 寸 OLED上【平滑显示汉字】及【温湿度数据采集显示】_ssj925319的博客-CSDN博客

基于STM32的温湿度采集——OLED显示_Harriet的博客-CSDN博客_基于stm32温湿度传感器采集

基于 I2C 协议使用 AHT20 温湿度传感器采集数据_ssj925319的博客-CSDN博客

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-11-27 10:04:07  更:2021-11-27 10:06:23 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 11:27:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码