Chinaunix首页 | 论坛 | 博客
  • 博客访问: 78979
  • 博文数量: 25
  • 博客积分: 1280
  • 博客等级: 中尉
  • 技术积分: 366
  • 用 户 组: 普通用户
  • 注册时间: 2008-09-09 17:36
文章分类

全部博文(25)

文章存档

2010年(1)

2009年(5)

2008年(19)

我的朋友

分类:

2008-10-22 14:16:45

在103项目中,原来SPI中断部分接收数据的程序如下(代码以简化):
void interrupt ISR(void)
       GIE=1;
       SSPIF=0;
       Byte0=SSPBUF;
       while(SSPIF==0);
 
       SSPIF=0;
       Byte1=SSPBUF;
       while(SSPIF==0);
      
       SSPIF=0;
       Byte2=SSPBUF;
       while(SSPIF==0);   //这行代码多余,应该去掉
       SSPIF=0;           //这行代码多余,去掉
       command=0;        //收发标志位
       GIE=1;
}
以上程序有两行是多余的程序,导致收发数据不正确;根据从模式时序,当主芯片时钟启动时,从SPI启动接收和发送,一个字节的八个时钟结束后SSPIF置1,产生中断,此时SPI收到一个字节,且发送出一个字节;当第三个字节的时钟跑完时,第三个字节接收完毕。此时接收命令的三个字节就完成了,而原程序在第三个字节接收完毕后执行了while(SSPIF==0);此时SSPIF在读取SSPBUF之前就已经置0了,又执行while(SSPIF==0);那么程序就会死在这个地方,等以后时钟再启动时程序才可以继续运行,这就会导致收发错误。
原SPI发送数据程序如下(部分):
void interrupt ISR(void)
       GIE=1;
       SSPBUF=0x11; 
       while(BF==0);
       。。。。。。。。。
       。。。。。。。。。
       while(BF==0);
       SSPBUF=0xbb;    //发送最后一个字节数据
       command=0;
       GIE=1;
}
当程序将最后一个要发送的字节0xbb给出后,SSPBUF=0xbb;最后一个数据主SPI要想成功接收,主SPI必须接着运行一个字节的时钟,也就是说要发送的数据是在时钟之前给出的,那么如果将0xbb给出后就马上退出中断就会有问题了,因为在0xbb给了SSPBUF后时钟启动,这是才启动最后这个字节的发送与接收,当八个CLK结束后0xbb被成功发送置主SPI,那同时SSPIF被置1,BF被置1,此时程序已经退出中断了,而SSPIF=1则在实际上没有接收到新数据的情况下就会产生中断,程序在没有收到新数据的情况下又一次进入中断,一起收发数据错误。
更改后程序为:
void interrupt ISR(void)       //接收主芯片下发的三个字节的命令
{
       GIE=0;
       SSPIF=0;
       Byte0=SSPBUF;
       while(SSPIF==0);
       SSPIF=0;
       Byte1=SSPBUF;
       while(SSPIF==0);
      
       SSPIF=0;
       Byte2=SSPBUF;          //去掉两行多余代码
       GIE=1;
}
void interrupt ISR(void)       //向主芯片返回数据
{
GIE=0;
SSPBUF=0x11; 
while(BF==0);
......
......
SSPBUF=0xbb;
while(BF==0);              //等待,等主时钟八个CLK后将最后一个字节接收完毕后将SSPIF清零
SSPIF=0;                   //此时再退出中断
command=0;

GIE=1;
}
 
 
阅读(1164) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~