【国产mcu填坑篇】华大单片机(小华半导体)一、SPI的DMA应用(发送主机)HC32L136

  • 最近需要用华大的hc32l136的硬件SPI+DMA传输,瞎写很久没调好,看参考手册,瞎碰一天搞通了。。。

    • 先说下我之前犯的错误,也是最宝贵的经验,供参考
      • 没多看参考手册直接写(即使有点烂仍然提供了最高的参考价值。。。),重点看SPIDMAC章节
      • 错误使用了软件触发传输,测到的现象是前两个字节可以正确发送,后面的无论是发送数量和数据都对不上了,误以为软件触发可用,自己的配置有问题,实际测试软件触发和规格书讲的一样,是不可用的或者说是不可靠的
    • 再说下正确的使用方式,文末会粘上测试代码
      • 关键点就一个,触发方式不要选DmaSWTrig软件触发(至于最后实例能用的这个,从软件的角度看还是软件触发,但官方的角度似乎不认为这是软件触发,或许是软件触发SPI硬件再触发DMA所以叫硬件触发?不管也罢,,,)
  • 特别注意:DMA可能存在硬件bug,在发送的最后一个字节DMA发送完成标记位(硬件置位)有50%概率提前置位,如果CS拉高太快(优化等级太高并且直接操作寄存器来操作CS)会概率导致最后一个字节异常,可以在拉高CS前加一个很小的延时解决,我单独测试DMA时没有异常,随便打开一个定时器中断(频率越高越容易)就可以碰到了,错误时序如下:
    在这里插入图片描述

  • 语文课兴许没及格,下面是参考手册的一些相关描述,没看明白:

  1. 先讲SPI支持软硬件访问
    在这里插入图片描述
    2.再讲只支持硬件块传输模式,且SPI和系统时钟不同频时不支持硬件触发(官方对软件/硬件触发的解释不是很到位,至少和我理解的不太一样)
    在这里插入图片描述
  2. 但是spi时钟和系统时钟必然是不同频的,那硬件触发到底能不能用呢?
    在这里插入图片描述
  3. 再看,所谓的软件/硬件DMA传输模式就是软件/硬件请求方式不同,似乎哪个也不支持了。。。软硬件触发和软硬件传输似乎没有关系?
    在这里插入图片描述
  • 最后,还是实践出真知。。。
  • 测试程序参考,每200ms用SPI+DMA发送24个字节:
#define SPI_HANDLE M0P_SPI1
#define DMA_HANDLE DmaCh1uint8_t data_tx_test[24] =
{0x11,0x22,0x23,0x44,0x55,0x66,0x77,0x88,0x11,0x22,0x23,0x44,0x55,0x66,0x77,0x88,0x11,0x22,0x23,0x44,0x55,0x66,0x77,0x88,
};//主要是CS/CLK/MOSI三个脚,不相干引脚忽略即可
static void App_GpioInit(void)		
{stc_gpio_cfg_t           stcPortCfg;DDL_ZERO_STRUCT(stcPortCfg);							//结构体初始化清零Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); //GPIO 外设时钟使能stcPortCfg.enDrv = GpioDrvH;stcPortCfg.enDir  = GpioDirOut;Gpio_Init(LCD_BK_PORT, LCD_BK_PIN, &stcPortCfg);  Gpio_Init(LCD_CS_PORT, LCD_CS_PIN, &stcPortCfg);  Gpio_SetAfMode(LCD_CS_PORT, LCD_CS_PIN,GpioAf1); 				//CSGpio_Init(LCD_RESET_PORT, LCD_RESET_PIN, &stcPortCfg);  Gpio_Init(LCD_WR_PORT, LCD_WR_PIN, &stcPortCfg);  Gpio_Init(LCD_SCK_PORT, LCD_SCK_PIN, &stcPortCfg);  Gpio_SetAfMode(LCD_SCK_PORT, LCD_SCK_PIN,GpioAf1);  			//CLKGpio_Init(LCD_SDA_PORT, LCD_SDA_PIN, &stcPortCfg);  Gpio_SetAfMode(LCD_SDA_PORT, LCD_SDA_PIN,GpioAf1);  			//MOSI	
}static void App_SPIInit(void)
{stc_spi_cfg_t  SpiInitStruct;Sysctrl_SetPeripheralGate(SysctrlPeripheralSpi1,TRUE);//SPI0模块配置:主机SpiInitStruct.enSpiMode = SpiMskMaster;   		//配置位主机模式SpiInitStruct.enPclkDiv = SpiClkMskDiv2;  		//波特率:fsys/2SpiInitStruct.enCPOL    = SpiMskcpolhigh;  		//极性SpiInitStruct.enCPHA 	= SpiMskCphasecond; 	//第二电平采样Spi_Init(SPI_HANDLE, &SpiInitStruct);Spi_FuncEnable(SPI_HANDLE,SpiMskDmaTxEn);		//这里只使用了发送功能
}static void App_DmaCfg(void)
{ stc_dma_cfg_t stcDmaCfg;Sysctrl_SetPeripheralGate(SysctrlPeripheralDma,TRUE); 			//打开DMA时钟DDL_ZERO_STRUCT(stcDmaCfg);stcDmaCfg.enMode =  DmaMskBlock;                           		//选择块传输stcDmaCfg.u16BlockSize = 1;                             		//块传输个数stcDmaCfg.u16TransferCnt = 24;                    				//块传输次数,一次传输数据大小为 块传输个数*BUFFER_SIZEstcDmaCfg.enTransferWidth = DmaMsk8Bit;                   		//传输数据的宽度,此处选择字(8Bit)宽度stcDmaCfg.enSrcAddrMode = DmaMskSrcAddrInc;                		//源地址自增stcDmaCfg.enDstAddrMode = DmaMskDstAddrFix;                		//目的地址固定stcDmaCfg.enDestAddrReloadCtl = DmaMskDstAddrReloadEnable;		//使能重新加载传输目的地址stcDmaCfg.enSrcAddrReloadCtl = DmaMskSrcAddrReloadEnable;		//使能重新加载传输源地址stcDmaCfg.enSrcBcTcReloadCtl = DmaMskBcTcReloadEnable;			//使能重新加载BC/TC值stcDmaCfg.u32SrcAddress = (uint32_t)&data_tx_test[0]; 			//指定传输源地址stcDmaCfg.u32DstAddress = (uint32_t)&(M0P_SPI1->DATA);    		//指定传输目的地址stcDmaCfg.enRequestNum = DmaSPI1TXTrig;                        	//设置为硬件触发stcDmaCfg.enTransferMode = DmaMskOneTransfer;              		//dma只传输一次,DMAC传输完成时清除CONFA:ENS位stcDmaCfg.enPriority = DmaMskPriorityFix;                  		//各通道固定优先级,CH0优先级 > CH1优先级Dma_InitChannel(DMA_HANDLE,&stcDmaCfg);                        	//初始化dma通道0Dma_Enable();//Dma_EnableChannel(DMA_HANDLE);								//开启通道即开启一次发送
}void dma_test(void)
{en_dma_stat_t ste;while(1){ delay1ms(200);M0P_SPI1->SSN = FALSE;Dma_EnableChannel(DMA_HANDLE);								//启动传输,所以这种方式到底算软件还是硬件??ste = Dma_GetStat(DMA_HANDLE);while(ste != DmaTransferComplete){ste = Dma_GetStat(DMA_HANDLE);}delay10us(1);												//!!!这个延时是必要的,防止数据多时上面的等待不能有效判断最后一个字节M0P_SPI1->SSN = TRUE;}
}void demo(void)
{App_GpioInit();App_DmaCfg();App_SPIInit();dma_test();
}
  • 实测SPI主机发送ok:
    在这里插入图片描述

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

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

相关文章

iis配置asp网站

1.安装IIS的ASP win7和win10都是一样的 下安装IIS时ASP一般被默认不选中的状态,因此需要打开IIS检查功能视图栏中是否存在ASP选项,若没有则需要从控制面板->程序和 功能->打开或关闭Windows功能->Internet信息服务->万维网服务->应用程序…

数环通更新动态|新增连接器抖店自建、叮当OKR、千易ERP、货拉拉

更新快速预览 新增连接器4个 抖店自建 叮当OKR 千易ERP 货拉拉 应用更新2个 百度统计(2) 旺店通(1) 应用连接器 新增连接器 1.抖店自建 抖店是抖音官方打造的电商商家实现一站式经营平台,为商家提供全链路服务&#xf…

Selenium定位元素的方法css和xpath的区别

selenium是一种自动化测试工具,它可以通过不同的定位方式来识别网页上的元素,如id、name、class、tag、link text、partial link text、css和xpath。 css和xpath是两种常用的定位方式,它们都可以通过元素的属性或者层级关系来定位元素&#…

MacOS环境下Kali Linux安装及使用指导

Kali Linux是一个开源的、基于Debian的Linux发行版,面向各种信息安全任务,如渗透测试、安全研究、计算机取证和逆向工程,是最先进的渗透测试发行版,它的前身是BackTrack。 1. 我们为什么要用Kali Linux 由于Kali Linux具有以下特…

【脑筋急转弯系列】乒乓球称重问题

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…

FDTD2018a安装问题记录

FDTD2018a安装问题记录 目录问题解决方案 目录 问题 解决方案 电脑名字如果是中文改成英文

全局唯一ID实现方案——雪花算法

全局唯一ID实现方案——雪花算法 雪花算法原理 Snowflake,雪花算法是由Twitter开源的分布式ID生成算法,以划分命名空间的方式将 64-bit位分割成多个部分,每个部分代表不同的含义。而 Java中64bit的整数是Long类型,所以在 Java 中…

数据加密过程和数据加密的方法有哪些?

在信息日益发达的今天,数据安全已成为越来越受到关注的问题。数据加密技术作为保护信息安全的重要手段,对于维护个人隐私、企业机密以及国家安全具有重要意义。希望通过本文的学习,您能够对数据加密有一个全面的认识,并在实际应用…

基于Java的校车管理系统

源码跳转链接: 基于java的校车管理系统 基于Java的校车管理系统 摘要一、绪论1.1设计目的与意义1.2需求分析1.3用户、管理员用例图 二、系统总体设计2.1系统模块设计2.2数据库分析与设计2.2.1数据库概念结构设计2.2.2表结构设计2.2.3数据库连接池原理 2.3系统后台设计与分析2.…

DAY9--learning english

一、积累 1.compilation 2.mow lawn 3.vendor 4.transparent 5. perpetual 6. extinct 7. thirst 8.defy 9.resentment 10.ample 11.restore 12. firm 13. coincidence 14. spoil 15. astonish 16. blade 17.pierce 18. indigenous 19.perspective 20.vibrant 二、练习 1.spe…

关于枚举问题

一、abc算法 #include "cstdio" int main(){int a,b,c;//定义名字为a,b,c的三个整型变量for(a0;a<9;a){ // a的初始值是0&#xff0c;当a满足a<9的时候&#xff0c;可以执行循环体 //自增的意思for(b0;b<9;b){for(c0;c<9;c){//abcbcc532//abc--&g…

Wpf 使用 Prism 实战开发Day11

仓储&#xff08;Repository&#xff09;/工作单元&#xff08;Unit Of Work&#xff09;模式 仓储&#xff08;rep&#xff09;:仓储接口定义了对实体类访问数据库及操作的方法。它统一管理数据访问的逻辑&#xff0c;并与业务逻辑层进行解耦。 简单的理解就是对访问数据库的一…

【设计模式之美】重构(三)之解耦方法论:如何通过封装、抽象、模块化、中间层等解耦代码?

文章目录 一. “解耦”概述二. 如何给代码“解耦”&#xff1f;1. 封装与抽象2. 中间层2.1. 引入中间层能**简化模块或类之间的依赖关系**。2.2. 引入中间层可以起到过渡的作用&#xff0c;能够让开发和重构同步进行&#xff0c;不互相干扰。 3. 模块化4. 其他设计思想和原则4.…

[晓丽紫]每日论文分享(有中文摘要,源码或项目地址)--大模型,扩散模型...

专属领域论文订阅 关注{晓理紫|小李子}&#xff0c;每日更新论文&#xff0c;如感兴趣&#xff0c;请转发给有需要的同学&#xff0c;谢谢支持 分类: 大语言模型LLM视觉模型VLM扩散模型视觉导航具身智能&#xff0c;机器人强化学习开放词汇&#xff0c;检测分割 [晓丽紫]每日论…

基于YOLOv7的学生课堂行为检测,引入BRA注意力和多种IoU改进提升检测能力

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文摘要&#xff1a;介绍了学生课堂行为检测&#xff0c;并使用YOLOv7进行训练模型&#xff0c;以及引入BRA注意力和多种IoU改进来提升检测能力 目录 1.SCB介绍 ​编辑 2.如何提高YOLOv7课堂行为检测能力 2.1 训练基于YOLOv7模型的…

C++ 有需求 需要对数字向下取整 int和 double 混淆 已解决

在项目使用中。 原本以为 直接 ceil(13/ 2) 3 但是实际是错误的。 需要 是 ceil(5.0 / 2) double 才能向上取整。结果有大佬 直接使用两种办法 能解决问题。 由于传入的参数和返回的参数都是double&#xff0c;所以需要手动转化 #include <bits/stdc.h> using name…

HANA:传参,游标(Cursor)应用,FOR循环,解决存储表内存溢出的问题

作者 idan lian 如需转载备注出处 1.应用场景 最近项目上用HANA开发的比较多&#xff0c;之前我是bw用的比较多&#xff0c;就不会有这种问题。我们这个项目很多都是开发的计算视图&#xff0c;但最近做acdoca的逻辑时&#xff0c;计算视图在生产环境执行的时候报错&#xf…

flink 1.18 sql gateway /sql gateway jdbc

一 sql gateway 注意 之所以直接启动gateway 能知道yarn session 主要还是隐藏的配置文件&#xff0c;但是配置文件可以被覆盖&#xff0c;多个session 保留最新的applicationid 1 安装flink &#xff08;略&#xff09; 2 启动sql-gatway(sql-gateway 通过官网介绍只能运行…

YOLOv8改进 | 检测头篇 | 利用DBB重参数化模块魔改检测头实现暴力涨点 (支持检测、分割、关键点检测)

一、本文介绍 本文给大家带来的改进机制是二次创新的机制,二次创新是我们发表论文中关键的一环,本文给大家带来的二次创新机制是通过DiverseBranchBlock(DBB)模块来改进我们的检测头形成一个新的检测头Detect_DBB,其中DBB是一种重参数化模块,其训练时采用复杂结构,推理时…

#AIGC##LLM##RAG# RAG:专补LLMs短板_减少LLM幻觉并多模态/RAG 技术最新进展

RAG技术&#xff0c;即检索增强生成&#xff0c;标志着自然语言处理领域的重大进展。通过整合先前知识&#xff0c;它提升了大型语言模型的性能&#xff0c;广泛应用于多模态领域和垂直行业。本文深入探讨了RAG技术的演进历程、技术发展、LLMs问题及其解决方案&#xff0c;为读…