您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 能源与动力工程 > nRF2401的调试过程
经过这几周的努力,nRF2401的原始样机调试基本完成了,指标到达了预期目标。灵敏度很高,在-20dBm的发射功率下,可以达到10米左右的距离;在0dBm的功率下,可以超过40米。整机平均功耗很低,平均工作电流约10uA(与工作时间的占空比有关)。下面将介绍调试过程中遇到的一些问题和解决过程,希望这些可以对初学者有所帮助。因为这是目前正在开发的一个系统,所以代码和原理图就不能公布了,这里只描述一些调试过程中的关键点,这应当也足够了。开发环境:AVRStudio+WinAVR+SLISP硬件环境:ATmega88V+AVRDragon+自制并口下载线先调试发射部分(因为以前有一套用nRF24E1做的系统,但是功耗太大,没有实用化,但是正好可以用来调试),nRF2401的数据手册很简洁,很快就看完了。但是它只有C51的例程,没有其他单片机的。开始以为移植起来很容易,就直接写程序了。结果运行后,没有任何效果,就是说发出的数据不对。仔细对照C51的例子程序,没有发现有什么区别啊。最后检查,逐步缩小范围,感觉问题可能在SPI部分。AVR的SPI支持4种工作模式,区别在于时钟和数据的时序不同,习惯上使用方式0的最多,而我当时随便选了方式3,修改了SPI的工作模式就正常了。发射部分可以工作了,但是新做的接收部分收不到数据。而接收部分和发射部分的电路基本相同的,只有部分地方不一致。将发射的程序写入到接收板,可以正常发出,说明电路没有问题,还是程序有问题。反复对比C51的程序,终于发现是没有将CE设置为高引起的。因为这个接收程序是从发射程序修改而来的,而发射程序只是定时发射一下,然后就进入Standby状态,平时将CE和CS都置低了。从这里还发现nRF2401的控制和一般芯片不同,一般芯片习惯上是高电平无效,低电平使能,nRF2401是相反的,比较容易造成习惯性错误。接收部分调通以后,又发现了新问题,接收部分取回的数据总是有规律的出现误码,总是每隔几个数据就有一位到2位和实际值不一致。仔细检查程序,没有发现问题,否则也不可能通信连上了。后来想到会不会和SPI的速度有关系,因为只有nRF2401只有SPI和单片机连接,于是尝试将SPI的速度降低为500K(开始用的是1M),读出的数据就正常了(发射部分使用了低频,所以没有这个问题)。为了测试发射部分的功耗,需要测量电路的电流。因为休眠时的功耗非常小,用万用表的电流档无法测量。于是尝试在VCC中串联一个电阻,测量电阻两端的电压来推算电流(I=V/R)。开始串联一个1Ω的电阻,可以看到发射时有10几个mV,但是休眠时测量不出来了。将电阻加大到10Ω,这次好多了,可以测量到休眠时有1mV,也就是大约100uA。在修改程序进一步降低功耗后,又测量不出来了。再次将电阻增加到100Ω,这次读出2.5mV,就是25uA使用电阻串联时,电阻会有一定的分压(100欧姆乘以10毫安有1V),但是我使能了BOD功能也并没有复位,这说明工作时的时间短,电容可以短时间提供工作需要的能量,从示波器上观察也证实了这一点。看来单片机的性能还不错。因为最终需要使用电池供电,需要尽量降低功耗(这里主要是降低休眠时的工作电流,因为工作时的功率是无法减少的)。为了降低单片机的功耗,做了几种尝试(因为我以前做的产品,从来不需要考虑功耗,也就没有用过低功耗模式,只是从数据手册中看过一点)。开始时运行时将单片机的频率不分频,休眠时设置256分频(使用内部8M振荡器),以为运行时高速,休眠时低速可以降低功耗。在使用中发现效果不明显,电流还在mA级。于是改为内部128K振荡器,工作电流明显下降(看来实际频率更重要,内部分频在其他模块没有工作时对功耗影响不大)。因为功率P=V*I,我先想降低工作电压会不会降低功耗呢?看单片机的数据手册上电压降低也会降低功耗的。于是将工作电压降低到2.5V,结果测试的结果和3V是基本没有区别,再降低到2V,万用表的读数也只是最后一位跳动了,也就是说没有什么效果。看来这里因为主要功耗在nRF2401上,而不是单片机上,降低电压没有实际用处,反而会增加麻烦(需要加入降压电路)。为了进一步降低功耗,一开始没有控制nRF2401的PWR_UP端口,不发射时处于standby模式,这样在16M时钟下nRF2401大约有30uA的静态电流(主要是时钟工作的电流)。对于电池供电,这无疑还是太大了。nRF2401还有一个PWR_UP端口,设置为低电平后,就处于休眠状态,时钟也停止了,电流将小于1uA。在控制PWR_UP后,这次测试的数据就很理想了,休眠时的电流小于10uA,万用表无法测量了(读数小于1,1mV/100=10uA)。从理论上计算,单片机大约小于5uA(启用了看门狗定时器),其他部分小于1uA,总共小于6uA,数据比较吻合。如果在考虑每两秒发射一次,每次工作时发射1ms,10mA,等待稳定和其他时间8ms,0.1mA,那么平均电流就是6+10/2+0.1*8/2=11.4,如果使用200mAH的电池也可以工作2年。还有一个问题,开始时我使用AVRDragon的DebugWire仿真(8M振荡器),降低到128K后,没有将程序中设置时钟256分频的代码屏蔽,结果出现了一个严重的问题。因为使用内部128K振荡器后,只能用低速方式下载,在一次仿真不正常退出后(使用DebugWire很容易出现这种现象),想恢复为正常模式(DebugWire使用了Reset,就不能正常下载了),但是却无法联机了。我分析是因为这时单片机还是处于DebugWire模式,RESET引脚的复位功能不起作用了。而这时因为使用内部低频振荡器(还256分频),SPI的速度非常慢,正常方式DebugWire很难连接。因为手头当时没有多余的芯片,于是就尝试反复进入DebugWire模式(因为也没有别的办法了),在大约尝试50次后,终于进入了DebugWire模式,赶紧恢复为正常模式,就又可以使用了。这说明在低速SPI时,连接的成功率很低,大家也要小心这里,否则很可能造成芯片死锁而无法恢复。nRF2401在上电后需要延时3ms才能进行初始化,开始时是使用定时器0做延时,延时基本时间是1ms。后来发现定时器2的分频更多(在128K时钟时128分频后正好是1ms),而且定时器2支持powersave模式下中断唤醒,于是改用定时器2做延时。开始还是正常的,可是后来发现时间不对,大概慢了10倍,找了半天没有发现程序有什么问题,寄存器的设置都是对的,软件仿真时间也正确。突然想到问题是在优化功耗时,加入power_all_disable()后出现,之前没有这个问题。于是将这个代码先注释掉在下载运行,果然时间就正常了。在查看手册中,原来power_all_disable()会将定时器2也关闭,于是在power_all_disable()之后加上power_timer2_enable(),运行定时器2工作,于是就正常了。但是现在还不清楚为什么在power_all_disable()后为什么定时器2还能运行,只是速度慢了很多。×目前还需要进一步测试的地方有:多个发射部分的碰撞处理、有几个可以进一步降低功耗的方法需要实验、更精确的测试功耗。此外,还预备将优化代码,使得移植性更好。
本文标题:nRF2401的调试过程
链接地址:https://www.777doc.com/doc-5584774 .html