嵌入式学习⑧——基于SPI/IIC接口的OLED数据显示

基于SPI/IIC接口的OLED数据显示



一、了解SPI

本部分转载自霁风AI博客:
SPI专题(一)——基础知识

1.什么是SPI

SPI(Serial Peripheral Interface)是串行外围设备接口。是一种高速的全双工同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为 PCB 的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议。常用于单片机和 EEPROM、FLASH、实时时钟、数字信号处理器等器件的通信。

2.特点

① 连接方式

SPI 是一个环形总线结构,由设备选择线(CS)时钟线(SCK)串行输出数据线(MOSI)串行输入数据线(MISO) 构成,其时序其实很简单,主要是在 sck 的控制下,两个双向移位寄存器进行数据交换。

在这里插入图片描述

(1)MOSI: 主器件数据输出,从器件数据输入

(2)MISO: 主器件数据输入,从器件数据输出

(3)SCLK : 时钟信号,由主器件产生

(4)SS(CS): 从器件使能信号,由主器件控制

② 模式

SPI 用主从模式Master Slave)架构;支持多 slave 模式应用,一般仅支持单 Master。时钟由 Master 控制,在时钟移位脉冲下,数据按位传输,高位在前,低位在后(MSB first);SPI 接口有 2 根单向数据线,为全双工通信,目前应用中的数据速率可达几 Mbps 的水平。

在这里插入图片描述
主片在访问某一从片时,必须使该从片的片选信号有效;主片在 SCK 信号的同步下,通过 MOSI 线发出指令、地址信息;如需将数据输出,则接着写指令,由 SCK 同步在 MOSI 线上发出数据;如需读回数据,则接着读指令,由主片发出 SCK,从片根据 SCK 的节拍通过 MISO 发回数据。对具有 SPI 接口的从片器件来讲,SCK、MOSI 是输入信号,MISO 是输出信号。

3.内部结构

在这里插入图片描述
工作原理:主机和从机内部都有一个串行的移位寄存器,主机向其串行移位寄存器中写入一个字节发起传输,寄存器通过 MOSI 信号线将字节发送到从机,从机也将自己的移位寄存器一个字节发送给主机,从而实现两个移位寄存器的一个字节交换。

4.通信方式

① 通信协议

SPI 是单主设备通信协议,这意味着总线中只有一个中心设备能发起通信,当 SPI 主设备想读/写从设备时,它要 拉低从设备对应的 CS 线(CS 是低电平有效的)。主机和从机都有一个串行移位寄存器,主机通过向它的 SPI 串行寄存器写入一个字节来发起一次传输。寄存器通过 MOSI 信号线将字节传送给从机,实现“写”的功能。从机也将自己的移位寄存器中的内容通过 MISO 信号线返回给主机,实现“读”的功能。这样,两个移位寄存器中的内容就被交换,外设的写操作和读操作是同步完成的。如果只进行写操作,主机只需忽略接收到的字节;反之,若主机要读取从机的一个字节,就必须发送一个空字节来引发从机的传输

② 操作模式

SPI 有四种操作模式,模式0、模式1、模式2、模式3 其中使用的最为广泛的是 SPI0 和 SPI3 方式。它们的区别是定义了在时钟脉冲的哪条边沿转换输出信号,哪条边沿采样输入信号,还有时钟脉冲的稳定电平值(就是时钟信号无效时是高还是低)。每种模式都由参数时钟极性 CPOL 和时钟相位 CPHA 刻画。 时钟极性设置时钟空闲时的电平,时钟相位设置读取数据和发送数据的时钟沿。 通信双方必须是工作在同一模式下,CPOL 与 CPHA 的选项可实现时钟信号 180 度的相移以及半个时钟周期的数据延迟。(CPHA = 0 表示在每个周期的第一个时钟沿采样; CPHA = 1 表示在每个周期的第二个时钟沿采样。)

四种模式如下图:

在这里插入图片描述
如图:数据采集的电平

在这里插入图片描述
主机和从机的发送数据是同时完成的,两者的接收数据也是同时完成的。所以为了保证主从机正确通信,应使得它们的 SPI 具有相同的时钟极性和时钟相位。因为:其一,主设备 SPI 时钟和极性的配置应该由外设来决定;其二,二者的配置应该保持一致,即主设备的 SDO 同从设备的 SDO 配置一致,主设备的 SDI 同从设备的S DI 配置一致。因为主从设备是在 SCK 的控制下,同时发送和接收数据,并通过 2 个双向移位寄存器来交换数据。

③ 传输时序

四种模式的传输时序如下:

在这里插入图片描述

一个完整的传送周期是16位,即两个字节,因为,首先主机要发送命令过去,然后从机根据主机的命令准备数据,主机在下一个8位时钟周期才把数据读回来。如下图:

在这里插入图片描述

④ 优缺点

SPI 接口具有如下优点:

(1)支持全双工操作;

(2)操作简单;

(3) 数据传输速率较高。

缺点:

(1) 需要占用主机较多的口线(每个从机都需要一根片选线);

(2)只支持单个主机;

(3) 没有指定的流控制,没有应答机制确认是否接收到数据。


二、使用OLED显示屏显示数据

1.实验器材

软件:keil
硬件:PC机,STM32MINI,0.96寸OLED显示屏,ST_Link

2.硬件连接

在这里插入图片描述

3.代码实现

此工程基于STM32例程编写,以实现以下功能:

  • 显示自己的学号
  • 显示自己的姓名
  • 添加汉字字模

使用软件PCtoLCD2002
在这里插入图片描述

软件设置如图所示
在这里插入图片描述

写入需要显示的字符
这里以:航神我的超人 为例
在这里插入图片描述
得到字模

(0)(1)(2)(3)(4)(5)

DB 10H 40H 20H 20H 7CH 00H 45H FCH 64H 00H 54H 00H 54H F0H FCH 90H;
DB 44H 90H 64H 90H 54H 90H 54H 92H 44H 92H 45H 12H 55H 0EH 8AH 00H;"航",0
DB 20H 20H 10H 20H 10H 20H F9H FCH 09H 24H 11H 24H 11H 24H 39H FCH;
DB 55H 24H 95H 24H 11H 24H 11H FCH 11H 24H 10H 20H 10H 20H 10H 20H;"神",1
DB 04H 40H 0EH 50H 78H 48H 08H 48H 08H 40H FFH FEH 08H 40H 08H 44H;
DB 0AH 44H 0CH 48H 18H 30H 68H 22H 08H 52H 08H 8AH 2BH 06H 10H 02H;"我",2
DB 10H 40H 10H 40H 20H 40H 7EH 7CH 42H 84H 42H 84H 43H 04H 42H 44H;
DB 7EH 24H 42H 24H 42H 04H 42H 04H 42H 04H 7EH 04H 42H 28H 00H 10H;"的",3
DB 08H 00H 09H FCH 08H 44H 7EH 44H 08H 44H 08H 94H FFH 08H 08H FCH;
DB 28H 84H 28H 84H 2EH 84H 28H FCH 28H 00H 58H 00H 4FH FEH 80H 00H;"超",4
DB 01H 00H 01H 00H 01H 00H 01H 00H 01H 00H 01H 00H 02H 80H 02H 80H;
DB 04H 40H 04H 40H 08H 20H 08H 20H 10H 10H 20H 08H 40H 04H 80H 02H;"人",5


将得到的字模添加进函数

const typFNT_GB16 cfont16[] = 
{
  "航",0x00,0x00,0x08,0x60,0x10,0x20,0x3E,0x20,0x27,0xFE,0x36,0x00,0x2E,0x00,0x26,0xF8,
  0x7E,0xC8,0x26,0xC8,0x36,0xC8,0x2E,0x88,0x26,0x88,0x46,0x8A,0x4D,0x0E,0x43,0x00,/*"航",0*/
  "神",0x00,0x00,0x10,0x20,0x08,0x20,0x11,0xFE,0x7D,0x22,0x0D,0x22,0x09,0x22,0x19,0xFE,
  0x3D,0x22,0x75,0x22,0x51,0xFE,0x11,0x22,0x11,0x20,0x10,0x20,0x10,0x20,0x10,0x20,/*"神",1*/
  "我",0x00,0x00,0x00,0x40,0x07,0x50,0x7C,0x48,0x0C,0x44,0x0C,0x40,0x7F,0xFE,0x0C,0x48,
  0x0C,0x44,0x0F,0x4C,0x7C,0x78,0x0C,0x30,0x0C,0x70,0x0C,0xDA,0x1B,0x0E,0x10,0x00,/*"我",3*/
  "的",0x00,0x00,0x08,0x20,0x08,0x60,0x18,0x40,0x3E,0x7E,0x22,0xC6,0x22,0x86,0x23,0x86,
  0x3E,0x66,0x22,0x24,0x22,0x34,0x22,0x04,0x22,0x04,0x3E,0x04,0x22,0x3C,0x00,0x00,/*"的",4*/
  "超",0x00,0x00,0x08,0x00,0x08,0xFE,0x3E,0x26,0x08,0x24,0x08,0x44,0x7F,0xDC,0x0C,0x90,
  0x0C,0x7C,0x2F,0x44,0x2D,0x44,0x2C,0x44,0x7C,0x7C,0x4C,0x00,0x47,0xFE,0x00,0x00,/*"超",5*/
  "人",0x00,0x00,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,
  0x03,0xC0,0x02,0x40,0x06,0x60,0x04,0x30,0x08,0x18,0x30,0x0C,0x60,0x06,0x00,0x00,/*"人",6*/

};

test.c

void TEST_MainPage(void)
{	

	TEST_Number_Character(); //数字和符号显示
	TEST_Chinese();  
}


void TEST_Number_Character(void) 
{
	GUI_ShowString(0,0,"631807030425",8,1);  //输出学号
}

void TEST_Chinese(void)
{	

	GUI_ShowCHinese(16,20,16,"航神我的超人",1);  //输出字符
	delay_ms(1000);

}

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();         //主界面显示测试
		OLED_Clear(0); 
	}
}

4.演示

在这里插入图片描述

三、显示AHT20的温湿度

实验器材与硬件连接与前一步相仿

1.代码实现

将上一步中的test.c代码修改为:

test.c

//温度显示函数
void show_tem(int hem,int tem)
{
	GUI_ShowString(8,32,"温度: ",16,1);//显示湿度
	GUI_ShowNum(48,32,hem,2,16,1);
	GUI_ShowString(64,32,"%",16,1);
	GUI_ShowString(8,48,"湿度: ",16,1);//显示温度
	GUI_ShowNum(48,48,tem,2,16,1);
	GUI_ShowCHinese(64,48,16,"¡æ",1);
}

main.c

#include "delay.h"
#include "sys.h"
#include "oled.h"
#include "gui.h"
#include "test.h"
#include "24cxx.h"	 
#include "AHT20.h"
struct m_AHT20 AHT20;
int main(void)
{	
	int hem,tem;
	delay_init();	    	    
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	 
	IIC_Init();						
	AHT20.alive=!AHT20_Init();	       
	OLED_Init();			    
	OLED_Clear(0);             
	while(1) 
	{	
		show_my_num(); 
		show_my_name();
		if(AHT20.alive)
		{
			AHT20.flag = AHT20_ReadHT(AHT20.HT);
			hem = AHT20.HT[0]*100*10/1024/1024/10;
			tem = (AHT20.HT[1]*200*10/1024/1024-500)/10;
		}
		show_tem(hem,tem);
		delay_ms(9000);
		delay_ms(9000);
	}
}

2.演示

在这里插入图片描述

四、显示滚动字符

1.代码实现

void Roll_display(void)
{
	int i,j,m=112,n=0,k=0;
	for(j=0;j<1;j++)
		for(i=m;i>=-208;i-=1)
		{
			if(i<m&&i>n)
				GUI_ShowFont16(i,22,"重",1);
			if(i+16<m&&i+16>n)
				GUI_ShowFont16(i+16,22,"庆",1);
			if(i+32<m&&i+32>n)
				GUI_ShowFont16(i+32,22,"交",1);
			if(i+48<m&&i+48>n)	
				GUI_ShowFont16(i+48,22,"通",1);
			if(i+64<m&&i+64>n)
				GUI_ShowFont16(i+64,22,"大",1);
			if(i+80<m&&i+80>n)
				GUI_ShowFont16(i+80,22,"学",1);
			if(i+96<m&&i+96>n)
				GUI_ShowFont16(i+96,22,"欢",1);
			if(i+112<m&&i+112>n)	
				GUI_ShowFont16(i+112,22,"迎",1);
			if(i+128<m&&i+128>n)
				GUI_ShowFont16(i+128,22,"您",1);
			delay_ms(42);
			k++;
			if(k==16)
			{
				OLED_Clear(0); 
				k=0;
			}
		}	
}

roll.c

void roll(void)
{  
	OLED_WR_Byte(0x2F, OLED_CMD);  
	OLED_WR_Byte(0x27, OLED_CMD);   
	OLED_WR_Byte(0x00,OLED_CMD);       
  	OLED_WR_Byte(0x00,OLED_CMD);        
  	OLED_WR_Byte(0x07,OLED_CMD);        
  	OLED_WR_Byte(0x2E,OLED_CMD); 	
  	while(1);
}

显示函数show_roll

void show_roll(void)
{	
	GUI_ShowCHinese(45,16,16,"重庆交通大学欢迎您",1);
}

2.演示

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值