最近在做SPI的双向通信,采用两个PIC16F1828,现在的问题是从机能收到主机发送的数据,但是主机收到的从机发送的顺序却有问题。比如主机发送的数据是0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,从机能按顺序收到主机发送的数据。从机发送的数据是0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,但是主机收到的数据却是0x10,0x11,0x17,0x01,0x02,0x03,0x16,0x17。有时候主机收到的数据顺序又是正确的,不知道是什么原因,请大神指点指点~ 主机配置发送接收程序 void SPI_INIT(void)//SPI的配置 { SPI_SCK_OUT; SPI_SDO_OUT; SPI_SDI_IN; SPI_nSS_OUT; ANSELB=0X00; SSP1STAT=0X80; SSPCON=0X32; SPI_nSS=1; INTCON=0XC0; PIE1=0X08;//开MSSP中断 PIR1=0X00;//清零MSSP中断 } void SPI_WRITE(uchar data) { uchar back; SPI_nSS=0; DELAY(20); SSP1BUF=data; back=SSP1BUF; SPI_nSS=1; DELAY(20); } //中断方式接收 void interrupt mssp(void) { if(SSP1IF) { SSP1IF=0; stage4=stage3; stage3=SSPBUF; if((stage4==0x10)&&(stage3==0x11)) { begin=1;j=0; } if(begin==1) { receive_spi[j++]=stage3; if(j==8) { begin=0;j=0;send=1; } }}} 从机配置发送接收程序 void SPI_INIT(void) { SPI_SCK_IN; SPI_SDO_OUT; SPI_SDI_IN; SPI_nSS_IN; ANSELB=0X00; ANSELC=0X00; SSP1STAT=0X00; SSPCON=0X34; INTCON=0XC0; PIE1=0X08;//开MSSP中断 PIR1=0X00;//清零MSSP中断 } //从机SPI发送 void SPI_WRITE(uchar data) { uchar back; DELAY(20); SSPBUF=data; back=SSPBUF; DELAY(20); }
//中断方式接收 void interrupt mssp(void) { if(SSP1IF) { SSP1IF=0; stage4=stage3; stage3=SSP1BUF; if((stage4==0x00)&&(stage3==0x01)) { begin=1;j=0; } if(begin==1) { receive[j++]=stage3; if(j==8) { begin=0;j=0;send=1; } }}}
1、排除硬件连接与线路干扰问题。
2、主机与从机分别将MISO与MOSI短接进行测试(使用查询方式,先不用中断),自发自收是否有问题。
3、不用中断,使用查询方式进行主、从机通讯,结果。
4、使用中断后的结果。
通过以上4步定位BUG的的位置是在哪一层上,再对应解决,个人感觉最有可能的问题是中断的处理上,你中断中是不是有自己定义的协议?你的协议最好是按帧进行接收,不要一个字节一个字节的,处理起来也麻烦。
感觉你的主机中断接收函数是不是有问题?
stage4=stage3; stage3=SSP1BUF; 接收的时候为什么要这么写一下呢?
stage4=stage3;
这样的话,如果第一次,stage3没有赋值的话,初值应该是0,那么stage4不是等于0了么?
那你的if((stage4==0x10)&&(stage3==0x11))岂不是不成立?是不是就会收不到东西呢?
不知道你的stage3在别的地方有没有设初值,这里确实看不出来……
你查一下手册 ,好久不用pic了,好像是这个寄存器。
先往SSPBUF中放一个值,就是用SPI发一个值,再用while(SSPIF==0);等发完了。