文章目录[隐藏]
一、SPI协议
SPI 协议是由摩托罗拉公司提出的通讯协议(Serial Peripheral Interface),即串行外围设备接口,是一种高速全双工的通信总线。它被广泛地使用在 ADC、LCD 等设备与 MCU 间,要求通讯速率较高的场合。
1、SPI物理层
物理层通讯设备连接方式
2、SPI协议层
与 I2C 的类似,SPI 协议定义了通讯的起始和停止信号、数据有效性、时钟同步等环节。
- 这是一个主机的通讯时序。NSS、SCK、MOSI 信号都由主机控制产生,而 MISO 的信号由从机产生,主机通过该信号线读取从机的数据。MOSI 与 MISO 的信号只在 NSS 为低电平的时候才有效,在 SCK 的每个时钟周期 MOSI 和 MISO 传输一位数据。
- 这种通讯时序只是SPI 中的其中一种通讯模式,SPI 一共有四种通讯模式,它们的主要区别是总线空闲时 SCK 的时钟状态以及数据采样时刻。为方便说明,在此引入“时钟极性 CPOL”和“时钟相位 CPHA”的概念。
由 CPOL 及 CPHA 的不同状态,SPI 分成了四种模式,主机与从机需要工作在相同的模式下才可以正常通讯,实际中采用较多的是“模式 0”与“模式 3”。 - 这只是关于SPI协议中的一部分内容,如果想知道更多可以去看 零死角玩转STM32–指南针第25章里面有详细介绍。
二、OLED显示屏介绍
OLED(OrganicLight-Emitting Diode),又称为有机电激光显示、有机发光半导体(OrganicElectroluminesence Display,OLED)。OLED属于一种电流型的有机发光器件,是通过载流子的注入和复合而致发光的现象,发光强度与注入的电流成正比。OLED在电场的作用下,阳极产生的空穴和阴极产生的电子就会发生移动,分别向空穴传输层和电子传输层注入,迁移到发光层。当二者在发光层相遇时,产生能量激子,从而激发发光分子最终产生可见光。
- OLED点阵显示
点阵屏像素按128列X64行组织,每一行128个像素单元的阴极是连接在一起,作为公共极(COM),每一列64个像素单元的阳极也连接在一起,作为一段(SEG)。行列交叉点上的LED就是一个显示单元,即一个像素。要点亮一个像素,只要在该像素所在列电极上加上正电压、行电极接地。同样,要驱动一整行图像,就需要同时把128列信号加载到列电极上,把该行行电极接地。该行显示时,其他63行均不能显示,其行电极应为高电平或悬空。可见,整屏的显示,只能分时扫描进行,一行一行的显示,每次显示一行。行驱依次产生低电平扫描各行,列驱动读取显示数据依次加载到列电极上。扫描一行的时间称为行周期,完成一次全屏扫描,就叫做一帧。一般帧频大于60,人眼观察不到逐行显示。每行扫描显示用时叫占空比,占空比小,为达到相同的显示亮度,驱动电流就大。SSD1306段驱动最大电流为100uA,当整行128个像素全部点亮时,行电极就要流过12.8mA的电流。
OLED接线说明
对于0.96寸OLED显示屏的介绍可参考以下连接:
http://www.lcdwiki.com/zh/0.96inch_SPI_OLED_Module这是0.96寸OLED显示屏最为详细的介绍,其中包括产品介绍、接口介绍、厂家的样本程序模块及各种参考资料。
三、汉字点阵编码原理
1、汉字点阵原理
可以参考我在上一篇汉字点阵练习博客中详细的说明了汉字点阵的原理。
2、点阵字库取模
①字库生成工具
可以在上述OLED显示屏的官网中下载。
也可以在字库官网中下载,官网连接:
http://www.ddooo.com/softdown/86895.htm
②汉字取模演示
点解设置修改取模参数
修改为如图所示。
配置号字模选项后,输入想要取模的汉字,再点击生成字模即可。
四、OLED显示屏显示实例
本次实验采用的都是7针的OLED显屏
先介绍一下OLED主要使用的函数
//OLED控制用函数
void OLED_WR_Byte(unsigned dat,unsigned cmd);
void OLED_Display_On(void);
void OLED_Display_Off(void);
void OLED_Set_Pos(unsigned char x, unsigned char y);
void OLED_Reset(void);
void OLED_Init_GPIO(void);
void OLED_Init(void);
void OLED_Set_Pixel(unsigned char x, unsigned char y,unsigned char color);
void OLED_Display(void);
void OLED_Clear(unsigned dat);
OLED显示屏介绍中有说明各个函数的作用。
(1)、OLED显示自己的学号和姓名
1、汉字取模自己的姓名
2、代码编写
main.c
#include "delay.h"
#include "sys.h"
#include "oled.h"
#include "gui.h"
#include "test.h"
int main(void)
{
delay_init(); //延时函数初始化
NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
OLED_Init(); //初始化OLED
OLED_Clear(0); //清屏(全黑)
while(1)
{
TEST_MainPage(); //主界面显示测试
}
}
主界面函数void TEST_MainPage(void)
void TEST_MainPage(void)
{
GUI_ShowCHinese(28,20,16,"通信工程啊桐",1);
GUI_ShowString(4,48,"631907030627",16,1);
delay_ms(1500);
delay_ms(1500);
}
GUI_ShowCHinese(28,20,16,"通信工程啊桐",1)
;含义:
28:表示字符在LCD显示的横轴x的起始坐标
20:表示字符在LCD显示的纵轴y的起始坐标
16:表示显示字符串字体的大小,可设置为12/16/24
通信工程啊桐:显示的汉字
1:显示样式(1:白字黑底;0:黑字白底)
GUI_ShowString(4,48,"631907030627",16,1);
参数含义:
4:表示字符在LCD显示的横轴x的起始坐标
48:表示字符在LCD显示的纵轴y的起始坐标
参数三:字符串(ASCLL码中的)
16:bit (表示字符显示格式,这里我用的 16 ,和汉字一样高)
1:显示样式(1:白字黑底;0:黑字白底)
将生成的点阵数据复制到gui.c
文件中的oledfont.h
的16*16格式的函数中:
3、结果显示
1、OLED显示接线、烧录.hex文件
2、结果显示
(2)、OLED显示AHT20的温度和湿度
1、代码编写
主函数main.c
#include "delay.h"
#include "usart.h"
#include "bsp_i2c.h"
#include "sys.h"
#include "oled.h"
#include "gui.h"
#include "test.h"
int main(void)
{
delay_init(); //延时函数初始化
uart_init(115200);
IIC_Init();
NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
OLED_Init(); //初始化OLED
OLED_Clear(0);
while(1)
{
//printf("温度湿度显示");
read_AHT20_once();
OLED_Clear(0);
delay_ms(500);
}
}
温湿度读取控制函数read_AHT20_once(void);
void read_AHT20_once(void)
{
delay_ms(10);
reset_AHT20();
delay_ms(10);
init_AHT20();
delay_ms(10);
startMeasure_AHT20();
delay_ms(80);
read_AHT20();
delay_ms(5);
}
可以直接在之前的串口显示的工程中加入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*/
"度",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*/
"湿",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*/
"显",0x00,0x00,0x1F,0xF0,0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10,0x10,0x10,0x1F,0xF0,
0x04,0x40,0x44,0x44,0x24,0x44,0x14,0x48,0x14,0x50,0x04,0x40,0xFF,0xFE,0x00,0x00,/*"显",0*/
"示",0x00,0x00,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFE,0x01,0x00,
0x01,0x00,0x11,0x10,0x11,0x08,0x21,0x04,0x41,0x02,0x81,0x02,0x05,0x00,0x02,0x00,/*"示",
2、结果显示
①、OLED及STM32硬件连线、烧录
②、结果显示
(3)、OLED左滚动显示“谢谢观看”
1、代码编写
主函数main.c
#include "delay.h"
#include "sys.h"
#include "oled.h"
#include "gui.h"
#include "test.h"
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(0x27,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); //虚拟字节
TEST_MainPage();
OLED_WR_Byte(0x2F,OLED_CMD); //开启滚动
while(1)
{
}
}
主函数中包括了OLED的滚动函数,其中27为向左滚动,26为向右滚动。
显示函数void TEST_MainPage(void)
void TEST_MainPage(void)
{
GUI_ShowCHinese(16,28,16,"谢谢观看",1);
delay_ms(1000);
delay_ms(1000);
}
在oledfont.h
文件中添加谢谢观看显示字模数据
2、结果显示
①、OLED及STM32硬件连线、烧录
②、结果显示
五、实验总结
本次实验主要为完成基于STM32及ISP协议的OLED显屏。本次实验学习了一遍ISP协议,和之前的I2C协议对比发现SPI的速度要比I2C的传输速度更快,更适合用作高速传输通信。还学习了OLED显屏,它的学习资料比较全,但也有很多不太了解的地方,虽然此次实验的代码是借鉴的学长学姐的,但也认真分析了代码,OLED的代码在介绍中有可直接下载使用。在实验过程中我也遇到了一些问题有很多代码都看不懂需要在网上搜索。总而言之,学习是个漫长的过程,还得加油。如有错误,请指正。
六、参考文献
【1】零死角玩转STM32
【2】0.96存OLED显示屏介绍
【3】https://blog.csdn.net/qq_45237293/article/details/111712565
【4】OLED显屏滚动显示
版权声明:本文为CSDN博主「捶死挣扎的小猴」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_48861452/article/details/121458717
一、SPI协议
SPI 协议是由摩托罗拉公司提出的通讯协议(Serial Peripheral Interface),即串行外围设备接口,是一种高速全双工的通信总线。它被广泛地使用在 ADC、LCD 等设备与 MCU 间,要求通讯速率较高的场合。
1、SPI物理层
物理层通讯设备连接方式
2、SPI协议层
与 I2C 的类似,SPI 协议定义了通讯的起始和停止信号、数据有效性、时钟同步等环节。
- 这是一个主机的通讯时序。NSS、SCK、MOSI 信号都由主机控制产生,而 MISO 的信号由从机产生,主机通过该信号线读取从机的数据。MOSI 与 MISO 的信号只在 NSS 为低电平的时候才有效,在 SCK 的每个时钟周期 MOSI 和 MISO 传输一位数据。
- 这种通讯时序只是SPI 中的其中一种通讯模式,SPI 一共有四种通讯模式,它们的主要区别是总线空闲时 SCK 的时钟状态以及数据采样时刻。为方便说明,在此引入“时钟极性 CPOL”和“时钟相位 CPHA”的概念。
由 CPOL 及 CPHA 的不同状态,SPI 分成了四种模式,主机与从机需要工作在相同的模式下才可以正常通讯,实际中采用较多的是“模式 0”与“模式 3”。 - 这只是关于SPI协议中的一部分内容,如果想知道更多可以去看 零死角玩转STM32–指南针第25章里面有详细介绍。
二、OLED显示屏介绍
OLED(OrganicLight-Emitting Diode),又称为有机电激光显示、有机发光半导体(OrganicElectroluminesence Display,OLED)。OLED属于一种电流型的有机发光器件,是通过载流子的注入和复合而致发光的现象,发光强度与注入的电流成正比。OLED在电场的作用下,阳极产生的空穴和阴极产生的电子就会发生移动,分别向空穴传输层和电子传输层注入,迁移到发光层。当二者在发光层相遇时,产生能量激子,从而激发发光分子最终产生可见光。
- OLED点阵显示
点阵屏像素按128列X64行组织,每一行128个像素单元的阴极是连接在一起,作为公共极(COM),每一列64个像素单元的阳极也连接在一起,作为一段(SEG)。行列交叉点上的LED就是一个显示单元,即一个像素。要点亮一个像素,只要在该像素所在列电极上加上正电压、行电极接地。同样,要驱动一整行图像,就需要同时把128列信号加载到列电极上,把该行行电极接地。该行显示时,其他63行均不能显示,其行电极应为高电平或悬空。可见,整屏的显示,只能分时扫描进行,一行一行的显示,每次显示一行。行驱依次产生低电平扫描各行,列驱动读取显示数据依次加载到列电极上。扫描一行的时间称为行周期,完成一次全屏扫描,就叫做一帧。一般帧频大于60,人眼观察不到逐行显示。每行扫描显示用时叫占空比,占空比小,为达到相同的显示亮度,驱动电流就大。SSD1306段驱动最大电流为100uA,当整行128个像素全部点亮时,行电极就要流过12.8mA的电流。
OLED接线说明
对于0.96寸OLED显示屏的介绍可参考以下连接:
http://www.lcdwiki.com/zh/0.96inch_SPI_OLED_Module这是0.96寸OLED显示屏最为详细的介绍,其中包括产品介绍、接口介绍、厂家的样本程序模块及各种参考资料。
三、汉字点阵编码原理
1、汉字点阵原理
可以参考我在上一篇汉字点阵练习博客中详细的说明了汉字点阵的原理。
2、点阵字库取模
①字库生成工具
可以在上述OLED显示屏的官网中下载。
也可以在字库官网中下载,官网连接:
http://www.ddooo.com/softdown/86895.htm
②汉字取模演示
点解设置修改取模参数
修改为如图所示。
配置号字模选项后,输入想要取模的汉字,再点击生成字模即可。
四、OLED显示屏显示实例
本次实验采用的都是7针的OLED显屏
先介绍一下OLED主要使用的函数
//OLED控制用函数
void OLED_WR_Byte(unsigned dat,unsigned cmd);
void OLED_Display_On(void);
void OLED_Display_Off(void);
void OLED_Set_Pos(unsigned char x, unsigned char y);
void OLED_Reset(void);
void OLED_Init_GPIO(void);
void OLED_Init(void);
void OLED_Set_Pixel(unsigned char x, unsigned char y,unsigned char color);
void OLED_Display(void);
void OLED_Clear(unsigned dat);
OLED显示屏介绍中有说明各个函数的作用。
(1)、OLED显示自己的学号和姓名
1、汉字取模自己的姓名
2、代码编写
main.c
#include "delay.h"
#include "sys.h"
#include "oled.h"
#include "gui.h"
#include "test.h"
int main(void)
{
delay_init(); //延时函数初始化
NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
OLED_Init(); //初始化OLED
OLED_Clear(0); //清屏(全黑)
while(1)
{
TEST_MainPage(); //主界面显示测试
}
}
主界面函数void TEST_MainPage(void)
void TEST_MainPage(void)
{
GUI_ShowCHinese(28,20,16,"通信工程啊桐",1);
GUI_ShowString(4,48,"631907030627",16,1);
delay_ms(1500);
delay_ms(1500);
}
GUI_ShowCHinese(28,20,16,"通信工程啊桐",1)
;含义:
28:表示字符在LCD显示的横轴x的起始坐标
20:表示字符在LCD显示的纵轴y的起始坐标
16:表示显示字符串字体的大小,可设置为12/16/24
通信工程啊桐:显示的汉字
1:显示样式(1:白字黑底;0:黑字白底)
GUI_ShowString(4,48,"631907030627",16,1);
参数含义:
4:表示字符在LCD显示的横轴x的起始坐标
48:表示字符在LCD显示的纵轴y的起始坐标
参数三:字符串(ASCLL码中的)
16:bit (表示字符显示格式,这里我用的 16 ,和汉字一样高)
1:显示样式(1:白字黑底;0:黑字白底)
将生成的点阵数据复制到gui.c
文件中的oledfont.h
的16*16格式的函数中:
3、结果显示
1、OLED显示接线、烧录.hex文件
2、结果显示
(2)、OLED显示AHT20的温度和湿度
1、代码编写
主函数main.c
#include "delay.h"
#include "usart.h"
#include "bsp_i2c.h"
#include "sys.h"
#include "oled.h"
#include "gui.h"
#include "test.h"
int main(void)
{
delay_init(); //延时函数初始化
uart_init(115200);
IIC_Init();
NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
OLED_Init(); //初始化OLED
OLED_Clear(0);
while(1)
{
//printf("温度湿度显示");
read_AHT20_once();
OLED_Clear(0);
delay_ms(500);
}
}
温湿度读取控制函数read_AHT20_once(void);
void read_AHT20_once(void)
{
delay_ms(10);
reset_AHT20();
delay_ms(10);
init_AHT20();
delay_ms(10);
startMeasure_AHT20();
delay_ms(80);
read_AHT20();
delay_ms(5);
}
可以直接在之前的串口显示的工程中加入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*/
"度",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*/
"湿",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*/
"显",0x00,0x00,0x1F,0xF0,0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10,0x10,0x10,0x1F,0xF0,
0x04,0x40,0x44,0x44,0x24,0x44,0x14,0x48,0x14,0x50,0x04,0x40,0xFF,0xFE,0x00,0x00,/*"显",0*/
"示",0x00,0x00,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFE,0x01,0x00,
0x01,0x00,0x11,0x10,0x11,0x08,0x21,0x04,0x41,0x02,0x81,0x02,0x05,0x00,0x02,0x00,/*"示",
2、结果显示
①、OLED及STM32硬件连线、烧录
②、结果显示
(3)、OLED左滚动显示“谢谢观看”
1、代码编写
主函数main.c
#include "delay.h"
#include "sys.h"
#include "oled.h"
#include "gui.h"
#include "test.h"
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(0x27,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); //虚拟字节
TEST_MainPage();
OLED_WR_Byte(0x2F,OLED_CMD); //开启滚动
while(1)
{
}
}
主函数中包括了OLED的滚动函数,其中27为向左滚动,26为向右滚动。
显示函数void TEST_MainPage(void)
void TEST_MainPage(void)
{
GUI_ShowCHinese(16,28,16,"谢谢观看",1);
delay_ms(1000);
delay_ms(1000);
}
在oledfont.h
文件中添加谢谢观看显示字模数据
2、结果显示
①、OLED及STM32硬件连线、烧录
②、结果显示
五、实验总结
本次实验主要为完成基于STM32及ISP协议的OLED显屏。本次实验学习了一遍ISP协议,和之前的I2C协议对比发现SPI的速度要比I2C的传输速度更快,更适合用作高速传输通信。还学习了OLED显屏,它的学习资料比较全,但也有很多不太了解的地方,虽然此次实验的代码是借鉴的学长学姐的,但也认真分析了代码,OLED的代码在介绍中有可直接下载使用。在实验过程中我也遇到了一些问题有很多代码都看不懂需要在网上搜索。总而言之,学习是个漫长的过程,还得加油。如有错误,请指正。
六、参考文献
【1】零死角玩转STM32
【2】0.96存OLED显示屏介绍
【3】https://blog.csdn.net/qq_45237293/article/details/111712565
【4】OLED显屏滚动显示
版权声明:本文为CSDN博主「捶死挣扎的小猴」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_48861452/article/details/121458717
暂无评论