华芯微特SWM34-IO速度优化之模拟SPI写速度提速

news2024/9/20 20:32:25

本文以在SWM34S(M33内核,150Mhz,编译器Keil MDK 5.36)上优化为例,说明优化方法和需要注意的地方,其他MCU可以参考。
在编写模拟SPI通信驱动LCD的例子的时候,会用到一个发送字节的核心函数,其基本实现方式如下:

static void Spi4_WriteByte(uint8_t d)
{
	uint8_t i,spidat;
	spidat = d;
	for(i=0; i<8; i++)			
	{  
		if( (spidat&0x80)!=0 ) 
			LCD0_SPI4_MOSI_HIGH();
		else 
			LCD0_SPI4_MOSI_LOW();
		spidat <<= 1;
		LCD0_SPI4_CLK_LOW();
		LCD0_SPI4_CLK_HIGH();		
	}
}

在这里插入图片描述
如上图,我们可以看到时钟的低电平时间非常的短,高电平时间很长。从如上代码我们也能看出来,是因为时钟高低电平只有一条指令,基本已经是最短的了,高电平持续期间还有其他代码运行。
参考一下ST7735的spi时序图:
在这里插入图片描述
在这里插入图片描述
重点看写参数:时钟低电平最低宽度Tshw(15ns),时钟高电平最低宽度Tslw(15ns),时钟最小周期Tscycw(66ns)。我们在实现模拟spi驱动的时候要严格遵循这个时序要求,很明显上面测试到的时序,低电平6ns太短了,需要处理。
简单的方法,在时钟低电平后插入延时,但是会导致整个速度变慢

		LCD0_SPI4_CLK_LOW();
		__NOP();
		LCD0_SPI4_CLK_HIGH();	

优化第一步:
把时钟拉低的时间移动到前面来,整个执行时间和代码并没有增加:

static void Spi4_WriteByte(uint8_t d)
{
	uint8_t i,spidat;
	spidat = d;
	for(i=0; i<8; i++)			
	{  
		LCD0_SPI4_CLK_LOW();
		if( (spidat&0x80)!=0 ) 
			LCD0_SPI4_MOSI_HIGH();
		else 
			LCD0_SPI4_MOSI_LOW();
		spidat <<= 1;
		LCD0_SPI4_CLK_HIGH();		
	}
}

在这里插入图片描述
由于编译器的优化(而且一定要开优化(O1以上),速度才会快,开与不开大约相差3倍),从低电平到高电平之间的时间似乎并没有完全和代码一致,但是宽度已经变成14ns了,已经能基本满足我们的需求了。
好了,到这里,我们把基本时序调整完成,发送一个字节大约需要714ns,此时发送一帧数据(320x240 16bit)大约需要110ms。
感觉速度还是不够,如何来进一步优化?
乍一看,貌似也没有多少优化空间了(那几个宏定义的操作已经是最优实现,可以不考虑)?那还能咋整?
细节决定成败,请记住我们用的是32bit mcu,代码中的i,spidat两个变量是采用8bit定义的,习惯了单片机的内存紧张,尽量用最小单位来定义了。
优化第二步,将变量i定义为32bit,看看发生了什么变化:

uint32_t i;

在这里插入图片描述
看看效果,一个字节的发送时间从714ns降低到628ns,一帧的数据时间降低到94.16ms。是不是很惊奇,说明在32bit的mcu上,效率最高的内存访问还是32bit的方式,在需要极度时间优化的时候请正确使用。
优化第三步,将变量spidat也定义为32bit:
最终全部代码如下:

static void Spi4_WriteByte(uint8_t d)
{
	uint32_t i,spidat;
	spidat = d;
	for(i=0; i<8; i++)			
	{  
		LCD0_SPI4_CLK_LOW();
		if( (spidat&0x80)!=0 ) 
			LCD0_SPI4_MOSI_HIGH();
		else sudu
			LCD0_SPI4_MOSI_LOW();
		spidat <<= 1;
		LCD0_SPI4_CLK_HIGH();		
	}
}

在这里插入图片描述
这个优化我们很容易忽略,因为spi传输8bit数据的时候,我们是msb在前,要先判断最高位,惯性的就用了8bit来表示数据,其实我们是需要判断第8bit,而不是一定需要8bit数据长度,在代码中,用32bit也是一样的效果
从图中实际测试数据来看,我们的字节传输时间再次下降到574ns,一帧数据86.09ms,提升还是比较明显。
综合来看,仅仅通过优化两个变量类型的定义,一帧数据的传输时间从110ms->94.16ms->86.09ms,提速约30%,并没有为cpu带来任何影响,也不会多ram开销,效果非常明显。

**************文章为原创,倾注了大量心血,欢迎转载,请注明出处**************

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/709048.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JavaSE】初步认识

目录 【1】Java语言概述 【1.1】Java是什么 【1.2】Java语言重要性 【1.3】Java语言发展简史 【1.4】Java语言特性 【1.5】 Java开发环境安装 【2】初识Java的main方法 【2.1】main方法示例 【2.2】运行Java程序 【3】注释 【3.1】基本规则 【3.2】注释规范 【4】…

ESP32-S2启动异常分析

客户反馈最近一批50块基于ESP32-S2的LoRaWAN gateway&#xff0c;有5块偶尔网络灯能亮&#xff0c;经常不能亮。 反复分析&#xff0c;定位&#xff0c;一个共同现象是用示波器看&#xff0c;串口输出一串信息后再没输出了。因为用了 ESP-ROM:esp32s2-rc4-20191025 Build:Oct …

企业构建知识库方案

AI模型理解误区&#xff1a;百万成本微调垂直行业达模型VS低成本建立企业专属知识库或ai助理_哔哩哔哩_bilibili

vscode关闭调试工具栏

问题描述 项目启动的时候老是蹦出这玩意 很碍眼 解决方案&#xff1a; 设置里搜索 选项改为hidden即可

前端Vue自定义注册界面模版 手机号邮箱账号输入框 验证码输入框 包含手机号邮箱账号验证

前端Vue自定义注册界面模版 手机号邮箱账号输入框 验证码输入框 包含手机号邮箱账号验证 &#xff0c; 下载完整代码请访问uni-app插件市场地址&#xff1a;https://ext.dcloud.net.cn/plugin?id13306 效果图如下&#xff1a;

CSS 备忘录2-动画、渐变、颜色、选择器等

1、背景 background属性是八个属性的简写形式&#xff1a; background-image 指定一个文件或生成的颜色渐变作为背景图片background-position 设置图片的初始位置background-size 指定背景图片的渲染尺寸background-repeat 是否平铺图片ba…

缺少msvcp140.dll丢失该如何解决?

msvcp140.dll是什么东西?相信很多人都遇到过msvcp140.dll这个文件吧?那么为什么一丢失msvcp140.dll电脑软件就会打不开?如果缺失了这个东西会怎么样?小编今天就来给大家详细的说说&#xff0c;其实这些都是一些比较常见的电脑知识&#xff0c;我们是需要去了解一下的。 msv…

Python 利用@property装饰器和property()方法将一个方法变成属性调用

目录 方法一&#xff1a;使用property装饰器 方法二&#xff1a;使用property()创建类属性 在创建实例属性时&#xff0c;如果直接把实例属性暴露出去&#xff0c;虽然写起来简单&#xff0c;但是存在一些风险&#xff0c;比如实例属性可以在外部被修改。 为了限制外部操作&a…

springboot集成openfeign,集成Histric

一、Feign简介 Feign是一个声明式的伪Http客户端&#xff0c;它使得写Http客户端变得更简单。使用Feign&#xff0c;只需要创建一个接口并注解。它具有可插拔的注解特性&#xff0c;可使用Feign 注解和JAX-RS注解。Feign支持可插拔的编码器和解码器。Feign默认集成了Ribbon&…

Echarts入门(SpringBoot + Vue)

一、Echarts简介 代码已上传至码云:echarts_boot: echarts使用demo ECharts是一个使用 JavaScript 实现的"数据可视化"库, 它可以流畅的运行在 PC 和移动设备上 什么是数据可视化? 也就是可以将数据通过图表的形式展示出来&#xff0c; Echarts官网:Apache ECh…

9-如何获取N维数组元素?【视频版】

目录 问题视频解答 问题 视频解答 点击观看&#xff1a; 9-如何获取N维数组元素&#xff1f;

基于 Opencv python实现批量图片去黑边—裁剪—压缩软件

简介 批量处理图片文件&#xff0c;批量提取GIF图片中的每一帧&#xff0c;具有范围裁剪、自动去除黑/白边、调整大小、压缩体积等功能。 先看一些软件的界面&#xff0c;是基于Tkinter写的GUI 裁剪等功能基于Opencv 下载 我添加了处理GIF的github&#xff1a; 原作者的gith…

基于Ant DesignPro Vue + SpringBoot 前后端分离 - 后端微服化 + 接口网关 + Nacos

基于Ant DesignPro Vue SpringBoot 前后端分离 - 后端微服化 接口网关 Nacos 通过Ant DesignPro Vue SpringBoot 搭建的后台管理系统后&#xff0c;实现了前后端分离&#xff0c;并实现了登录认证&#xff0c;认证成功后返回该用户相应权限范围内可见的菜单。 后端采用Spri…

一、枚举类型——新特性(将 switch 作为表达式)

switch 一直以来都只是一个语句&#xff0c;并不会生成结果。 JDK 14 使得 switch 还可以作为 一个表达式来使用&#xff0c;因此它可以得到一个值&#xff1a; SwitchExpression.java public class SwitchExpression {static int colon(String s) {var result switch (s) {ca…

基于单片机的智能点滴速度输液液体检测

功能介绍 以51单片机作为主控系统&#xff1b;显示液位&#xff0c;滴数&#xff0c;温度等信息&#xff1b;通过水位传感器检测当前药瓶是否有水&#xff1b;通过滴速传传感器利用单片机定时器计算当前滴速&#xff1b;通过DS18B20温度传感器采集当前药液温度&#xff0c;继电…

【前端】JS语法——数据类型转换

一、字符串&#xff08;里面必须数字&#xff09;转换为数字类型&#xff08;number&#xff09; 1、强制转换&#xff1a;(parseInt()、parseFloat()、Number())&#xff1b; 2、隐式转换&#xff08;number[-/*%]string&#xff09;&#xff1b; <script>let s &qu…

红米K60刷入MIUI.EU安装面具magisk与root教程

文章目录 前言1.解锁BootLoader2.刷入Recovery3.刷入EU的ROM包4.刷入magisk面具后话 前言 教程大概就是四步&#xff0c;解锁&#xff0c;刷入rec&#xff0c;刷入系统&#xff0c;刷入面具&#xff0c;跟着教程走即可。这次是刷机方式&#xff1a;卡刷&#xff08;Recovery&a…

SELECT * 会导致查询效率低的原因

SELECT * 会导致查询效率低的原因 前言一、适合SELECT * 的使用场景二、SELECT * 会导致查询效率低的原因2.1、数据库引擎的查询流程2.2、SELECT * 的实际执行过程2.3、使用 SELECT * 查询语句带来的不良影响 三、优化查询效率的方法四、总结 前言 因为 SELECT * 查询语句会查…

PCL可视化 3D点云PCD文件

工具安装 sudo apt install pcl-tools 启动命令&#xff1a; pcl_viewer 000000.pcd

chatgpt赋能python:在Python官网上下载Python:一位有10年Python编程经验的工程师分享

在Python官网上下载Python&#xff1a;一位有10年Python编程经验的工程师分享 Python是如今最受欢迎的编程语言之一。它是一种易学易用、具有广泛用途的开源语言。如果您刚开始使用Python&#xff0c;或者想要更新到最新版本的Python&#xff0c;Python官网是一个很好的起点。…