This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320VC5509A: 5509A的Mcbsp配置为spi从机模式,接收到的数据会经常性、无规律的出现数据错误/移位等现象

Part Number: TMS320VC5509A

工程师们好,最近我将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 1001 1000),但DSP总会接收到错误数据,如下图所示:

除此之外,诡异的是,断开clkx0与主机的连线时,DSP依然可以完成读数(rx = 0x0),接收数据的寄存器可以在没有主时钟的情况下工作?

希望工程师们能解答我的疑惑,感谢!