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
相关产品推荐
相关产品推荐

