SPI从机接收无法触发

qq_24402601 2016-10-24 09:40:27
使用28335 SPIA作为主机读取传感器数据成功了。然后想拿一块DSP模拟从机,做类似的通信却怎么都不成功。
主机1s发送一个0X5600,想读取从机返回的数据,但是从机数据接收时,0X5600只传到SPIDAT,不自动存入RXBUF也不会将INT_FLAG置位。
void Init_SPIA()
{
SpiaRegs.SPICCR.bit.SPICHAR = 0xf ; //数据长度配置1-16可选 16
SpiaRegs.SPICCR.bit.CLKPOLARITY = 1; // output on rising edge
SpiaRegs.SPICTL.bit.CLK_PHASE = 0; // normal phase
SpiaRegs.SPICTL.bit.MASTER_SLAVE = 0; // 1:主机模式;0:从机
SpiaRegs.SPICTL.bit.SPIINTENA = 0; // 禁止SPI中断
SpiaRegs.SPICTL.bit.TALK = 1; // 使能发送(否则MOSI将为高阻态)
SpiaRegs.SPIBRR = 0x3f; // 7位, 当BRR >= 3时速度 = LSPCLK/(BRR+1)
SpiaRegs.SPICCR.bit.SPILBK = 0; // 1:使能内部回环测试功能,调试时使用
// 0:关闭回环测试,正常使用
SpiaRegs.SPICCR.bit.SPISWRESET = 1; // 启动SPI发送和接收
SpiaRegs.SPIPRI.bit.FREE = 1; // 断点不影响SPI传输
}
时钟相位四种模式都试过了,主机设置为1,0时,从机1,0和0,1两种模式比较接近成功,另外两种SPIDAT都是错的。
有人遇到过类似的情况吗,怎么解?
...全文
1441 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_24402601 2016-10-25
  • 打赏
  • 举报
回复
主机加延时试过了,没用。从机还是有时候会阻塞while(SpiaRegs.SPISTS.bit.INT_FLAG != 1) {}过不去。这个时候主机就在接收自己发的数。
	for(;;)
	{
		rdata = 0x0000;
		Delay_nMS(1000);
		ADIS445_NCS;
		test = SPIA_ReadWriteByte(PROD_ID);
		Delay_nMS(10);
		ADIS445_CS;
		Delay_nMS(10);
		ADIS445_NCS;
		rdata = SPIA_ReadWriteByte(0xffff);
		Delay_nMS(10);
		ADIS445_CS;
		transmit_16bit(test);
		transmit_16bit(rdata);
	};
主机接收到的数据如下: F0 F0 55 AA F0 F0 56 00 F0 F0 55 AA F0 F0 55 AA F0 F0 55 AA F0 F0 56 00 F0 F0 55 AA F0 F0 55 AA F0 F0 56 00 从机发送的第一个16位字间断性出问题,但是最后一个字F0 F0倒是非常稳定,尝试过每1s三个字通讯,还是只有最后一个字正常。
of123 2016-10-25
  • 打赏
  • 举报
回复
哪位到“两个电脑同一个串口通讯问题”帖子中回复一下。我再发一个协议设想。坛子只允许连续发 3 个。
of123 2016-10-25
  • 打赏
  • 举报
回复
你试试发送 56 00 后等待一段时间,给够从机应答的的准备时间。
qq_24402601 2016-10-25
  • 打赏
  • 举报
回复
主机一次循环中发送0X5600,0XFFFF,第二个发送是为了接收从机判断之后发来的数据,预期为0X55AA。主机希望只接收到0X55AA。
qq_24402601 2016-10-25
  • 打赏
  • 举报
回复
主机接收到0x5600时的情况,就是我指的从机无法触发。无操作的这1s中断点查看寄存器发现从机接收的正确数据0x5600已经到SPIDAT,但是没能进入RXBUF(感觉像少一个电平跳变)。尝试过主机手动控制片选,结束时增加延时也没用(话说本来就是1s一次循环发送)。当主机一个周期完成多次读写时,55 AA 55 AA 55 AA 56 F0 55 AA 56 F0 55 AA 主机: Delay_nMS(1000); ADIS445_NCS; SPIA_ReadWriteByte(PROD_ID); DELAY_US(16); rdata = SPIA_ReadWriteByte(0xffff); ADIS445_CS; transmit_16bit(rdata); 从机: for(;;) { while(SpiaRegs.SPISTS.bit.INT_FLAG != 1) {} rdata = SpiaRegs.SPIRXBUF; if(rdata==0x5600) SpiaRegs.SPITXBUF = 0x55aa; // Next Transmit Byte else SpiaRegs.SPITXBUF = 0xf0f0; GpioDataRegs.GPATOGGLE.bit.GPIO1 = 1; }
of123 2016-10-25
  • 打赏
  • 举报
回复
哪些是主机发送的?你预期的返回串是什么?
qq_24402601 2016-10-25
  • 打赏
  • 举报
回复
主机和从机是能够正常通信的,但是经常会从机不响应, 表现就是你说的 “如果从机端是硬件 SPI 模块,且已经工作,即使从机不对主机响应,主机所发送的字符在下一个字符帧期间也会自动返回。” 贴出主机接收到的数据如下: 55 AA 55 AA 56 00 56 00 56 00 56 00 55 AA 56 00 56 00 56 00 55 AA
of123 2016-10-25
  • 打赏
  • 举报
回复
一般来说,如果从机端是硬件 SPI 模块,且已经工作,即使从机不对主机响应,主机所发送的字符在下一个字符帧期间也会自动返回。 如果什么都没有返回,检查从机是否工作,片选信号是否有效,MISO 线是否接通。
of123 2016-10-25
  • 打赏
  • 举报
回复
去我新发的那个“两个主机……”帖子领一下分。
of123 2016-10-25
  • 打赏
  • 举报
回复
估计是丢失时钟信号造成的。试试时钟信号用屏蔽线,或加上驱动电路。 另外,就是主机在每个字节间加上片选拉高,延时半个通讯时钟周期。这样,丢失时钟不会传递到后续字节。 还有,就是检查你主从两方的 SPOL 和 SPHA 模式是否一致。
qq_24402601 2016-10-24
  • 打赏
  • 举报
回复
上面那个手误,应该是 rdata = SpiaRegs.SPIRXBUF; 可惜 while(SpiaRegs.SPISTS.bit.INT_FLAG != 1) {} 都一直过不来。。有谁知道原因吗?
qq_24402601 2016-10-24
  • 打赏
  • 举报
回复
从机的主函数初始化之后如下循环等待主机发送数据。 SpiaRegs.SPITXBUF = 0x55aa; for(;;) { while(SpiaRegs.SPISTS.bit.INT_FLAG != 1) {} rdata = SpiaRegs.SPIDAT; SpiaRegs.SPITXBUF = 0x55aa; // Next Transmit Byte GpioDataRegs.GPATOGGLE.bit.GPIO1 = 1; } 试过采用中断的方式接收,都无法进入中断。。。

27,382

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧