zoukankan      html  css  js  c++  java
  • STM32F072单片机的低功耗实验/STOP模式低功耗调试

    这几天对公司的一个生产小工具进行了升级,由于准备将小工具发给客户使用,因此需要制作的精良一些,于是便卡在低功耗上。

    程序是公司前辈几年前写的,在stm32f042单片机中使用正常,自己画的第一版电路板也是f042单片机,刷进去程序后实测功耗低于0.01mA,万用表显示0.00mA。
    然而将程序刷进更新后的板子,功耗就上去了,达到了0.88mA,翻了百倍。
    好的起先是怀疑硬件电路问题,将外围电路拆除后,功耗竟然上升到1.5mA了。
    得,直接找了块新板子只焊了单片机和几个电容,测试还是1.5mA。
    这时候基本确定就是程序问题了,当然也有可能是我PCB画的有问题,但是检查了一会儿没发现什么问题,就直接去查程序了。


    在网络上检索了“stm32f0”“低功耗”“STOP模式”“停止模式”等关键词后,查询到了以下几篇文章,在这里只列出与现在的问题相关的,可能是检索词有问题,最后也只有这几篇文章。

    https://bbs.21ic.com/icview-329660-1-1.html

    http://www.stmcu.org.cn/module/forum/thread-613274-1-1.html

    https://bbs.21ic.com/icview-2533200-1-1.html

    https://blog.csdn.net/qq_16587307/article/details/81739838?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase

    https://blog.csdn.net/hanping1020/article/details/89431935
    前辈说可能是单片机有什么功能没有关掉,所以检索的时候也着重检索了“STOP模式”和“耗电”相关内容。

    翻了一会儿帖子,基本上都是说IO口配置没有配置好,觉得还是得自己尝试一下。
    在单片机开机时,将所有IO口都设置为下拉输入(注意:这里是因为当前PCB只焊了单片机,可以说所有引脚都是悬空状态),然后直接延时五秒钟,然后进入STOP模式,这里要注意一定要延时一会儿,不然接下来在STOP模式是无法下载程序的!
    程序下载进去,果然,5秒后进入停止模式,单片机功耗达到0.006mA。
    OK!
    接下来就是要测试一下什么程序没有关掉。
    ADC、USB、定时器、各IO模块晶振应该是全部关掉了,没有检查出什么问题来。
    这时候,重点来了,这时候心知肚明的是,一定是有什么东西没有关掉,但是不知道是哪里出的问题。
    !直接从初始化入手!
    把初始化部分的几个模块逐个注释掉!
    果然!注释到USB_Init();时,功耗没有了。
    就是USB的锅!
    继续检索,这时候检索到写一篇文章,在这里看到了大佬的留言:

      

    USB先复位,再关闭。

    检查一下自己的程序,只关闭了,没有复位。
    然后抱着试试看的成分在USB关闭之前,写了下面一句话:

    RCC->APB1RSTR = RCC_APB1RSTR_USBRST;

    我承认有赌的成分,可是......不好意思跳戏了......

    功耗正常了,就是USB的问题,USB的关闭除了需要关闭以下几个模块之外,需要先将USB复位。

    其实在测试过程中还有个小插曲,到了小插曲就基本上锁定了问题所在。因为同一个程序,在F042上ok,在F072上GG。区别是F042使用的20pin,F072使用的48pin,在引脚上除了普通IO口之外,有1个区别:
    F042的USB是使用的IO口复用功能,将PA9和10重映射到11和12,11和12这两个引脚拥有USB功能。

    总结一下,如果网友们有遇到停止模式或是睡眠模式功耗过高的问题,可以按以下顺序着手测试:
    1.先清除PCB上其他元器件,或是只焊单片机,确认GPIO全部悬空。
    2.程序初始化阶段,将所有GPIO置下拉输入,延时几秒钟,进入STOP模式或是SLEEP模式,检查功耗是否正常。一般而言,这一步如果正常,那么PCB的问题基本就排除了,当然前提是所有IO都是悬空状态,如果有直接接到VCC或是其他高电平处,该引脚置上拉输入。
    3.然后将自己的程序中的初始化部分逐个注释,排查是哪个模块没有关掉。到这一步基本能排查出问题了。
    4.根据第3步排查出的问题,检索解决办法。

    需要注意的是:要仔细观察功耗的变化,如果程序修改完功耗有变化,那么修改处一定是有问题的。

    再总结一下可能出现问题的地方:
    1.IO口配置,可先全部下拉,然后检查电路,对需要上拉的地方上拉。悬空脚、接地脚下拉,接VCC或其他高电平信号脚上拉。也可设置输出模式,具体输出当时可以自己测试一下。
    2.检查使用到的模块,USB,ADC等都是重点,像USB,要关的话,里面有很多地方都需要关,例如:

    CRS_AutomaticCalibrationCmd(DISABLE);
    CRS_FrequencyErrorCounterCmd(DISABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CRS, DISABLE); 
    NVIC_InitStructure.NVIC_IRQChannel = USB_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority = 1;
    NVIC_Init(&NVIC_InitStructure);    
    NVIC_DisableIRQ(USB_IRQn);
    RCC->APB1RSTR = RCC_APB1RSTR_USBRST;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, DISABLE);


    3.注意各模块关闭程序的顺序,例如:

    GPIO_InitStructure.GPIO_Pin =   GPIO_Pin_0 |GPIO_Pin_1;                
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_DOWN;
    GPIO_Init(GPIOF, &GPIO_InitStructure);
    
    RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOF, DISABLE);

    先设置下拉再关相关IO模块的时钟。对于每个模块,时钟最后关。

    -谢谢-

  • 相关阅读:
    小程序路由
    机器学习笔记—支持向量机(1)
    用极大似然估计法推出朴素贝叶斯法中的先验概率估计公式
    机器学习笔记—生成学习
    机器学习笔记—再谈广义线性模型
    机器学习笔记—指数分布簇和广义线性模型
    机器学习笔记—Logistic 回归
    机器学习笔记—局部权重线性回归
    机器学习笔记—线性回归
    机器学习笔记1
  • 原文地址:https://www.cnblogs.com/surer1213/p/13124641.html
Copyright © 2011-2022 走看看