原创 nRF905模块调试心得

2011-6-4 14:43 4287 11 12 分类: EDA/ IP/ 设计与制造

               细数,从买下模块到现在,已经过了一个月有多。但中间的辛酸苦楚远比这时间难熬。但总结下来,只有这么一句话:

                       今天对细节的置之不理,造就明天的抓耳挠腮。

      若想看我如何犯下一个个不可饶恕的错误,请听我慢慢道来。

     先说明一下自己的情况:工作电压为5V的STC89C52RC    LED模块 自己的想法是把模块的收发信息或工作状态反映在LED上

     起初自己一边看模块说明书,一边尝试去写代码。

     if(DR) LED=0x55;

      但后来辛辛苦苦把12根模块上的管脚通过杜邦线连到单片机上是,发现LED并没有亮,无论是发送端还是接收端。我能在这好一段时间,一直怀疑是电路的问题,如 STC89C52到底属不属于51系列单片机(因为如果是别的单片机,管脚输出电流会烧坏模块,说明书有提),是否需要在模块上加几个电阻等。闷了几天,当时还正以为模块被烧坏,想着寄回厂家检修(在淘宝买,回寄不便)。

     我还真天真地去中工再买了两个质量好的模块回来试。当然,结果同上。这时才逼出一个想法,SPI写Config进去,再读出来,将任何一个字节反映在LED模块上,试试模块能否工作。

     void SpiWrite(uchar send){
         uchar j; 
         DATA_BUF=send;
         for(j=0;j<8;j++){ 
            SCK=1; 

           if((DATA_BUF&0x80)!=0){
                      MOSI=1;
             }else{
                      MOSI=0;
             }
             DATA_BUF<<=1;
             SCK=0;
        }
}

     ( 已知nRF905的SPI通信工作在模式0下)

       SPI写入代码如上。实验发现,LED全灭,说明压根没写进去,或没读出来。这又让我纠结了好久。百度百科了一下,有了发现。

      让我们来关注SCK的第一个时钟周期,根据SPI的通信原理知,在时钟的上升沿采样数据,时钟的下降沿输出数据(相对从机而言)。因此,按照上面的代码,在第一次循环中SCK=1时,MOSI为0,这样就造成了字节的错位。当然写不进去,更不要读出来了。

     正确写法应该是把 SCK=1; 移至 SCK=0;上方。

      SPI问题解决了,我以为收发也就顺理成章,轻松加愉快。但天真了。

      SPI写入已经可以保证不会出错。因此,只要发送代码正确,根据说明书所说,数据准备管脚DR将置高。

void TxPacket(unsigned char *Txbuf)
{
 uchar i;
 //Config905();
 CSN=0;
 SpiWrite(WTP);    // Write payload command
 for (i=0;i<4;i++)
 {
  SpiWrite(Txbuf);  // Write 4 bytes Tx data
 }// Spi enable for write a spi command
 CSN=1;
 Delay(1);      // Spi disable
 CSN=0;      // Spi enable for write a spi command
 SpiWrite(WTA);    // Write address command
 for (i=0;i<4;i++)   // Write 4 bytes address
 {
  SpiWrite(TxAddress);
 }
 CSN=1;      // Spi disable
 TRX_CE=1;     // Set TRX_CE high,start Tx data transmission
 Delay(5);     
 while (DR!=1) P0=0x55;
 TRX_CE=0;     // Set TRX_CE low
 P0=0x0f;

}

        理应来说,DR置高,然后程序顺利运行下去,跳过 while (DR!=1); ,但令人头痛的事,LED始终亮暗相间,P0=0x55.

        这时我一直想是否是延时的长短有问题。不得不去看看原版DataSheet中的时序图。

      

nRF905模块心得 - maixianyu - maixy

 

        其实我看这图时,有些疑问。DR 的时序变化图在那,如果要画的话,应该画哪。

 TRX_CE=1; // Set TRX_CE high,start Tx data transmission
Delay(5);
while (DR!=1) P0=0x55;
TRX_CE=0;

        如果真像代码所写,DR的置高应该是在T0于T1之间。但数据的发送却又是在T2开始,这让我不知该把while 语句放哪,并且还怀疑说明书上的代码有没有错。我把上述的语句排列组合了许多次,但总是老样子。

      又因此烦恼了数个夜晚。后来想着为啥不是着把管脚于管脚间的线断开,用万用表测测分开的管脚的电平。经测试,发现单片机上的IO口管脚电平始终为低,而nRF905模块上的DR管脚却有着令人兴奋的 3.38V .这就找到路子了,一定是IO口的问题,但具体问题在哪,及如何解决还的再看看.

       直到在 电子工程师论坛的Q群里,咨询了一些技术人员才得出了答案。问题出现在我的程序初始化。

void nRF905Init(void)
{
    CSN=1;      // Spi  disable
 SCK=0;      // Spi clock line init low
 DR=0;      // Init DR for input
 AM=0;      // Init AM for input
 CD=0;      // Init CD for input

 PWR=1;     // nRF905 power on
 TRX_CE=0;     // Set nRF905 in standby mode
 TXEN=0;     // set radio in Rx mode
}

    如上,我把DR设为了低电平,根据电路基础知识知道,高电平于低电平线与得 低电平,高电平只有与高电平线与才能得高电平。所以现在人们都是通过初始化设管脚为高来设置不需 设输入输出的IO口。由此看来,DR设为高便可。果然,发送成功。

    当然,接受端的nRF905模块DR管脚也有3V以上。但接收端的单片机却识别不了。这就诡异了,几乎是相同的电路布置,理应都一样,除了P3口有一个未拆除的排阻。问题也正是在这排阻上。

nRF905模块调试心得 - maixianyu - maixy

 不实践不会注意到 排阻上不光 1和2 有电阻,2,3,4,5,6,7,8,9 两两之间也有电阻,而且不小。这样一来,单片机识别错误也不足为怪了。

 

 

 

 

 

 

          问题月月有,这次特别多。好的方法是,认真打好基础,明年好好学习电学的基础知识,对待好细节。

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户377235 2013-7-13 15:19

如何实现双工呢??

相关推荐阅读
EE直播间
更多
我要评论
1
11
关闭 站长推荐上一条 /3 下一条