当前位置: 首页 > news >正文

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

  • 最近需要用华大的hc32l136的硬件SPI+DMA传输,瞎写很久没调好,看参考手册,瞎碰一天搞通了。。。
    • 先说下我之前犯的错误,也是最宝贵的经验,供参考
      • 没多看参考手册直接写(即使有点烂仍然提供了最高的参考价值。。。),重点看SPIDMAC章节
      • 错误使用了软件触发传输,测到的现象是前两个字节可以正确发送,后面的无论是发送数量和数据都对不上了,误以为软件触发可用,自己的配置有问题,实际测试软件触发和规格书讲的一样,是不可用的或者说是不可靠的
    • 再说下正确的使用方式,文末会粘上测试代码
      • 关键点就一个,触发方式不要选DmaSWTrig软件触发(至于最后实例能用的这个,从软件的角度看还是软件触发,但官方的角度似乎不认为这是软件触发,或许是软件触发SPI硬件再触发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);}M0P_SPI1->SSN = TRUE;}
}void demo(void)
{App_GpioInit();App_DmaCfg();App_SPIInit();dma_test();
}
  • 实测SPI主机发送ok:
    在这里插入图片描述

相关文章:

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

最近需要用华大的hc32l136的硬件SPIDMA传输,瞎写很久没调好,看参考手册,瞎碰一天搞通了。。。 先说下我之前犯的错误,也是最宝贵的经验,供参考 没多看参考手册直接写(即使有点烂仍然提供了最高的参考价值。…...

【前后端的那些事】treeSelect树形结构数据展示

文章目录 tree-selector1. 新增表单组件2. 在父组件中引用3. 父组件添加新增按钮4. 树形组件4.1 前端代码4.2 后端代码 前言:最近写项目,发现了一些很有意思的功能,想写文章,录视频把这些内容记录下。但这些功能太零碎&#xff0c…...

华为OD机试 - 最长子字符串的长度(二)(Java JS Python C)

题目描述 给你一个字符串 s,字符串 s 首尾相连成一个环形,请你在环中找出 l、o、x 字符都恰好出现了偶数次最长子字符串的长度。 输入描述 输入是一串小写的字母组成的字符串 输出描述 输出是一个整数 备注 1 ≤ s.length ≤ 5 * 10^5s 只包含小写英文字母用例 输入alolob…...

【VRTK】【Unity】【游戏开发】更多技巧

课程配套学习项目源码资源下载 https://download.csdn.net/download/weixin_41697242/88485426?spm=1001.2014.3001.5503 【概述】 本篇将较为零散但常用的VRTK开发技巧集合在一起,主要内容: 创建物理手震动反馈高亮互动对象【创建物理手】 非物理手状态下,你的手会直接…...

Spark 读excel报错,scala.MatchError

Spark3详细报错: scala.MatchError: Map(treatemptyvaluesasnulls -> true, location -> viewfs://path.xlsx, inferschema -> false, addcolorcolumns -> true, header -> true) (of class org.apache.spark.sql.catalyst.util.CaseInsensitiveMap)scala代码…...

【漏洞复现】Office365-Indexs-任意文件读取

漏洞描述 Office 365 Indexs接口存在一个任意文件读取漏洞,攻击者可以通过构造精心设计的请求,成功利用漏洞读取服务器上的任意文件,包括敏感系统文件和应用程序配置文件等。通过利用此漏洞,攻击者可能获得系统内的敏感信息,导致潜在的信息泄露风险 免责声明 技术文章…...

使用Python向RabbitMQ发送JSON数据只需要一个send_json方法

发送JSON数据 通过调用rabbitmq.send_json(channel, user, queueresult)能够更简单的实现发送JSON数据。 生产者 import json import rabbitmq# 建立连接 connection rabbitmq.get_connection()# 创建管道 channel connection.channel()# 创建队列 queue_name "user…...

Gitlab Gitee GitHub 远程仓库显示图片

大家好我是苏麟 , 今天出一期开发之外的如何在远程仓库展示图片 . 以GitLab为例 1.首先我们要把一张图片上传到远程仓库 . 2.第二步,点击图片 3.鼠标右键点击下载左键点击复制连接 4.找到我们要上传的md文件 , 把连接复制到 ( ) 里 , 这样上传md之后就可以看到图片了 . 这期就到…...

JS常用的几种事件

JavaScript常用的几种事件有: 点击事件:当用户点击某个元素时触发,常用于按钮、链接等交互元素。事件名称为"click"。 javascriptbutton.addEventListener(click, function() { alert(按钮被点击了!); }); 鼠标移动事…...

代码随想录算法训练营第一天| 27 移除元素 704 二分查找

目录 27 移除元素 704 二分查找 27 移除元素 快指针遍历&#xff0c;慢指针记录 class Solution { public:int removeElement(vector<int>& nums, int val) {int l 0,r 0;for(;r < nums.size();r){if(nums[r] val){}else{nums[l] nums[r];}}return l;} }; …...

深度生成模型(Deep Generative Models)

什么是机器学习 深度生成模型&#xff08;Deep Generative Models&#xff09;是一类利用深度学习方法生成新样本的模型。这些模型通常被用于生成与训练数据集相似的新数据&#xff0c;例如图像、文本或音频。深度生成模型的两个主要类型是生成对抗网络&#xff08;GANs&#…...

C++(20):vector通过erase,erase_if删除符合条件的元素

C++20前,vector可以通过成员函数erase删除迭代器指定的元素,并返回被删除的下一个元素: iterator erase( iterator pos ); iterator erase( iterator first, iterator last ); 1.删除单个元素 #include <vector> #include <iostream> #include <algorithm&…...

树莓派ubuntu:新增用户

切换到Root用户 sudo -i创建新用户 useradd -m 新用户名设置密码 passwd 新用户名将新用户加入sudo用户组 adduser newname sudo拷贝数据 cp -R /home/旧用户名/* /home/新用户名/查看用户所属组 id 新用户名更改文件所属 sudo chown 新用户名:group /home/新用户名/*gr…...

C //练习 5-14 修改排序程序,使它能处理-r标记。该标记表明,以逆序(递减)方式排序。要保证-r和-n能够组合在一起使用。

C程序设计语言 &#xff08;第二版&#xff09; 练习 5-14 练习 5-14 修改排序程序&#xff0c;使它能处理-r标记。该标记表明&#xff0c;以逆序&#xff08;递减&#xff09;方式排序。要保证-r和-n能够组合在一起使用。 注意&#xff1a;代码在win32控制台运行&#xff0c…...

CAN总线报文格式———标准数据帧

标准数据帧 : 用于节点向外传送数据 标准数据帧由帧起始、仲裁段、控制段、数据段、CRC段、ACK段、帧结束等组成。 一、总线空闲&#xff08;Bus Idle&#xff09; CAN总线空闲时&#xff0c;总线上会输出持续的高电平“1”。当总线空闲时任何连接的单元都可以开始发送新的报…...

DFT中的SCAN、BIST、ATPG基本概念

DFT中的SCAN、BIST、ATPG基本概念 SCAN 定义 扫描路径法是一种针对时序电路芯片的DFT方案&#xff0c;目标是在不影响正常功能的情况下来能够提高可控性和可观测性。 原理 原理是将时序电路可以模型化为一个组合电路网络和带触发器(Flip-Flop&#xff0c;简称FF)的时序电路…...

掌握 Vue 响应式系统,让数据驱动视图(下)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…...

apache、nginx、php 隐藏版本号

apache、nginx、php 隐藏版本号 针对的系统都是CentOS 1、没配置之前 1.1 Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/7.2.24 mod_wsgi/3.4 Python/2.7.5 1.2 Server: nginx/1.16.0 1.3 X-Powered-By&#xff1a;7.2.24 2、配置信息 不知道具体位置&#xff0c;可…...

sqoop的安装与使用

Sqoop是一个用于在hadoop与mysql之间传输数据的工具 Sqoop 环境搭建 (1)上传安装包:sqoop-1.4.6-cdh5.14.2.tar.gz到/opt/software (2)解压安装包:tar -zxf sqoop-1.4.6-cdh5.14.2.tar.gz -C /opt/install/ (3)创建软连接:ln -s /opt/install/sqoop-1.4.6-cdh5.14.2/ /opt/ins…...

【docker】Docker Stack 详细使用及注意事项

一、什么是 Docker Stack Docker Stack 是 Docker Swarm 环境中用于管理一组相关服务的工具。它使得在 Swarm 集群中部署、管理和扩展一组相互关联的服务变得简单。主要用于定义和编排容器化应用的多个服务。以下是 Docker Stack 的一些关键特点&#xff1a; 服务集合&#xf…...

Playwright浏览器上下文全解析:如何用Python实现多账号同时登录测试?

Playwright浏览器上下文全解析&#xff1a;如何用Python实现多账号同时登录测试&#xff1f; 在当今复杂的Web应用生态中&#xff0c;自动化测试工程师经常面临一个核心挑战&#xff1a;如何高效模拟真实用户的多账号并行操作场景&#xff1f;无论是电商平台的促销活动测试、社…...

pose-search:Web端人体姿态识别与动作检索的革新实践

pose-search&#xff1a;Web端人体姿态识别与动作检索的革新实践 【免费下载链接】pose-search x6ud.github.io/pose-search 项目地址: https://gitcode.com/gh_mirrors/po/pose-search 在计算机视觉与Web技术深度融合的今天&#xff0c;pose-search作为一款开源项目&am…...

QT项目实战:zlib数据压缩与解压缩的集成与应用

1. 为什么QT项目需要zlib数据压缩 在开发QT应用程序时&#xff0c;我们经常会遇到需要处理大量数据的场景。比如网络传输中的文件发送、本地日志文件的存储、或者游戏资源包的打包。这时候数据压缩就显得尤为重要了。zlib作为一个轻量级的高效压缩库&#xff0c;可以帮助我们将…...

3个步骤打造个人AI知识库:AnythingLLM浏览器扩展完全指南

3个步骤打造个人AI知识库&#xff1a;AnythingLLM浏览器扩展完全指南 【免费下载链接】anything-llm 这是一个全栈应用程序&#xff0c;可以将任何文档、资源&#xff08;如网址链接、音频、视频&#xff09;或内容片段转换为上下文&#xff0c;以便任何大语言模型&#xff08;…...

AI超分辨率技术突破:OptiScaler实现跨显卡自由体验

AI超分辨率技术突破&#xff1a;OptiScaler实现跨显卡自由体验 【免费下载链接】OptiScaler DLSS replacement for AMD/Intel/Nvidia cards with multiple upscalers (XeSS/FSR2/DLSS) 项目地址: https://gitcode.com/GitHub_Trending/op/OptiScaler 你的显卡是否因厂商…...

知识管理革命:OpenClaw+ollama-QwQ-32B构建个人第二大脑

知识管理革命&#xff1a;OpenClawollama-QwQ-32B构建个人第二大脑 1. 为什么我们需要"第二大脑"&#xff1f; 作为一个长期被信息过载困扰的技术写作者&#xff0c;我每天要处理几十篇技术文档、研究论文和行业动态。最痛苦的不是获取信息&#xff0c;而是如何有效…...

从模型到服务:EasyAnimateV5 API开发完整解决方案

从模型到服务&#xff1a;EasyAnimateV5 API开发完整解决方案 1. 为什么需要API服务化 将AI模型封装为API服务是现代AI应用开发的关键步骤。对于EasyAnimateV5这样的图生视频模型&#xff0c;API化能带来多重价值&#xff1a; 降低使用门槛&#xff1a;非技术用户通过简单接…...

当 AI 开始制造 AI:递归自我提升时代的人类工程师生存指南

1. 核心命题:人类瓶颈的消失与算力主导的新纪元 1.1 递归自我提升的拐点降临 1.1.1 从"人类设计"到"自我迭代"的范式转移 人工智能发展正经历一场深刻的范式革命,其核心特征是从"人类工程师主导设计"向"AI系统自主迭代进化"的根本…...

Python金融数据工程:构建高可靠股票数据管道的3种架构方案

Python金融数据工程&#xff1a;构建高可靠股票数据管道的3种架构方案 【免费下载链接】mootdx 通达信数据读取的一个简便使用封装 项目地址: https://gitcode.com/GitHub_Trending/mo/mootdx 在量化投资和金融数据分析领域&#xff0c;获取稳定、实时的股票数据是每个技…...

如何通过OpCore-Simplify在30分钟内完成黑苹果EFI自动化配置

如何通过OpCore-Simplify在30分钟内完成黑苹果EFI自动化配置 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify OpCore-Simplify是一款专注于自动化OpenC…...