硬汉嵌入式论坛

 找回密码
 立即注册
查看: 616|回复: 3
收起左侧

[SPI/QSPI] CUBE MX+STM32H743+SPI6+BDMA无法进入SPI中断回调函数

[复制链接]

6

主题

10

回帖

28

积分

新手上路

积分
28
发表于 2025-1-3 16:53:39 | 显示全部楼层 |阅读模式
问题:CUBE MX+STM32H743+SPI6+BDMA无法进入SPI中断回调函数HAL_SPI_TxCpltCallback

BDMA仅可以范围地址0x3800 0000
#define __ATTR_RAM_D3   __attribute__ ((section(".RAM_D3"))) __attribute__ ((aligned (4)))
uint8_t g_ucBufHead10 __ATTR_RAM_D3;
uint8_t ucaSpiData10[DBUF_NUM][SPI_PACKET_LEN] __ATTR_RAM_D3;

发现无法进入SPI6_IRQHandler();
发现时钟SPI6的时钟设置为了80MHZ,STM32的SPI外设可用作通讯的主机及从机,支持最高的SCK时钟频率为fpclk/2
修改后改为40MHZ;STM32H7的主频400MHz时,SPI1, 2, 3最高通信时钟是100MHz,而SPI4, 5, 6是50MHz。

经调试发现可以进入SPI6中断了,但是没有进入HAL_SPI_RxCpltCallback

检查 SPI_SR 寄存器状态:
· RXNE(接收缓冲区非空标志)
· OVR(溢出标志)
uint32_t spi_status = SPI6->SR;
printf("SPI6->SR: 0x%08lX\n", spi_status);

调试打印出:
SPI6->SR: 0x0001E007
加上一些清除标志位的可以进入一次SPI回调函数。
void SPI6_IRQHandler(void)
{
    /* USER CODE BEGIN SPI6_IRQn 0 */
    printf("SPI6 Interrupt Triggered\n");

    // 检查 RXNE 标志
    if (__HAL_SPI_GET_FLAG(&hspi6, SPI_FLAG_RXNE))
    {
        printf("RXNE Flag Set\n");
        HAL_SPI_RxCpltCallback(&hspi6);
    }

    // 清除 OVR 标志
    if (__HAL_SPI_GET_FLAG(&hspi6, SPI_FLAG_OVR))
    {
        printf("Clearing OVR Flag\n");
        __HAL_SPI_CLEAR_OVRFLAG(&hspi6);
    }

    // 清除 MODF 标志
    if (__HAL_SPI_GET_FLAG(&hspi6, SPI_FLAG_MODF))
    {
        printf("Clearing MODF Flag\n");
        __HAL_SPI_CLEAR_MODFFLAG(&hspi6);
    }
    /* USER CODE END SPI6_IRQn 0 */
    HAL_SPI_IRQHandler(&hspi6);
    /* USER CODE BEGIN SPI6_IRQn 1 */
    uint32_t spi_status = SPI6->SR;
    printf("SPI6->SR: 0x%08lX\n", spi_status);
    /* USER CODE END SPI6_IRQn 1 */
}









回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115488
QQ
发表于 2025-1-4 06:55:22 | 显示全部楼层
1、方便的话,完整的程序配置代码看下
2、函数HAL_SPI_IRQHandler(&hspi6);里面各种标志都处理了,不需要用户额外添加,直接检查各种回调就行
回复

使用道具 举报

6

主题

10

回帖

28

积分

新手上路

积分
28
 楼主| 发表于 2025-1-6 11:23:11 | 显示全部楼层
// 放置在 RAM_D3 的变量
__attribute__((section(".sram3"))) uint8_t g_ucBufTail;
__attribute__((section(".sram3"))) uint8_t g_ucBufHead;
__attribute__((section(".sram3"))) uint8_t ucaSpiData[1024];
已解决:cubeIDE定义了如上数据,但是发现mep文件里面定义的数据不在D3域,
.sram3          0x24000010     0x1968 load address 0x080070b0
.sram3         0x24000010     0x1968 ./Core/Src/main.o
                0x24000010                g_ucBufTail
                0x24000011                g_ucBufHead
                0x24000014                ucaSpiData
                0x24001978                        . = ALIGN (0x4)     .sram3应该为0X38000000
查看链接脚本(.ld 文件)发现没有RAM_D3段的分配。
/* Define output sections */
SECTIONS
{
  /* The startup code goes first into FLASH */
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >FLASH
.....
增加段的分配,问题解决
/* 设置段的分配 */
SECTIONS
{
    /* SRAM3 段分配到 RAM_D3 */
    .sram3 :
    {
        . = ALIGN(4);
        *(.sram3*) /* 将所有带有 .sram3 段标记的内容放入 */
        . = ALIGN(4);
    } >RAM_D3
}
再次编译查看mep文件, .sram3 正确映射到 0x38000000
.sram3          0x38000000     0x1968
                0x38000000                        . = ALIGN (0x4)
*(.sram3*)
.sram3         0x38000000     0x1968 ./Core/Src/main.o
                0x38000000                g_ucBufTail
                0x38000001                g_ucBufHead
                0x38000004                ucaSpiData
                0x38001968                        . = ALIGN (0x4)
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115488
QQ
发表于 2025-1-7 06:52:53 | 显示全部楼层
沉思静学 发表于 2025-1-6 11:23
// 放置在 RAM_D3 的变量
__attribute__((section(".sram3"))) uint8_t g_ucBufTail;
__attribute__((sec ...

谢谢告知最终原因
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-4-28 16:35 , Processed in 0.425216 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表