news 2026/9/26 17:39:20

HC32F460 DMA的链式传输(SPI从机+DMA发送/接收)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
HC32F460 DMA的链式传输(SPI从机+DMA发送/接收)

1、SPI从机+DMA接收

SPI从机的接收机制与串口接收类似(参考前面文章),在使用DMA进行数据接收时,其配置方式也较为相似,因此不再重复说明DMA的具体配置过程。

由于SPI外设本身不提供接收超时中断机制,因此无法依赖超时信号来判断一次接收操作是否完成。为了解决这一问题,本DEMO中采用了片选信号(CS)的上升沿中断作为接收完成的判断依据。

具体实现逻辑如下:

  • SPI片选信号(CS)被配置为上升沿触发的外部中断源;
  • 当主机完成数据发送、释放片选信号后,CS引脚由低变高,触发上升沿中断;
  • 在该中断服务程序中,先判断当前已接收的数据长度,然后对DMA通道进行重置或重新使能,以便准备下一次接收操作;

这种方式有效地利用了SPI通信的物理特性,即片选信号为低时通信正在进行,为高时通信结束,从而实现了对接收完成事件的判断。

片选信号中断配置以及中断复位函数代码如下:

//片选中断配置,上升沿中断,用于指示通信结束 void SPI3_CS_Intterupt_Init(void) { stc_extint_init_t stcExtIntInit; stc_irq_signin_config_t stcIrqSignConfig; stc_gpio_init_t stcGpioInit; /* GPIO config */ (void)GPIO_StructInit(&stcGpioInit); stcGpioInit.u16ExtInt = PIN_EXTINT_ON; (void)GPIO_Init(SPI3_SS0_PORT, SPI3_SS0_PIN, &stcGpioInit); /* ExtInt config */ (void)EXTINT_StructInit(&stcExtIntInit); stcExtIntInit.u32Filter = EXTINT_FILTER_ON; stcExtIntInit.u32FilterClock = EXTINT_FCLK_DIV8; stcExtIntInit.u32Edge = EXTINT_TRIG_RISING; (void)EXTINT_Init(SPI3_SS0_EXTINT_CH, &stcExtIntInit); /* IRQ sign-in */ stcIrqSignConfig.enIntSrc = SPI3_SS0_INTSRC; stcIrqSignConfig.enIRQn = SPI3_CS_IRQn; stcIrqSignConfig.pfnCallback = &BSP_SPI_Slave_IRQHandler; (void)INTC_IrqSignIn(&stcIrqSignConfig); /* NVIC config */ NVIC_ClearPendingIRQ(stcIrqSignConfig.enIRQn); NVIC_SetPriority(stcIrqSignConfig.enIRQn, DDL_IRQ_PRIO_DEFAULT); NVIC_EnableIRQ(stcIrqSignConfig.enIRQn); } //从机片选中断处理 void BSP_SPI_Slave_IRQHandler(void) { if (SET == EXTINT_GetExtIntStatus(SPI3_SS0_EXTINT_CH)) { SPI3_Recv_Lenth = SPI3_RX_BUF_SIZE - DMA_GetTransCount(SPI3_RX_DMA_UNIT, SPI3_RX_DMA_CH); //获取接收长度 SPI3_Receive_Evt = 1; //置位接收完成事件标志 DMA_SetDestAddr(SPI3_RX_DMA_UNIT, SPI3_RX_DMA_CH, (uint32_t)&SPI3_RxBuf[0]); //设置下次开始接收的地址 DMA_SetTransCount(SPI3_RX_DMA_UNIT, SPI3_RX_DMA_CH, SPI3_RX_BUF_SIZE); //设置下次DMA传输长度 EXTINT_ClearExtIntStatus(SPI3_SS0_EXTINT_CH); //清除中断标志 } }

2、SPI从机+DMA发送

在SPI从机的设计中,数据的发送过程是由主机完全控制的。从机无法预知主机何时开始读取数据,也无法确定主机需要接收多少数据。因此,从机必须始终保持数据就绪状态,并确保DMA发送通道随时准备响应主机的读取请求。

SPI从机内部通常包含两个关键寄存器:发送数据寄存器(DR) 和 移位寄存器(Shift Register)。当这两个寄存器均为空时,写入发送数据寄存器的数据会立即被转移到移位寄存器中,从而触发“发送寄存器空”事件,进而可能再次通过DMA向发送数据寄存器写入新数据。这种行为虽然不会导致数据覆盖,但在通信尚未开始前,从机并不知道主机希望读取哪些数据。因此,提前填充到这两个寄存器中的数据可能是不合适的,甚至会导致错误的数据被发送出去。

为了解决这个问题,通常需要主机与从机之间进行一定的协议协商:

  • 主机先发送命令帧,通知从机需要执行的操作或读取的数据类型。
  • 从机接收到命令后,解析并准备相应的数据,并在内部完成数据缓冲。
  • 为了确保数据正确性,从机需清空发送数据寄存器和移位寄存器中的旧数据,但由于SPI外设没有专门用于清除移位寄存器的配置项,因此通常的做法是先关闭SPI外设再重新启用,以清空内部状态。
  • 最后,主机发起正式的数据读取操作,此时从机已准备好正确的数据,可以确保数据传输的准确性。

因此SPI从机发送的DMA通道,在数据准备完成之后,配置DMA的地址与长度,然后重启SPI外设。

此部分代码如下:

//SPI从机,需要在主机未读取数据之前,将数据准备好,待主机发起读取数据。 void SPI_Slave_Load_1st_Data(uint8_t *pu8Data) { DMA_SetSrcAddr(SPI3_TX_DMA_UNIT, SPI3_TX_DMA_CH, (uint32_t)(pu8Data)); // 设置DMA目的地址 DMA_SetTransCount(SPI3_TX_DMA_UNIT, SPI3_TX_DMA_CH, SPI3_TX_BUF_SIZE); // 设置DMA传输长度 CLR_REG32_BIT(CM_SPI3->CR1, SPI_CR1_SPE);//注意需要将SPI关闭再使能,才可以重新加载移位寄存器的数据 SET_REG32_BIT(CM_SPI3->CR1, SPI_CR1_SPE); }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/26 16:52:17

26、网络连接与安全全解析

网络连接与安全全解析 在当今数字化时代,网络连接和网络安全是我们日常使用计算机时不可忽视的重要方面。下面我们将详细探讨网络连接相关文件、网络安全的多个要点,包括密码安全、远程登录以及防火墙配置等内容。 网络连接相关文件问答 首先,我们来看一些关于连接互联网…

作者头像 李华
网站建设 2026/9/26 10:19:29

2025.12.16 HSRP双机热备

1)拓扑图2)实验步骤2.1 PC机配置PC0 PC1PC22.2 路由器配置2.3 交换机配置SW3 SW1SW22.4 测试PC0 ping PC1PC0 ping PC2

作者头像 李华
网站建设 2026/9/26 19:03:14

万全智能RFID模块设备他们产品档次怎么样

万全智能的RFID模块设备在行业内属于中高端档次,其产品特点主要体现在以下方面: 技术性能 读写能力 支持多协议兼容(如EPC Class1 Gen2、ISO 18000-6C等),读写距离可达10米以上(超高频型号)&…

作者头像 李华
网站建设 2026/9/27 1:08:09

RuoYi v1.2.0 全端开发神器:让多端适配从未如此简单!

一、 引言:为什么选择 RuoYi APP 框架?在移动应用开发领域,跨平台适配一直是开发者的噩梦。传统方案需为 iOS、Android、小程序等多端单独开发,成本高、效率低。而 RuoYi v1.2.0 基于 UniAppUniUI 的轻量级框架,彻底打…

作者头像 李华
网站建设 2026/9/26 12:02:33

少儿编程Scratch3.0教程——03 外观积木(基础知识)

在前面的两节课中,我们一起学习了 动作积木的基础知识 和 项目练习 ,这节课我们就开始来学习第二种积木类型,外观积木。其实在上节课的项目练习中,我们就已经提前使用过外观积木中的说话积木,这节课我就带你来看看除了…

作者头像 李华
网站建设 2026/9/25 21:17:58

libxslt XSLT转换库:鸿蒙PC上的XML转换工具

ohos-libxslt 是为 OpenHarmony 平台编译的 libxslt XSLT 转换库。本文档详细介绍如何在鸿蒙PC上安装和使用官方适配完成的 libxslt 库,包括 HNP 包的打包、安装和使用方法。 📋 目录 一、项目概述二、为什么需要 HNP 包三、HNP 包打包方法四、安装与使…

作者头像 李华