• 已解决 73482 个问题
  • 已帮助 5993 位优秀工程师

SPI双向通信时,主机收到的数据有问题!

追梦的阿土哥 2016-03-13 浏览量:2388

     最近在做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 0 收起

我来回答

上传资料:
选择文件 文件大小不超过15M(格式支持:doc、ppt、xls、pdf、zip、rar、txt)
最佳答案
  • 1、排除硬件连接与线路干扰问题。

    2、主机与从机分别将MISO与MOSI短接进行测试(使用查询方式,先不用中断),自发自收是否有问题。

    3、不用中断,使用查询方式进行主、从机通讯,结果。

    4、使用中断后的结果。

    通过以上4步定位BUG的的位置是在哪一层上,再对应解决,个人感觉最有可能的问题是中断的处理上,你中断中是不是有自己定义的协议?你的协议最好是按帧进行接收,不要一个字节一个字节的,处理起来也麻烦。

    • 发布于 2016-03-13
    • 举报
    • 评论 0
    • 0
    • 0

其他答案 数量:20

  • 感觉你的主机中断接收函数是不是有问题?

    stage4=stage3;
    stage3=SSP1BUF;
    接收的时候为什么要这么写一下呢?

    stage4=stage3;

    这样的话,如果第一次,stage3没有赋值的话,初值应该是0,那么stage4不是等于0了么?

    那你的if((stage4==0x10)&&(stage3==0x11))岂不是不成立?是不是就会收不到东西呢?

    不知道你的stage3在别的地方有没有设初值,这里确实看不出来……

    • 发布于2016-03-13
    • 举报
    • 评论 0
    • 0
    • 0

  • 用逻辑分析仪看一下时序或者单步调试一下看哪部分出问题。
    • 发布于2016-03-13
    • 举报
    • 评论 0
    • 0
    • 0

  • 嗯,主要是为了对比主从机的不同好分析原因嘛,所以都给贴上来了~
    • 发布于2016-03-14
    • 举报
    • 评论 0
    • 0
    • 0

  • 没有设初值,这个是一二次收到的数据用来判断的,符合才开始接收,从机也是这样写的,收到的数据就没有问题~
    • 发布于2016-03-14
    • 举报
    • 评论 0
    • 0
    • 0

  • 这个时序看不出吧,毕竟能收到数据,只是数据的顺序有问题。
    • 发布于2016-03-14
    • 举报
    • 评论 0
    • 0
    • 0

  • 如果不用中断该如何接收数据?查询法不懂,能不能讲详细点?中断里是有自己的协议,按485/232的套路写的~
    • 发布于2016-03-14
    • 举报
    • 评论 0
    • 0
    • 0

  • 在main的while(1)里查询SPI寄存器的状态来读写。
    • 发布于2016-03-14
    • 举报
    • 评论 0
    • 0
    • 0

  • 从机没问题那是因为你主机发送的是从00开始的吧?而定义的变量一般没赋初值的话,默认为0!但是你从机发给主机的 就不是从00开始了……所以,你试试吧……
    • 发布于2016-03-14
    • 举报
    • 评论 0
    • 0
    • 0

  • 不知道楼主的问题解决了没?
    • 发布于2016-03-16
    • 举报
    • 评论 0
    • 0
    • 0

  • 在while(1)里查SSPIF的状态来收数据,一个都收不到了,不知道是不是查这个标志位?
    • 发布于2016-03-16
    • 举报
    • 评论 0
    • 0
    • 0

  • 还没有呢,由于没有过压保护,火气大把板子烧了,只好重新焊从头开始调了~
    • 发布于2016-03-16
    • 举报
    • 评论 0
    • 0
    • 0

  • 也只能是这样了,贴出来就是怕自己的思路走进死胡同了,集思广益嘛~
    • 发布于2016-03-16
    • 举报
    • 评论 0
    • 0
    • 0

  • 你查一下手册 ,好久不用pic了,好像是这个寄存器。


    先往SSPBUF中放一个值,就是用SPI发一个值,再用while(SSPIF==0);等发完了。

    • 发布于2016-03-16
    • 举报
    • 评论 0
    • 0
    • 0

  • 我试了一下,主机发送的数据从20开始从机也是能正常接收数据的~
    • 发布于2016-03-17
    • 举报
    • 评论 0
    • 0
    • 0

  • 围观一起学习。
    • 发布于2016-03-17
    • 举报
    • 评论 0
    • 0
    • 0

  • 问题已经解决了,主机收数据也得用写数据的方式来跟从机交换寄存器的值,而不是用中断的方式收,谢谢大家的指点~
    • 发布于2016-03-20
    • 举报
    • 评论 0
    • 0
    • 0

相关问题

问题达人换一批

SPI双向通信时,主机收到的数据有问题!