TMS320C6748: McBSP通过CPU中断发送数据与预期不符

Part Number: TMS320C6748

我在学习McBSP的使用时遇到一个问题,我编写了一段验证程序,通过CPU中断触发连续的数据输出,但是运行起来后,只能触发第一次中断,后续就无法继续触发中断了,我怀疑写DXR寄存器的逻辑存在问题,但一直没能解决。能否提供一些关于McBSP使用的样例或者帮忙看一下代码里存在的问题?

验证程序的部分代码如下:

volatile int ximt_flag = 1;

void InterruptInit(void)
{
    // 初始化 DSP 中断控制器
    IntDSPINTCInit();

    // 使能 DSP 全局中断
    IntGlobalEnable();
}

void McBSP0Init(void)
{
    // McBSP0 串行口控制寄存器
    McBSP0Regs.SPCR.bit.FREE=1;
    McBSP0Regs.SPCR.bit.SOFT=0;
    // McBSP0 使能数据自环
    McBSP0Regs.SPCR.bit.DLB=0;

    // 禁用 FRST GRST XRST RRST
    McBSP0Regs.SPCR.bit.FRST=0;
    McBSP0Regs.SPCR.bit.GRST=0;
    McBSP0Regs.SPCR.bit.XRST=0;
    McBSP0Regs.SPCR.bit.RRST=0;

    // McBSP0 管脚控制寄存器
    // 发送帧同步信号由内部采样率生成器输出
    McBSP0Regs.PCR.bit.FSXM=1;
    // 接收帧同步信号外部输入
    McBSP0Regs.PCR.bit.FSRM=0;
    // 发送时钟信号由内部采样率生成器产生
    McBSP0Regs.PCR.bit.CLKXM=1;
    // 接收时钟信号由内部采样率生成器产生
    McBSP0Regs.PCR.bit.CLKRM=1;
    // 内部采样率生成器时钟信号由 McBSP 内部输入时钟产生(内部输入时钟 456MHz)
    McBSP0Regs.PCR.bit.SCLKME=0;
    // 发送帧同步信号低电平有效
    McBSP0Regs.PCR.bit.FSXP=1;
    // 接收帧同步信号低电平有效
    McBSP0Regs.PCR.bit.FSRP=1;
    // 发送数据在时钟信号上降沿采样
    McBSP0Regs.PCR.bit.CLKXP=0;
    // 接收数据在时钟信号下降沿采样
    McBSP0Regs.PCR.bit.CLKRP=0;

    // McBSP0 采样率生成寄存器
    // 采样率生成寄存器自由运行
    McBSP0Regs.SRGR.bit.GSYNC=0;
    // CLKS上升沿产生CLKG和FSG
    McBSP0Regs.SRGR.bit.CLKSP=0;
    // 采样率生成器时钟信号由 McBSP 内部输入时钟产生(内部输入时钟 456MHz)
    McBSP0Regs.SRGR.bit.CLKSM=1;
    // 指定帧周期值(+1)
    McBSP0Regs.SRGR.bit.FPER=0;
    // 指定帧宽度值(+1)
    McBSP0Regs.SRGR.bit.FWID=0;
    // 采样率生成器时钟分频,采用16倍的bit采样,CLKGDV的数值在28.987~30.829之间,取30
    McBSP0Regs.SRGR.bit.CLKGDV=30;

    // McBSP0 接收控制寄存器
    // 多相位帧
    McBSP0Regs.RCR.bit.RPHASE=1;
    // 指定相位 2 接收帧长度(2个字)
    McBSP0Regs.RCR.bit.RFRLEN2=1;
    // 指定相位 2 接收字长度(8 位)
    McBSP0Regs.RCR.bit.RWDLEN2=0;
    // 无压缩 MSB(最高有效位)
    McBSP0Regs.RCR.bit.RCOMPAND=0;
    // 忽略第一个接收帧同步脉冲
    McBSP0Regs.RCR.bit.RFIG=1;
    // 1位接收数据延迟位
    McBSP0Regs.RCR.bit.RDATDLY=1;
    // 指定相位 1 接收帧长度(10 个字)
    McBSP0Regs.RCR.bit.RFRLEN1=0x9;
    // 指定相位 2 接收字长度(16 位)
    McBSP0Regs.RCR.bit.RWDLEN1=0x2;
    // 无数据位倒置
    McBSP0Regs.RCR.bit.RWDREVRS=0;

    // McBSP0 发送控制寄存器
    // 多相位帧
    McBSP0Regs.XCR.bit.XPHASE=1;
    // 指定相位 2 发送帧长度(2个字)
    McBSP0Regs.XCR.bit.XFRLEN2=1;
    // 指定相位 2 发送字长度(8 位)
    McBSP0Regs.XCR.bit.XWDLEN2=0;
    // 无压缩 MSB(最高有效位)
    McBSP0Regs.XCR.bit.XCOMPAND=0;
    // 忽略第一个发送帧同步脉冲
    McBSP0Regs.XCR.bit.XFIG=1;
    // 无发送数据延迟位
    McBSP0Regs.XCR.bit.XDATDLY=0;
    // 指定相位 1 发送帧长度(10 个字)
    McBSP0Regs.XCR.bit.XFRLEN1=0x9;
    // 指定相位 1 发送字长度(16 位)
    McBSP0Regs.XCR.bit.XWDLEN1=0x2;
    // 无数据位倒置
    McBSP0Regs.XCR.bit.XWDREVRS=0;

    // 延时100个时钟周期,等待内部同步
    unsigned char i;
    for(i=0;i<100;i++)
        asm (" nop");

    // 使能 接收
    McBSP0Regs.SPCR.bit.RRST=1;
    // 使能 接收帧同步信号
    McBSP0Regs.SPCR.bit.FRST=1;

    // 使能 内部采样率生成器
    McBSP0Regs.SPCR.bit.GRST=1;
    // 使能 发送
    McBSP0Regs.SPCR.bit.XRST=1;

    // 延时100个时钟周期,等待内部同步
    for(i=0;i<100;i++)
        asm (" nop ");
}

void InterruptInit(void)
{
    // 初始化 DSP 中断控制器
    IntDSPINTCInit();

    // 使能 DSP 全局中断
    IntGlobalEnable();
}

void McBSP0InterruptInit(void)
{
    // 注册 McBSP0 中断服务函数
    IntRegister(C674X_MASK_INT5, McBSP0ISR_TX);
    // 映射系统中断至可屏蔽中断
    IntEventMap(C674X_MASK_INT5, SYS_INT_MCBSP0_XINT);
    // 使能可屏蔽中断
    IntEnable(C674X_MASK_INT5);
}

void McBSP0ISR_TX(void)
{
    printf("start transmit.\n");
    unsigned int to_send = 0x0;
    if (ximt_flag) {
        ximt_flag = 0;
        to_send = 0x0;
    } else {
        ximt_flag = 1;
        to_send = 0xFFFFFF;
    }
    while (!McBSP0Regs.SPCR.bit.XRDY);
    // 写入数据到DXR寄存器
    McBSP0Regs.DXR = to_send;

}