经过多年的低功耗硬件设计(公司硬件设计和软件设计是分开的,我一直是做硬件的,面对低功耗生产事故往往很难做硬件),遇到的问题之一很容易出现单片机进入睡眠模式之前IO没有正确配置。 该产品的主要问题是有问题的IO相对隐蔽。 经过当时多次测试,都没有被发现。 后来在生产或者现场发现概率功耗过高。 问题。
从硬件角度来看,我最近意识到软件中的一个常见错误是在进入睡眠之前没有重新配置所有IO,这很容易导致低功耗IO bug。
本次经验总结是:在进入睡眠模式之前,需要将代码1 IO到1 IO所使用的单片机的所有IO都配置好。 不要偷懒,不要将多个IO配置在一起。
分析:
外设时钟
外设的时钟没有关闭,单片机的内部模块没有关闭等。有的单片机进入睡眠后会自动关闭,有的则不会自动关闭。 如果不关闭,现场测试时功耗会很高,很快就能发现。 所以在实际生产中并没有出现任何问题。
IO配置
配置1个IO连接到1个IO。 不要将多个 IO 配置在一起,如 BIT1|BIT2…、|=0xxx。 因为代码越直观,出现笔误的概率就越低。 而我们在检查IO的时候,总是一一检查配置是否正确。 所以把代码一一写下来其实并不需要太多的时间和代码空间。 需要5到30分钟才能走完,但后面节省的时间和金钱就很难说了。 人总是很懒的。 我自己写代码的时候,只配置了一部分,就进入了低功耗。 现在我正在慢慢习惯所有的配置。 很多配置可以复制之前的IO初始化(这个已经开发了1个IO了,1个IO的配置其实改起来很舒服)。
案例分析
实际发生的最麻烦、最隐蔽的情况往往与IO配置有关。 配置越简单,就越容易出现问题。
1、比如大多数情况下,程序从A子程序进入睡眠后IO配置没有问题,经过大量测试也没有发现问题。 但是当B执行完然后进入睡眠时,在B中操作了IO,但是再次进入睡眠时IO没有变回来,那么可能会出现问题。 而如果执行了C、D…等程序然后睡眠,就不会有IO的隐患了。
案例:客户发现约50%的产品在放置一段时间后电量耗尽。 研发团队很困惑。 多次检查代码,没有发现问题,之前也不存在崩溃问题(崩溃会导致无法进入低功耗和功耗极高)。 我们派人进行了现场测试,经过大量测试,我们发现IO部分产品的产量很高。 结果,电流多了约1mA。 原因是客户上电后进行第二次脉冲输出,产品断电后由电池供电。 客户在断电前没有配置关闭第二脉冲输出,程序断电后也没有重新配置IO,导致IO输出有50%的概率为高电平。
2、某产品生产了几万台,没有发现任何问题。 后来转用PCB厂家生产后发现部分产品功耗过高,大约10uA。 研发拿回来分析,发现还是换芯片比较好。 但如果生产中存在百分之几的功耗不良,芯片就不可能以这么高的概率损坏。 430芯片,来自正规供应商。 经过一一查找IO,通过触摸IO,终于发现与光耦输入端连接的IO配置为输入模式。 更换芯片是因为焊锡了,板子脏了,电阻变小了。 IO对GND的电压有一个相对固定的偏置,所以没有问题。 之前没有任何问题。 可能是板子的电阻比现在的小,或者是生产时湿度比较大,或者是光耦的反向漏电流比较大。 有多种可能性。 软件发现这个IO本来配置没有问题,但是不知道在哪里配置或者配置其他IO时不小心配置了这个IO。 总之,当时我并没有发现这个IO的配置有什么变化。 我只是在进入低功耗之前重新配置了这个IO。
3、产品使用的外包低功耗射频模块存在IO问题。 使用 CC1101 和 430F2132。 它们都被认为是低功耗芯片。 我找到了两家公司来开发模块。 第一家公司没有配置2132的IO,在生产阶段发现部分产品功耗过高。 后来由于领导原因,换了无线厂商来做这个,仍然是CC1101+2132的方案。 按理说,如果你以前犯过错误,你就应该吸取教训。 而且软件人员也是退伍军人。 结果,生产上没有出现任何问题。 然而,部分产品在发货给客户时发现了一些问题。 最后发现是某个IO没有配置好。
4、上面的感受很简单,但却是多次花费时间和金钱后获得的痛苦经验。 而这些都是软件问题,但功耗问题往往首先是在硬件上发现的:你设计的产品功耗高,电池没电了。 你检查一下看看出了什么问题。 做硬件的人打不开代码,软件的人一开始往往不承认IO配置有问题,尤其是外部厂家开发的模块。 他们的意思是,我做软件已经xx年了。 开发了这么多产品,这么简单的产品怎么会出问题呢? 问题是你自己的产品没做好造成的。 辛勤的硬件工程师无奈,只能想各种办法来查找出现问题的IO。 软件工作人员修改代码后完成了对比测试,但最终软件仍然不肯说自己的代码有问题。
5.关于IO的问题。 430单片机的IO设置是最弱的。 大多数都没有上拉和下拉电阻。 默认为输入状态。 如果不配置IO,很容易造成功耗问题。 ST的相对好一些。 51默认的51 IO状态有上拉电阻。 不用的脚不配置的话是没有问题的。 我以前喜欢配置空IO输出0状态。 最近用STM8S看代码,发现喜欢配置成上拉输入状态。 STM8S没有下拉电阻,但STM32有。 最好配置为下拉输入状态。 如果不小心遇到的话,会向外输出电流。
题外话:关于单片机的低功耗模式,之前对STM32了解不深。 我最近发现,当进入功耗最低的STANDBAY模式时,RAM中的数据对会丢失。 这还不如8位机。 以前用STC的51和STM8系列从来没有担心过。 RAM 数据丢失问题。 STM32L系列在功耗最低的时候也存在这个问题,但是可以断电保护的RAM区域被划分为更多更大的区域。