[原创] 关于MSP430FR5969的功耗你知多少

littleshrimp   2014-12-30 17:15 楼主
关于MSP430FR5969的功耗你知多少
为了测试MSP430FR5969的功耗,我焊了一块只有复位电路的最小系统板,然后做了一些实验,现在和大家分享一下。
IMG_20141230_153243189.jpg
思路是这样的,首先写了一个休眠函数,函数会进入LPM3模式指定时间后唤醒单片机工作。
  1. uint16_t ta_lpm = 0;
  2. void delay_ms_lpm3(uint16_t ms)
  3. {
  4. ta_lpm = LPM3_bits; //低功耗LPM1_bits
  5. if(ms > 5957)while(1);
  6. TA0CCTL0 = CCIE; // CCR0 interrupt enabled
  7. TA0CCR0 = 33*ms;
  8. TA0CTL = TASSEL_1 + MC_1; // ACLK = 11KHz, Up to CCR0
  9. if(ta_lpm)
  10. {
  11. __bis_SR_register(ta_lpm + GIE); // CPUoff, interrupts enabled
  12. }
  13. else
  14. {
  15. while((TA0CTL & TAIFG) == 0);
  16. }
  17. }
  18. // Timer A0 interrupt service routine
  19. #pragma vector=TIMER0_A0_VECTOR
  20. __interrupt void Timer_A (void)
  21. {
  22. TA0CTL &= ~(MC_1);
  23. TA0CCTL0 &= ~(CCIE);
  24. if(ta_lpm)
  25. {
  26. __bic_SR_register_on_exit(ta_lpm); // Exit LPMx
  27. }
  28. }
然后是时钟配置函数,使用1MDCO
  1. void clock_init(void)
  2. {
  3. WDTCTL = WDTPW | WDTHOLD; // Stop Watchdog
  4. PM5CTL0 &= ~LOCKLPM5;
  5. CSCTL0_H = CSKEY >> 8; // Unlock CS registers
  6. CSCTL1 = DCOFSEL_0; // Set DCO to 1 MHz
  7. CSCTL2 = SELM__DCOCLK | SELS__DCOCLK | SELA__VLOCLK;
  8. CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1; // Set all dividers to 1
  9. CSCTL4 = LFXTOFF | HFXTOFF;
  10. CSCTL0_H = 0; // Lock CS registers
  11. }
再写一个唤醒函数,指定单片机被唤醒的次数
//唤醒指定次数
  1. void weekup(unsigned char n)
  2. {
  3. unsigned char i;
  4. for(i=0;i<n;i++)
  5. {
  6. __delay_cycles(65500);//工作一段时间
  7. delay_ms_lpm3(100);//休眠
  8. }
  9. }
接下来是上电测试
首个测试是只配置时钟时的电流情况,让单片机每唤醒一次休眠1秒的情况
  1. int main(void)
  2. {
  3. clock_init();
  4. while(1)
  5. {
  6. weekup(1);
  7. delay_ms_lpm3(1000);//休眠一秒
  8. }
  9. }
test1.png
电流在600uA左右,波动是我活动板子造成的(相信我,板子的电源连接非常结实),
p2.png
MSP430FR5969官方的功耗才不到1uA,你的电流表是不是不准啊?对,是不准,但不会差这么多的,这么高的电流,很奇怪吧,别着急,我们往下实验。
第一个测试:所有I/O口设置成输出0后的电流消耗
  1. void test1(void)
  2. {
  3. //所有引脚配置成输出模式,输出零
  4. P1OUT = 0;
  5. P1DIR = 0xFF;
  6. P2OUT = 0;
  7. P2DIR = 0xFF;
  8. P3OUT = 0;
  9. P3DIR = 0xFF;
  10. P4OUT = 0;
  11. P4DIR = 0xFF;
  12. PJOUT = 0;
  13. PJDIR = 0xFFFF;
  14. }
  15. int main(void)
  16. {
  17. clock_init();
  18. while(1)
  19. {
  20. weekup(3);
  21. test1();
  22. delay_ms_lpm3(1000);//休眠一秒
  23. }
  24. }
test2.png
1uA左右,基本正常。
第二个测试:这是将所有I/O口输出高电平
  1. void test2(void)
  2. {
  3. // 所有引脚输出模式,输出1
  4. P1OUT = 0xFF;
  5. P1DIR = 0xFF;
  6. P2OUT = 0xFF;
  7. P2DIR = 0xFF;
  8. P3OUT = 0xFF;
  9. P3DIR = 0xFF;
  10. P4OUT = 0xFF;
  11. P4DIR = 0xFF;
  12. PJOUT = 0xFFFF;
  13. PJDIR = 0xFFFF;
  14. }
  15. int main(void)
  16. {
  17. clock_init();
  18. while(1)
  19. {
  20. weekup(3);
  21. test1();
  22. delay_ms_lpm3(1000);//休眠一秒
  23. }
  24. }
test3.png
和低电平一样,也是1uA多。
测试3:这是所有I/O口配置成输出无上拉
  1. void test3(void)
  2. {
  3. // 所有引脚输入模式,无上下拉
  4. P1OUT = 0xFF;
  5. P1DIR = 0;
  6. P2OUT = 0xFF;
  7. P2DIR = 0;
  8. P3OUT = 0xFF;
  9. P3DIR = 0;
  10. P4OUT = 0xFF;
  11. P4DIR = 0;
  12. PJOUT = 0xFFFF;
  13. PJDIR = 0;
  14. }
  15. int main(void)
  16. {
  17. clock_init();
  18. while(1)
  19. {
  20. weekup(3);
  21. test3();
  22. delay_ms_lpm3(1000);//休眠一秒
  23. }
  24. }
test4.png
可以看到在我刚刚插上电源那一瞬间电流飙升,然后稳定在200uA,这时候如果我活动一下板子电流也会上下波动。这时的状态和上电不配置引脚的结果是一样的,因为不配置其实就是输出无上下拉。
测试4:这是所有I/O口配置成输入上拉
  1. void test4(void)
  2. {
  3. // 所有引脚输出模式,上拉
  4. P1REN = 0xFF;
  5. P1OUT = 0xFF;
  6. P1DIR = 0;
  7. P2REN = 0xFF;
  8. P2OUT = 0xFF;
  9. P2DIR = 0;
  10. <font color="#ff0000">P2REN = 0xFF;</font>
  11. P3OUT = 0xFF;
  12. P3DIR = 0;
  13. <font color="#ff0000">P2REN = 0xFF;</font>
  14. P4OUT = 0xFF;
  15. P4DIR = 0;
  16. <font color="#ff0000">P2REN = 0xFF;</font>
  17. PJOUT = 0xFFFF;
  18. PJDIR = 0;
  19. }
  20. int main(void)
  21. {
  22. clock_init();
  23. while(1)
  24. {
  25. weekup(3);
  26. test4();
  27. delay_ms_lpm3(1000);//休眠一秒
  28. }
  29. }
test5.png
3尖峰右边的大波是我手活动后造成的,说明一个问题,和不配置一样,电流还是不稳定。
测试5:所有I/O口输入下拉
  1. void test5(void)
  2. {
  3. // 所有引脚输出模式,下拉
  4. P1REN = 0xFF;
  5. P1OUT = 0;
  6. P1DIR = 0;
  7. P2REN = 0xFF;
  8. P2OUT = 0;
  9. P2DIR = 0;
  10. <font color="#ff0000">P2REN = 0xFF;</font>
  11. P3OUT = 0;
  12. P3DIR = 0;
  13. <font color="#ff0000">P2REN = 0xFF;</font>
  14. P4OUT = 0;
  15. P4DIR = 0;
  16. <font color="#ff0000">P2REN = 0xFF;</font>
  17. PJOUT = 0;
  18. PJDIR = 0;
  19. }
  20. int main(void)
  21. {
  22. clock_init();
  23. while(1)
  24. {
  25. weekup(3);
  26. test5();
  27. delay_ms_lpm3(1000);//休眠一秒
  28. }
  29. }
test6.png
3个尖峰后也活动过一次板子,电流最高时达到了900uA,电流还是不稳定。
都测试过了发现只有在I/O口输出时电流的消耗才是最低的
测试6FRAM操作,先执行test1()I/O口配置成输出0,再重复对FRAM写入32K数据
  1. void test6(void)
  2. {
  3. //写32K数据到FRAM
  4. uint16_t i;
  5. uint8_t * ptr = (uint8_t *)0x10000;
  6. for(i=0;i<32768;i++)
  7. {
  8. *ptr++ = (uint8_t )i;
  9. }
  10. }
  11. int main(void)
  12. {
  13. clock_init();
  14. test1();
  15. while(1)
  16. {
  17. weekup(3);
  18. test6();
  19. delay_ms_lpm3(1000);//休眠一秒
  20. }
  21. }
test7.png
写入时的平均电流消耗130uA左右,1M时钟写入32K数据的时间为330ms左右
test8.png
看来FRAM在写入时的电流真的和读数据一样。
test9.png
以前我们总是担心写数据会消耗很多电流,这回你应该知道了吧,如果I/O配置成输入,休眠模式下的电流消耗比写数据大了多少倍。
为什么输出时电流消耗更高,我也在实验中,还没在网上查资料,有兴趣的朋友可以找找相关资料,有知道的朋友也麻烦给大家指个明路。
在输出模式下,如果活动PCB电流会波动很大,也是一个奇怪的现实,就留着日后实验证明吧。
今天继续解决上边低功耗的问题,在硬件电路上费了很大劲,做了很多测试,结果证明——,上边的测试代码写错了。 因为习惯性的复制粘贴导致P3,P4,PJ没有配置上拉,下边改好代码,就不会出现电流不稳定的情况了。
  1. void test4(void)
  2. {
  3. // 所有引脚输出模式,上拉
  4. P1REN = 0xFF;
  5. P1OUT = 0xFF;
  6. P1DIR = 0;
  7. P2REN = 0xFF;
  8. P2OUT = 0xFF;
  9. P2DIR = 0;
  10. P3REN = 0xFF;
  11. P3OUT = 0xFF;
  12. P3DIR = 0;
  13. P4REN = 0xFF;
  14. P4OUT = 0xFF;
  15. P4DIR = 0;
  16. PJREN = 0xFF;
  17. PJOUT = 0xFFFF;
  18. PJDIR = 0;
  19. }
  20. void test5(void)
  21. {
  22. // 所有引脚输出模式,下拉
  23. P1REN = 0xFF;
  24. P1OUT = 0;
  25. P1DIR = 0;
  26. P2REN = 0xFF;
  27. P2OUT = 0;
  28. P2DIR = 0;
  29. P3REN = 0xFF;
  30. P3OUT = 0;
  31. P3DIR = 0;
  32. P4REN = 0xFF;
  33. P4OUT = 0;
  34. P4DIR = 0;
  35. PJREN = 0xFF;
  36. PJOUT = 0;
  37. PJDIR = 0;
  38. }
最后的结论是,为了降低功耗,能配置成输出的I/O要配置成输出,不能配置输出的可以配置成输入,但一定要使用内部或外部上la.
39.msp430fr5969 低功耗引脚配置的演示.rar (4.42 KB)
(下载次数: 53, 2015-12-22 17:12 上传)
本帖最后由 littleshrimp 于 2015-12-22 17:13 编辑
虾扯蛋,蛋扯虾,虾扯蛋扯虾

回复评论 (11)

之前在TI官方支持论坛看到的一个帖子http://www.deyisupport.com/quest ... 0/f/55/t/24347.aspx
配置为输入的话,很不稳定,导致电流功耗反而很大。

最近接手的MSP430F5528,给的USB参考例程里,除了USB口,默认其他的GPIO输出拉底,结合上面的帖子,应该就是低功耗处理。
点赞  2014-12-30 19:22
比较好奇楼主测试电流用的什么东西?
一别四五年,变化万千。https://home.eeworld.com.cn/static/image/smiley/comcom/5.gif[/img]
点赞  2014-12-30 21:30
fram读出步骤是破坏性读出,需要硬件再自动写回,所以FRAM读写功耗接近。flash的读写功耗相差比较大。
点赞  2014-12-31 00:01
引用: jqh_111 发表于 2014-12-30 21:30
比较好奇楼主测试电流用的什么东西?
小壁虎的开发板
虾扯蛋,蛋扯虾,虾扯蛋扯虾
点赞  2015-1-4 13:01
引用: 易兮水 发表于 2014-12-30 19:22
之前在TI官方支持论坛看到的一个帖子http://www.deyisupport.com/question_answer/microcontrollers/msp430/f/55/t/24347.aspx
配置为输入的话,很不稳定,导致电流功耗反而很大。

最近接手的MSP430F5528,给的USB参考例程里,除了USB口,默认其他的GPIO输出拉底,结合上面的帖子,应该就是低功耗处理。
这个贴子很有用,谢谢。
虾扯蛋,蛋扯虾,虾扯蛋扯虾
点赞  2015-1-4 13:02
为什么我直接复制粘贴lz的代码,在LPM3时测得的电流为7.4uA呢
点赞  2015-12-22 16:58
引用: ytm1987 发表于 2015-12-22 16:58
为什么我直接复制粘贴lz的代码,在LPM3时测得的电流为7.4uA呢

会不会是外围电路引起的?
我把代码放到一楼地面了,你试试看。
虾扯蛋,蛋扯虾,虾扯蛋扯虾
点赞  2015-12-22 17:13
引用: littleshrimp 发表于 2015-12-22 17:13
会不会是外围电路引起的?
我把代码放到一楼地面了,你试试看。

是金刚狼的板载仿真器导致的,当测试时把跳线帽去掉就可以了,谢谢!
还需要请教lz一个问题,我现在做的项目是平时处于低功耗状态,但需要以800Hz进行AD采样(越低约到),我现在用ADC12+timerA做到了56uA(ACLK=VLO),当AD大于一定值时,进入正常状态,此时对功耗要求不高,但对时间精度要求很高,我打算此时MCLK采用外部的16M晶振,但在实际测试中,只要16M晶振起振,在LPM3时功耗就到达150uA左右,我打算需要的时候在给外部16M晶振起振,可是无论是对PJSEL0操作还是 CSCTL4|=HFXTOFF;,程序都会复位,请问lz有没有好的解决方案?谢谢
点赞  2015-12-24 11:38
引用: ytm1987 发表于 2015-12-24 11:38
是金刚狼的板载仿真器导致的,当测试时把跳线帽去掉就可以了,谢谢!
还需要请教lz一个问题,我现在做的 ...

不知道你的配置是不是正确,另外你可以参考一下这个贴子,在16M主频下针对铁电存储器的时钟配置
https://bbs.eeworld.com.cn/thread-465164-1-1.html

QQ图片20151224132018.png
虾扯蛋,蛋扯虾,虾扯蛋扯虾
点赞  2015-12-24 13:23
FR5系列和6系列,低功耗LPM3以下,可以关闭CSCTL6的MCLKREQEN、SMCLKREQEN,不然系统用到这些时钟的模块,就会唤醒时钟,低功耗就白费了。
点赞  2017-7-20 16:11
多谢楼主解惑,
点赞  2018-5-29 18:45
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复