做了个多功能时钟,只因我解决了这4个问题,续航24天超轻松!

做了一个能常亮24天的多功能时钟,也是一个指南针!

做了个多功能时钟,只因我解决了这4个问题,续航24天超轻松!

为什么它能续航这么久?我做对了什么?(见第3章)

其有哪些功能?(见第1章)

硬件设计注意事项?(见第2章)

下面就一一为你解答!

一、时钟的功能/亮点展示

1.指南针功能

使用时先原地慢慢转一圈即可校准。

此模式下功耗:1.3mA

做了个多功能时钟,只因我解决了这4个问题,续航24天超轻松!

2.TV模式(时钟等基础显示)

40秒显示时间电池电量。

此模式下功耗:1.7~1.9mA

做了个多功能时钟,只因我解决了这4个问题,续航24天超轻松!

10秒显示温度、湿度、气压

做了个多功能时钟,只因我解决了这4个问题,续航24天超轻松!

10秒显示电池状态循环(持续时间可按喜好调整)

做了个多功能时钟,只因我解决了这4个问题,续航24天超轻松!

3.菜单设置

设置了三级菜单。

主菜单:见图,这里预设了16个二级菜单。

滚动时总功耗:2mA

做了个多功能时钟,只因我解决了这4个问题,续航24天超轻松!

二级菜单:见图,按确定进行设置

滚动时总功耗:4mA

做了个多功能时钟,只因我解决了这4个问题,续航24天超轻松!

三级菜单:见图,按确定进行设置

页面总功耗:1.4mA

做了个多功能时钟,只因我解决了这4个问题,续航24天超轻松!

支持开发:水平尺、增量闹钟、秒表、手电筒、系统设置、工厂模式

未来加入亮度自动调节机制,可坚持超过一个月

二、硬件说明

使用STC32F12K54芯片作为主控,在TV模式可运行大约24天,以下是相关电路图。

做了个多功能时钟,只因我解决了这4个问题,续航24天超轻松!

控制板原理图

做了个多功能时钟,只因我解决了这4个问题,续航24天超轻松!

控制板PCB图

做了个多功能时钟,只因我解决了这4个问题,续航24天超轻松!

电源板原理图

做了个多功能时钟,只因我解决了这4个问题,续航24天超轻松!

电源板PCB图

1.控制板参数介绍

主控:STC32F12K541.3寸OLED:SSD1315(使用SPI)温湿度计:SHT40气压计:SPL-06RTC:INS5699光强计:BH1745磁强计+加速度计:BMC050无源蜂鸣器(但有独立4K方波产生电路,不占用MCU资源)震动开关按键X5:+、-、确定键、退出键、复位键

2.电源板参数介绍

电源板2.8V空载,5V OFF的情况下,待机电流1.6uA(电池3.83V)

DC-DC锂电池充电:ME4059ASPG-N)锂电池保护:ME4211AM6GDC-DC降压(主板供电):TPS62740DSSRDC-DC升压(OLED供电):MT9700+MT3608L,可以通过主板的两个IO口控制反馈电阻,从而获得5V、6V、7V、8V充电电流检测:INA181A2IDBVT+50mΩ电阻

三、续航24天,我做对了什么?

本项目之所以可以这么省电,是因为MCU不会干多余的事情,有任务的时候才会运行,其他时间都在休眠。

但,事情怎么会这么简单呢?

1.发现的第一个问题

之前做第一代第二代时钟的时候,就发现一个事情:

MCU在执行任务的时候,很多时候都在delay

例如滚动数字的时候,平移32格像素,需要平移32次,每次平移后间隔6毫秒才能执行下一次的平移,这个时候,空跑的的时间就是31×6=186ms。

这是非常致命的。

如果一秒刷新一次,就有18.6%的时间浪费在等待上。

再例如给传感器发送测量指令后,需要等待一段时间才能读取测量后的值……

这一段时间也是需要等待的。

解决思路

为了解决MCU在等待时摸鱼的情况,可以让MCU在等待的时候进入掉电模式,从而降低功耗。

2.第二个问题

但这样又不得不面临一个新的问题,就是

MCU怎么知道自己什么时候醒过来?

解决思路

针对这个问题,可以使用:

掉电唤醒定时器

通过设置掉电唤醒定时器的时间,控制MCU休眠后在我们指定的时间醒过来

3.第三个问题

但这样又有一个问题,那就是:

MCU怎么知道下次什么时候醒过来?

例如执行一个32格像素的平移,要执行32次,MCU执行了第一次,它怎么知道还要执行32次间隔6ms的任务?

解决思路

为了解决这个问题,我想了个办法:

引入两个数组

一个是“休眠时间数组”,一个是“任务号数组”(每个bit代表一个任务),两个数组的值一一对应。

例如执行一个32格像素的平移,要执行32次,我就先在“休眠时间数组”和“任务号数组”中预约32个任务,如下图所示。

做了个多功能时钟,只因我解决了这4个问题,续航24天超轻松!

每次MCU检测数组“休眠时间数组”[0]和“任务号数组”[0]中的数值,如果不等于0,则将“休眠时间数组”[0]的值装入掉电唤醒寄存器,进行休眠,唤醒后再根据“任务号数组”[0]的值匹配相应的任务。

任务完成后整个数组的值向左移动一位。

当检测到“休眠时间数组”[0]和“任务号数组”[0]中的数值为0时,说明UI刷新任务已经完成,掉电唤醒寄存器关闭,彻底进入休眠,等待外部按键中断任务的唤醒。

但项目中并非只有一个OLED屏幕刷新的任务

对于传感器测量等待的任务,为了尽可能保证时效性,不可能排在UI刷新完成之后再测量。

我们当然希望能两不误。

这时就需要写插入算法将任务插入任务队列中。

例如在队列中插入一个气压测量的任务(“任务号数组”bit1 =1),需要等待15ms(6+6+3),插入上图的队列中,如下图。

可以看到当数值不可以重合时,需要打断队列插入数值。

做了个多功能时钟,只因我解决了这4个问题,续航24天超轻松!

再例如在队列中插入一个气压测量的任务,需要等待12ms,插入上图的队列中,如下图。

可以看到当数值重合时,不需要打断队列插入数值。

只需要添加任务号所对应的bit位。

做了个多功能时钟,只因我解决了这4个问题,续航24天超轻松!

4.第四个问题

到目前为止,低功耗任务预约的算法算是弄完了,但还有一个问题,就是:

在休眠的过程中,如果有外部中断输入,就会让MCU提前结束休眠。

这样可能会导致传感器采样异常,影响用户体验。

解决思路

这个时候,就需要:

优化睡眠的算法

检测醒来的时候,如果掉电唤醒寄存器内的时间还没有走完,就把值装填回去再次休眠,直到定时器内的值是0为止

5.最后一步,将MCU性能榨干

事情还没有结束,我们还可以进一步降低功耗,争取榨干MCU性能!

MCU最耗电的任务其实是在刷屏的时候——这时候使用SPI发送数据,需要MCU参与其中,不能去干别的事情。

这个时候我们可以使用DMA功能,使用双缓冲区,先装填1区,DMA发送1区的数据,在1区发送的时候,装填2区,轮流发送,循环往复,提高MCU的工作效率。

但单纯DMA发送数据的话,其实还是会更耗电。

因为需要将数据从flash搬到XRAM里面,再通过DMA发出去是需要时间的,效率上不如把flash的数据直接发送出去。

这个时候可以利用MCU进入停IDLE模式时,MCU停止工作,但外设还在可以工作的特点。

如果在2区填充完成,但1区还没发完的情况下,还可以让MCU进入停IDLE模式,这个时候MCU停止工作,但外设还在可以工作,在IDLE模式等待SPI DMA 发送完成后再唤醒执行别的程序。

这样功耗就可以进一步降低。

除此之外,还有各种优化局部刷新,一点点抠功耗,直至榨干最大性能价值……

参考资料:

[1]开源资料https://oshwhub.com/yq-qvq/low-power-consumption-for-24-days-desktop-clock

— 完 —

嘉立创EDA·头条号

关注我,看一手优质开源项目

免责声明:文章内容来自互联网,本站仅提供信息存储空间服务,真实性请自行鉴别,本站不承担任何责任,如有侵权等情况,请与本站联系删除。
转载请注明出处:做了个多功能时钟,只因我解决了这4个问题,续航24天超轻松! https://www.bxbdf.com/a/180461.shtml

上一篇 2025-04-10 23:15:08
下一篇 2025-04-10 23:22:04

猜你喜欢

联系我们

在线咨询: QQ交谈

邮件:362039258#qq.com(把#换成@)

工作时间:周一至周五,10:30-16:30,节假日休息。