关于ADC从STOP模式唤醒后的坑

  • 之前写过关于MCU内部参考电压的文章,不熟悉的话可以点击直达 MCU内部参考电压几种妙用你都知道嘛
  • 近期回顾测试中却发现唤醒后测量内部电压的数值是有问题的,带问题运行这么久也真是…[捂脸(*/ω\*)]

发现问题

  • 进入停止模式前为了更节省能源,对ADC进行了HAL_ADC_DeInit(&hadc),并在唤醒后对其进行了MX_ADC_Init()重新开启再测量。本以为就OK了,实际运行中不知道是不是没遇到过电压掉下阈值的情况,反正也没触发相应动作就没管了…哎,测试不到位啊,深刻反省中… …
  • 问题还是在一次调试中暴露了,发现用HAL_ADC_GetValue(&hadc)获取值后计算出来是有问题的,是一个极大的数(对测量电压毫无意义),于是开始找问题。

排查原因

1. 起初,以为是进入STOP模式前开启的HAL_PWREx_EnableUltraLowPower()HAL_PWREx_EnableFastWakeUp()引起的。
: 这两个API大致作用是忽略唤醒后ADC的恢复时间同时让ADC在STOP下不再工作,进一步减低了功耗。
  • 于是就在唤醒后又用HAL_PWREx_DisableUltraLowPower()HAL_PWREx_DisableFastWakeUp()把他们失能了。但… …并没有什么luan用。
2. 再来,是不是因为偷懒,所以唤醒后没有重新配置时钟导致ADC初始化不成功呀…
: 唤醒前用的就是HSI,而唤醒后MCU默认就是HSI,所以没有再次去初始化时钟
  • 那就加上嘛,吭哧吭哧把Cube生成的从SystemClock_Config()MX_XXX_Init()都加到唤醒后第一条开始执行… …依然没有什么作用,通过调试ADC寄存器发现还是没有任何位被置起,也就是ADC初始化无效。
3. 秉承着有问题,找售后的原则,开始在官方生成的库HAL文件中翻来翻去,看看接口注释上是不是有什么提示。
  • 还是找到了,在HAL_ADC_Init()的注释中发现这么一段:

在这里插入图片描述

  • HAL_ADCEx_EnableVREFINT()是个什么,进去看看

在这里插入图片描述

  • 原来问题在这里呢,HAL_ADCEx_EnableVREFINT()把使用的内部参考电压Vrefint缓冲区重新使能,并且从低功耗模式唤醒后一定要在HAL_ADC_Init()之前使用

解决问题

  • HAL_ADCEx_EnableVREFINT()加到唤醒后对ADC初始化HAL_ADC_Init()的前面,终于OK了,读数正常,问题解决。

碎碎念

  • 使用官方提供的API,如果遇到问题,看看注释中使用注意事项没准会有提示的,也希望以后官方可以把"在什么情况下调用就一定要做什么的事情一并写到接口中直接运行,减少这种令人摸不着头脑的情况"… …
发布了22 篇原创文章 · 获赞 29 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/Emmy_kanly/article/details/103968612
今日推荐