大家好、
最近、我将 McBSP0配置为 SPI 从站、相关寄存器配置如下。 (我参考了 SPRU592E 的第6.7节。) 代码注释不准确、DSP 在时钟的下降沿接收数据。
MCBSP_Config SPI_SLAVE = { MCBSP_SPCR1_RMK( MCBSP_SPCR1_DLB_OFF, /* DLB = 0,禁止自闭环方式 */ MCBSP_SPCR1_RJUST_LZF, /* RJUST = 2,左检验,低位填0*/ MCBSP_SPCR1_CLKSTP_NODELAY, /时停模式无延迟*/ MCBSP_SPCR1_DXENA_NA, /* DXENA = 1,不允许DX数据延迟 */ 0, /* ABIS = 0 */ MCBSP_SPCR1_RINTM_FRM, /* RINTM = 0 ,RRDY bit从0到1产生接收中断*/ 0, /* RSYNCER = 0,无同步错误*/ MCBSP_SPCR1_RRST_DISABLE /* RRST = 0,串口复位 */ ), MCBSP_SPCR2_RMK( MCBSP_SPCR2_FREE_NO, /* FREE = 0,时钟受SOFYT bit控制 */ MCBSP_SPCR2_SOFT_NO, /* SOFT = 0,调试出现断点时时钟立即停止 */ //MCBSP_SPCR2_FRST_RESET, //帧同步关闭 MCBSP_SPCR2_FRST_FSG, /* FRST = 0 */ //MCBSP_SPCR2_GRST_RESET, /* GRST = 0,采样率发生器复位,CLKG频率为CPU时钟周期的一半 */ MCBSP_SPCR2_GRST_CLKG, MCBSP_SPCR2_XINTM_XRDY, /* XINTM = 0,XRDY bit从0到1产生发送中断 */ 0, /* XSYNCER = N/A,无同步错误 */ MCBSP_SPCR2_XRST_DISABLE /* XRST = 0,发送串口复位 */ ), /*单数据相,接受数据长度为16位,每相2个数据*/ MCBSP_RCR1_RMK( MCBSP_RCR1_RFRLEN1_OF(0), /* RFRLEN1 = 0,接收帧每帧一字 */ MCBSP_RCR1_RWDLEN1_16BIT /* RWDLEN1 = 5,每字32位 */ ), MCBSP_RCR2_RMK( MCBSP_RCR2_RPHASE_SINGLE, /* RPHASE = 0,单段帧 */ MCBSP_RCR2_RFRLEN2_OF(0), /* RFRLEN2 = 0,该帧无字 */ MCBSP_RCR2_RWDLEN2_8BIT, /* RWDLEN2 = 0,每字8bit */ MCBSP_RCR2_RCOMPAND_MSB, /* RCOMPAND = 0,无压缩,先传输高位数据 */ MCBSP_RCR2_RFIG_YES, /* RFIG = 0,每个帧同步信号启动一次数据接收 */ MCBSP_RCR2_RDATDLY_0BIT /* RDATDLY = 1,1bit数据延迟 */ ), MCBSP_XCR1_RMK( MCBSP_XCR1_XFRLEN1_OF(0), /* XFRLEN1 = 0,发送帧每帧一字 */ MCBSP_XCR1_XWDLEN1_16BIT /* XWDLEN1 = 5,每字32位 */ ), MCBSP_XCR2_RMK( MCBSP_XCR2_XPHASE_SINGLE, /* XPHASE = 0,单段帧 */ MCBSP_XCR2_XFRLEN2_OF(0), /* XFRLEN2 = 0,该帧无字 */ MCBSP_XCR2_XWDLEN2_8BIT, /* XWDLEN2 = 5,每字32bit */ MCBSP_XCR2_XCOMPAND_MSB, /* XCOMPAND = 0,无压缩,先传输高位数据 */ MCBSP_XCR2_XFIG_YES, /* XFIG = 0,每个帧同步信号启动一次数据发送 */ MCBSP_XCR2_XDATDLY_0BIT /* XDATDLY = 1,1bit数据延迟 */ ), MCBSP_SRGR1_RMK( MCBSP_SRGR1_FWID_OF(1), /* 停止模式无效**重要FWID = 0 帧同步信号的脉宽周期数*/ MCBSP_SRGR1_CLKGDV_OF(0) /* 停止模式无效**重要CLKGDV =1 CLKG时钟频率*/ ), MCBSP_SRGR2_RMK( 0,//MCBSP_SRGR2_GSYNC_FREE, /* FREE = 0 内部时钟帧同步 (每FPER+1个CLKG周期产生FSG脉冲时钟同步)*/ MCBSP_SRGR2_CLKSP_RISING, /* 重要CLKSP = 0 CLKS 引脚极性,CLKS上升沿产生CLKG和FSG*/ MCBSP_SRGR2_CLKSM_INTERNAL, /* 重要CLKSM = 1 cpu时钟(叠加93行SCLKME=0)*/ MCBSP_SRGR2_FSGM_DXR2XSR, /* FSGM = 0 发送帧同步模式,如果FXSM=1,当DXR->XSR时,McBSP产生帧同步信号*/ MCBSP_SRGR2_FPER_OF(0) /*重要 FPER = 0 FSG信号帧同步时钟周期数,应该是7*(每个FSG周期为FPER+1个CLKG时钟周期)*/ ), MCBSP_MCR1_DEFAULT, MCBSP_MCR2_DEFAULT, MCBSP_PCR_RMK( MCBSP_PCR_IDLEEN_RESET, /* IDLEEN = 0,当PERIPH域idle时MCBSP保持有效 */ MCBSP_PCR_XIOEN_SP, /* XIOEN = 0,CLKX,FSX,DX,CLKS用作串口引脚 */ MCBSP_PCR_RIOEN_SP, /* RIOEN = 0,CLKX,FSX,DX,CLKS用作串口引脚 */ MCBSP_PCR_FSXM_EXTERNAL, /* FSXM = 0,接收帧同步信号 */ MCBSP_PCR_FSRM_EXTERNAL, /* FSRM = 1,接收帧同步信号由MCBSP提供 */ MCBSP_PCR_CLKXM_INPUT, /* CLKXM = 0,MCBSP作为SPI从设备 */ MCBSP_PCR_CLKRM_OUTPUT, /* CLKRM = 0,外部通过CLKR引脚提供接收时钟(叠加27行DLB=0) */ MCBSP_PCR_SCLKME_NO, /*SCLKME =0,CPU时钟(叠加79行CLKSM=1) */ //MCBSP_PCR_CLKSSTAT_0, MCBSP_PCR_DXSTAT_0, /* DXSTAT = 0,DX引脚设为低电平 */ //MCBSP_PCR_DRSTAT_0, /*DRSTAT =0,DR引脚设为低电平 */ MCBSP_PCR_FSXP_ACTIVELOW, /* FSXP = 1,发送帧同步信号低有效 */ MCBSP_PCR_FSRP_ACTIVELOW, /* FSRP = 1,接收帧同步信号低有效 */ MCBSP_PCR_CLKXP_FALLING, /* CLKXP = 0,CLKX上升沿发送数据 */ MCBSP_PCR_CLKRP_FALLING /* CLKRP = 1,CLKR上升沿接收数据(CLKR输出数据信号时内部CLKR经过转换后送到CLKR引脚) */ /*低电平无效,有延迟,MCBSP在CLKX上升沿之前半个周期发送数据,在CLKR上升沿接收数据*/ ), MCBSP_RCERA_DEFAULT, MCBSP_RCERB_DEFAULT, MCBSP_RCERC_DEFAULT, MCBSP_RCERD_DEFAULT, MCBSP_RCERE_DEFAULT, MCBSP_RCERF_DEFAULT, MCBSP_RCERG_DEFAULT, MCBSP_RCERH_DEFAULT, MCBSP_XCERA_DEFAULT, MCBSP_XCERB_DEFAULT, MCBSP_XCERC_DEFAULT, MCBSP_XCERD_DEFAULT, MCBSP_XCERE_DEFAULT, MCBSP_XCERF_DEFAULT, MCBSP_XCERG_DEFAULT, MCBSP_XCERH_DEFAULT };
我选择 RINT0作为中断、初始化函数如下。
void IRQInit(void) { /* 设置中断向量入口 修改寄存器IVPH,IVPD,重新定义中断向量表*/ IRQ_setVecs((Uint32)(&VECSTART)); /*禁止可屏蔽中断使能*/ old_intm = IRQ_globalDisable(); /*获取中断标号*/ eventId0 = IRQ_EVT_RINT0; /* 清除外部中断*/ IRQ_clear(eventId0); /*设置中断向量地址*/ IRQ_plug(eventId0,&transmit_ready); /*使能外部中断*/ IRQ_enable(eventId0); /*使能可屏蔽中断*/ IRQ_globalEnable(); }
中断功能如下。
interrupt void transmit_ready() { Uint16 data = 0; data = slave_rx16(); delay_us(1); } Uint16 slave_rx16(void) { Uint16 rx = 0; while(!MCBSP_rrdy(hMcbsp2)); rx=MCBSP_read16(hMcbsp2); while(!MCBSP_xrdy(hMcbsp2)); MCBSP_write16(hMcbsp2,0x1234); return rx; }
我使用 STM32作为主机来周期性发送16位数据0x9898 (1001 1000 1000)、但 DSP 将始终接收到错误的数据、如 下图所示。
此外、 令人好奇的是、当 clkx0与主机断开连接时、DSP 仍然可以完成读取(Rx = 0x0)、并且接收数据的寄存器可以在没有主时钟的情况下工作。 我想知道为什么。
您能解释一下吗? 提前感谢您。
此致、
Katherine