STM32之CubeMX学习笔记(7)SPI驱动OLED及其优化

这篇具有很好参考价值的文章主要介绍了STM32之CubeMX学习笔记(7)SPI驱动OLED及其优化。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


SPI通信

购买了逻辑分析仪后,总想着把所有的通讯信号全都看一遍。之前一篇笔记讲的是串口通信,做了一些小实验,搞清楚了如何基于底层利用串口传一些“非标”的数据。关于通信协议的第二篇,我想来看看SPI通信。

SPI简述

SPI通信是Serial peripheral interface的缩写,中文是串行外设接口,它可以使单片机与各种外围设备以串行的方式进行通信和交换信息,外围设备包括FlashRAM、网络控制器、LCD屏幕、AD转换器、甚至是其他的MCU。最早是摩托罗拉提出的三线SPI全双工协议,由一根SCK时钟线,一根主出从入MOSI线,一根主入从出MISO线。其中从线可以供多个从机使用,这时就需要片选线来进行选择,总共需要四根线。我们只需要确定是时钟上升沿为数据还是下降沿为数据即可。

一个关于时钟系“小”通信协议的问题

对比IIC来说,由于全双工的属性,SPI的传输速率是很高的,但是这样也会使用比较多的IO资源,IIC需要的IO口少,只要两个,但是IIC传输速度较慢。但这只是很多攻略上说的那样,其实SPI也可以只用两根线进行通信,一根时钟线,一根半双工通讯线。当然串口也有同步传输模式,不过它会在RX和TX的基础上再多加一个时钟线,这看起来又和SPI的全双工的三线模式很像了。这些“小”通讯协议虽然在底层的处理数据的逻辑上有些不同,但是其本质上还是服务于单片机等一些不需要大量传输数据的芯片间通信场景。
但是这些相似而不全相同的通讯协议间,在使用相同的系统资源后,性能和优缺点到底是怎么样的,这些问题可能已经有人做过了,但是耳闻不如躬行,所以还是要通过实验来验真知。
但是在本篇文章中我们不进行对比实验,我们要通过用SPI通信OLED屏幕来看一下双线SPI工作情况和对OLED驱动的优化。

7针OLED使用SPI协议显示

在我的操作习惯中,一般使用7针的0.96寸OLED屏幕进行对一些数字信息进行实时显示。首先这个传统是由和我对接的实验室师兄传给我的,而且在以后的一段时间中,因为驱动一只能用,就没有深究,只知道因为SPI传输速率快,所以一直用7针的。当然,实验室还有一批人是用4针,甚至我还认识一位兄弟用的是6针的OLED,4针和6针的OLED都是用IIC通信的,这种协议我们可以今后再做一个小实验来验证显示速率问题。
这个7针中景园OLED的驱动比较简单,管脚除了GND和VCC之外,还有D0(时钟线),D1(MOSI),RES(低电平复位),DC(决定发送的是命令还是数据),CS(片选口)。

OLED软件SPI

我们先在CubeMX中设置一下GPIO输出,并且将其速率调整到非常高,Very High。
stm32硬件spi驱动oled,STM32CubeMX,stm32,单片机,学习,stm32 CubeMx,嵌入式硬件
stm32硬件spi驱动oled,STM32CubeMX,stm32,单片机,学习,stm32 CubeMx,嵌入式硬件
在程序中只有一个写字节的底层函数,中景园用的是软件SPI,程序如下。

void OLED_WR_Byte(uint8_t dat,uint8_t cmd)
{	
	uint8_t i;			  
	OLED_DC=cmd; //写命令 
	OLED_CS=0;		  
	for(i=0;i<8;i++)
	{			  
		OLED_D0=0;
		if(dat&0x80)OLED_D1=1;
		else OLED_D1=0;
		OLED_D0=1;
		dat<<=1;   
	}				 
	OLED_CS=1;		  
	OLED_DC=1; 
}

我们发现当片选CS拉低后,开始发送,D0模拟一个8个脉冲的时钟,D1则在这8个脉冲的时间内表现出“我是个8位数据”的样子,其中DC为0时是写命令给OLED,DC为1时是写显示数据给OLED。写完一个Byte后,DC和CS拉高。

stm32硬件spi驱动oled,STM32CubeMX,stm32,单片机,学习,stm32 CubeMx,嵌入式硬件
stm32硬件spi驱动oled,STM32CubeMX,stm32,单片机,学习,stm32 CubeMx,嵌入式硬件

我们通过上图可以发现,将STM32F401RCT6(84MHz)的IO速率设置为最高后,做出的D0时钟周期要100ns,再加上DC和CS的拉高,整个SPI发送8位数据的时间需要1.6us。当刷新整块OLED屏幕需要128*8=1024个8位数据,所需的时间需要近2ms的时间。所以不能将其放入1ms级的定时器中断,会导致单片机死机。

OLED硬件SPI

软件SPI在84MHz主频的单片机手下可以做到略高于5Mbit/s的传输速率,虽然这已经很快了,但是STM32F401RCT6的SPI1和4可以做到42Mbit/s的速率,SPI2和3也可以做到24Mbit/s的传输速率,我们为何不用硬件SPI呢。
stm32硬件spi驱动oled,STM32CubeMX,stm32,单片机,学习,stm32 CubeMx,嵌入式硬件

并且对原代码进行修改,原代码是发送一个字节,我们这里也设置size为1

void OLED_WR_Byte(uint8_t dat,uint8_t cmd)
{	
	uint8_t *data = &dat;		  
	if(cmd)
		OLED_DC_Set();
	else
		OLED_DC_Clr();
	OLED_CS_Clr();
	
  	HAL_SPI_Transmit(&hspi1, (uint8_t *)data, 1, 200); 
	
	OLED_CS_Set();
	OLED_DC_Set();
}

很可惜的是,由于HAL库中对各种功能的判断处理操作过多,发送每个字节之间的间隔被延长到3.25us左右。如图。
stm32硬件spi驱动oled,STM32CubeMX,stm32,单片机,学习,stm32 CubeMx,嵌入式硬件

HAL库在这方面是真的比较慢。改成16分频是因为这个速度不仅和GPIO控制的速度差不多(5.25Mbit/s),这也是我的逻辑分析仪能承受速度的极限(稳定采样率12MHz)。2分频的42Mbit/s也是可以用的,但只是不好观察。
stm32硬件spi驱动oled,STM32CubeMX,stm32,单片机,学习,stm32 CubeMx,嵌入式硬件

我们拉长时间轴,可以发现这每个字节多用的3.25us让整个刷新OLED显存操作的时间上升到5ms,就算是换成42Mbit/s,这3us的硬伤还是无法解决。

OLED硬件SPI优化版

我们发现HAL_SPI是可以一次发送多个数据的,这样就不会一直做很多判断操作。我们从这个点出发,对程序进行一些修改。中景园使用的是一个二维数组来存放显存,但是数组的行是Y轴,数组的列是X轴,其刷新操作又是按照、X轴去刷新的。所以我们要将X轴变为横向的数组,这样我们就可以用spi一次发128个字节了。由于要写命令不能1024个字节一起发,但是128个连发已经省了不少时间。

uint8_t OLED_GRAM[128][8];//[x][y]
uint8_t OLED_XGRAM[128];

void OLED_Refresh_Gram(void)
{
	uint8_t i;
	uint8_t n;		    
	for(i=0;i<8;i++)  
	{  
		OLED_WR_Byte (0xb0+i,OLED_CMD);//设置页地址(0~7)
		OLED_WR_Byte (0x00,OLED_CMD);//设置显示位置—列低地址
		OLED_WR_Byte (0x10,OLED_CMD);//设置显示位置—列高地址   
		for(n=0;n<128;n++)
		{
//			OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA);
			OLED_XGRAM[n] = OLED_GRAM[n][i];
//			OLED_WR_Byte(OLED_XGRAM[n], OLED_DATA);
		}
    OLED_WR_128Byte(OLED_XGRAM, OLED_DATA);
	}   
}

void OLED_WR_128Byte(uint8_t *dat,uint8_t cmd)
{	 

//	uint8_t *data = &dat;		  
	if(cmd)
		OLED_DC_Set();
	else
		OLED_DC_Clr();
	OLED_CS_Clr();
	
  HAL_SPI_Transmit(&hspi1, dat, 128, 200); //需根据实际情况修改 
	
	OLED_CS_Set();
	OLED_DC_Set();

}

在调试程序的时候,我直接改成了数组首地址传送,不然当单个数据传过来时,它的地址已经去了堆栈,根本找不到下一个数据的地址。
stm32硬件spi驱动oled,STM32CubeMX,stm32,单片机,学习,stm32 CubeMx,嵌入式硬件

我们发现,现在硬件SPI的速度终于赶上了软件SPI的1.8ms,但是这才是16分频,2分频的42Mbit/s才是真正的王道,大家请欣赏。
stm32硬件spi驱动oled,STM32CubeMX,stm32,单片机,学习,stm32 CubeMx,嵌入式硬件

SPI的速度已经超过了我的逻辑分析仪采样速度,时钟读取和数据翻译已经完全乱套了,但是我们通过时间还可以看到整个屏幕显存刷新显示时间已经降低到了0.55ms。甚至数组转存的时间都在图中显而易见了。

总结

通过小幅改进中景园的OLED程序,我们熟悉了SPI数据的传输结构,尝试了软件和硬件spi的使用,也领略了42Mbit/s的硬件SPI的速度。SPI是一款实用的,简单的,高速的通讯协议,它的硬件传输直接与你的芯片主频挂钩,没有什么奇奇怪怪的速率协议,说的就是你,IIC。下一期,我会从软件和硬件的两个维度,来用逻辑分析仪看IIC协议。文章来源地址https://www.toymoban.com/news/detail-755898.html

到了这里,关于STM32之CubeMX学习笔记(7)SPI驱动OLED及其优化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32_SPI总线驱动OLED详细原理讲解

    目录 13.1.1 SPI总线介绍 SPI(Serial Peripheral interface):是由Motorola公司开发的串行外围设备接口,是一种高速的,全双工,同步的通信总线。主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器等器件。 UART:异步串行全双工 SPI:同步串行全双工

    2024年01月20日
    浏览(43)
  • STM32-SPI驱动7针脚OLED,显示中文,字符串,数字,图片。

    STM32-SPI驱动7针脚OLED,显示中文,数字,图片。 本文为STM32f103rct6利用SPI驱动7针脚oled模块显示中文,数字和图片。 1,如图,为本次驱动的oled模块 2,引脚定义: GND--电源地; VCC--电源正极(3.3v~5v); D0--时钟线; D1--数据线; RES--复位线; DC--数据/命令控制线; CS--片选线,低电

    2024年02月05日
    浏览(51)
  • STM32配合cubeMX硬件I2C驱动0.96寸OLED

    目录 一、简单介绍 1.1   OLED 1.2   I2C协议 二、实战 2.1 工程配置 2.2 测试工程 2.3 波形分析 三、驱动OLED 3.1 初始化代码 3.2 清屏函数 3.3 设置坐标函数 3.4 显示字符函数 3.5 显示字符串函数 3.6 显示图片函数 附录 驱动代码文件 oled.c oled.h f6x8.h 有机发光二极管 (英语:Organic

    2024年02月08日
    浏览(64)
  • 【STM32CubeMX】教程二_IIC驱动0.96oled屏幕(SSD1306)

    本篇博客涉及以下内容 IIC通讯原理讲解、代码编写 SSD1306驱动芯片datasheet讲解、驱动代码编写、0.96oled模块原理图说明 STM32CubeMX配置IIC 使用硬件:STM32F103C8T6 使用软件:STM32CubeMX、keil5(MDK)、VSCode(搭载keil assistant插件) 提示:以下是本篇文章正文内容   在计算机科学里,大

    2023年04月21日
    浏览(50)
  • 7针0.96寸OLED的HAL库代码(硬件SPI/全代码/stm32f1/CubeMX配置/包含有正负浮点数/100%一次点亮)

    HC-SR04超声波模块的使用  编码电机以及双电机驱动 4针 0.96\\\'OLED的使用 更多有意思的文章点击“我的主页” --------😐 更多有意思的视频 ----- B站 @想要亿只独角兽 --------😐 之前发布了一篇硬件I2C的0.96\\\' OLED驱动代码,这次就添加一篇硬件SPI的驱动代码。 其实改动的代码不多,

    2024年02月16日
    浏览(47)
  • STM32F1基于STM32CubeMX配置硬件SPI驱动1.8寸TFT LCD128X160 ST7735S屏幕

    📌相关篇《【STM32CubeIDE】STM32F103硬件SPI驱动1.8寸TFT LCD128X160 ST7735S屏幕》 ✨驱动效果就不做演示了,和上面的相关篇一样,主要是为了方便使用MDK Keil开发的使用。所以花了点时间从上面的工程当中做了分离,重新使用STM32CubeMX配置一个方便二次开发移植使用和配置的工程。本

    2024年02月03日
    浏览(50)
  • STM32F103C8T6—库函数应用I2C/SPI驱动OLED显示中文、字符串

    I2C(Inter-Integrated Circuit) SPI(Serial Peripheral Interface) 传输方式 半双工 全双工 传输速度 低速,100Kbps----4Mbps 高速,30Mbps以上 几线制 4线制:VCC,GND,SCL,SDA 6/7线制:VCC,GND,SCLK(D0),MOSI(D1/SDA),DC,CS/SS 主从模式 多主机总线,通过SDA上的地址信息锁定从机 只有一个主机,主

    2024年02月02日
    浏览(62)
  • 【STM32CubeMX学习】SPI读写W25Q16

            SPI分为主从工作模式,通常有一个主设备和一个或多个从设备,本文中MCU为主机,W25Q16为从机。 SPI通信有以下四根线: MISO:主设备数据输入,从设备数据输出。 MOSI:主设备数据输出,从设备数据输入。 SCLK:时钟信号,由主设备产生。 CS:从设备片选信号,由

    2024年02月03日
    浏览(51)
  • 【STM32】BLDC驱动&控制开发笔记 | 07_SPI通信测试 - STM32F407用SPI配置DRV8323驱动芯片

    最近在埋头搞STM32 + 无刷直流电机控制,想实现用自己的STM32F407VGT6芯片板子,外加一块驱动板(目前选用到TI的DRV8302或者DRV8323驱动芯片),搞定电机驱动,最后实现比较好的控制效果。如果不是同一块芯片的同学也不用急着走,大体上都是可借鉴哒~ 本文主要实现使用SPI通信

    2024年02月08日
    浏览(55)
  • STM32 cubeMX配置OLED

    本篇文章主要介绍OLED的操作和使用。 OLED一共有四根线这里我使用的是IIC的OLED显示屏。 VCC----3.3V或者5V GND-----GND SDA-----PB7 SCL-----PB6 开启IIC1的IIC功能。基础的配置在这里就不讲了,还不懂的可以看我前面的文章。 OLED cubemx的配置只需要这样设置一下即可。 这里只展示几个比较

    2023年04月20日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包