You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

dsPIC33CK64MP505的SPI2音频接收中断无法触发问题求助

问题分析与解决方案

结合你描述的现象(轮询正常、手动置位SPI2IF能进入ISR),问题核心出在音频模式下SPI中断触发条件的配置逻辑以及寄存器配置顺序上,以下是具体排查点和修复方案:

1. 音频模式下的中断掩码选择错误

当AUDEN=1(音频模式启用)且ENHBUF=1(增强型缓冲区启用)时,24位左对齐音频数据的接收完成中断,需要通过SPI2IMSKHbits.RXWIEN(接收字中断使能)来触发,而非你当前使用的SPI2IMSKLbits.SPIRBFEN。

SPIRBFEN是针对单字节缓冲区满的中断使能,而音频模式下SPI是按完整的24位字来接收的,只有当整字(SPI2BUFH+SPI2BUFL)接收完成后,才会触发RXWIF(接收字中断标志),进而触发SPI2全局中断。你之前尝试过RXWIEN但可能因其他配置冲突未生效。

2. 增强型缓冲区与中断的配置顺序问题

你当前的配置顺序是先开SPI2IE和SPIRBFEN,再开ENHBUF,最后开SPIEN。正确的顺序应该是:

  • 先配置所有SPI核心参数(包括AUDMOD、AUDEN、MODE等)
  • 开启ENHBUF
  • 配置中断优先级、中断掩码
  • 清除中断标志位
  • 最后开启SPIEN和全局中断

错误的顺序可能导致增强型缓冲区的中断逻辑未正确初始化。

3. 遗漏初始中断标志位清除

即使手动置位能进ISR,在开启中断前必须确保IFS7bits.SPI2IF被清零,避免初始状态下的无效中断或标志位异常。


修改后的配置代码

RPINR23bits.SS2R  = 38; // RB6 LRCK
RPINR22bits.SCK2R = 39; // RB7 BCLK
RPINR22bits.SDI2R = 40; // RB8 ADCDAT (SDI)

IEC7bits.SPI2IE      = 0;
SPI2CON1Lbits.SPIEN  = 0;
SPI2CON1H            = 0;

// 清空接收缓冲区
while(!SPI2STATLbits.SPIRBE) { 
    (void) SPI2BUFL; 
    (void) SPI2BUFH; 
}
SPI2STATLbits.SPIROV = 0; // 清除接收溢出标志

// 配置音频模式核心参数
SPI2CON1Hbits.AUDMOD = 1; // 左对齐格式
SPI2CON1Hbits.AUDEN  = 1; // 启用音频模式
SPI2CON1Lbits.MSTEN  = 0; // 从机模式
SPI2CON1Lbits.CKP    = 0; // 时钟极性配置(根据你的音频时钟调整)
SPI2CON1Hbits.FRMPOL = 1; // 帧极性配置
SPI2CON1Lbits.MODE   = 3; // 24位数据映射到32位寄存器

// 开启增强型缓冲区
SPI2CON1Lbits.ENHBUF = 1;

// 配置中断优先级与掩码
IPC7bits.SPI2RXIP    = 4; // 中断优先级
SPI2IMSKHbits.RXWIEN = 1; // 启用接收字中断(音频模式下的正确选择)
IFS7bits.SPI2IF      = 0; // 强制清除初始中断标志

// 开启SPI与全局中断
SPI2CON1Lbits.SPIEN  = 1;
IEC7bits.SPI2IE      = 1;

修改后的中断服务函数

void __attribute__((interrupt, no_auto_psv)) _SPI2Interrupt(void) {
    // 先清除接收字中断标志(SPI2IF是全局中断标志,RXWIF是具体的字接收完成标志)
    SPI2STATLbits.RXWIF = 0;
    IFS7bits.SPI2IF = 0;

    // 读取完整的24位音频数据
    uint16_t high_byte = SPI2BUFH;
    uint8_t low_byte = SPI2BUFL;
    uint32_t audio_data = ((uint32_t)high_byte << 8) | low_byte;

    // 处理音频数据(此处替换为你的左右声道同步逻辑)
    // ...

    // 检查并清除溢出标志
    if(SPI2STATLbits.SPIROV) {
        SPI2STATLbits.SPIROV = 0;
    }
}

关键说明

  • 音频模式下,RXWIF标志会在24位数据完整接收并写入SPI2BUFH/SPI2BUFL后置位,此时才会触发SPI2中断,而非单字节缓冲区满。
  • 增强型缓冲区开启后,SPI会自动处理多字节的字对齐接收,无需手动轮询缓冲区(除非你需要处理溢出)。
  • 确保你的时钟极性(CKP)和帧极性(FRMPOL)与音频数据源的输出完全匹配,这会影响数据接收的正确性,进而间接影响中断触发。

内容的提问来源于stack exchange,提问作者Max Kielland

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 23:07:48