本帖最后由 我的孤独 于 2019-9-21 19:17 编辑
前言
资料来源:
(1)2月2号-外置采集温度_让arduino用2颗5号电池运行1年以上
(2)C:\Program Files (x86)\Arduino\hardware\tools\avr\avr\include\avr目录下的sleep.h里的例程
(3)ATMEGA328P详细资料数据手册(提取码:qft2),第302页(ACSR寄存位配置)和第319页(ADCSRA寄存位配置)
(4)ACSRACSR寄存位配置中文翻译
因为本人在做一个便携的自动浇水系统,只用电池和太阳能板供电,所以不浇水时需要用到休眠模式,以增加续航。
浇水部分已经完成,休眠部分完成一半还未整合进浇水系统,先上浇水系统给大家看看,看视频点这里。
本文使用干掉电源指示灯的arduino pro mini进行测试。
ACD、ADC的开关配置
接下来是本篇文章的重点之一,ACD、ADC的配置。
我查询了ATMEGA328P详细资料数据手册以及网上的其他文章,得知:
休眠前关闭ACD和ADC更省电,0.12ma,不关ACD和ADC就休眠,0.26ma,这样我们又省了一半的电。
但是不知道关闭ACD和ADC后会不会对后续的外部中断的唤醒休眠有影响,有待测试。
接下来我们看一下如何开启和关闭ACD、ADC,代码如有错误请指出。 - //ON ACD
- ACSR &= ~_BV(ACIE); //禁止模拟比较器中断后再对ACD位操作,否则ACD位变化会发生中断,写入0关闭
- ACSR &= ~_BV(ACD); //开启模拟比较器
- ACSR |= _BV(ACIE); //开启模拟比较器中断
- //ON ADC
- ADCSRA |= _BV(ADEN); //ADC使能开启
- ADCSRA |= _BV(ADIF); //ADC中断使能开启
- //OFF ACD
- ACSR &= ~_BV(ACIE); //禁止模拟比较器中断后再对ACD位操作,否则ACD位变化会发生中断,写入0关闭
- ACSR |= _BV(ACD); //关闭模拟比较器 ,写入1关闭
- //OFF ADC
- ADCSRA |= _BV(ADIF); //清除标志,写1清除
- ADCSRA &= ~_BV(ADIE); //ADC中断使能关闭
- ADCSRA &= ~_BV(ADEN); //ADC使能关闭,写入0关闭
复制代码 这段代码,也就是ACD、ADC的配置说明可以从手册里查出。
第302页(ACSR寄存位配置)和第319页(ADCSRA寄存位配置)。
休眠模式
接下来是休眠模式,我直接使用了文章2月2号-外置采集温度_让arduino用2颗5号电池运行1年以上里的部分代码,并做了一下改进和注释。 原文章把休眠模式已经说的很清楚了,我就不多做介绍了。 需要注意的地方是sleep_mode()这个API,根据sleep.h文件里的说明使用sleep_mode()可能会在某些状态下失效。 所以,根据例程,我将进入休眠模式的步骤改成: cli(); //关闭全局中断,防止中断引起意外 set_sleep_mode(SLEEP_MODE_PWR_DOWN); //这里设置睡眠模式 sleep_enable(); //开启休眠功能 sei(); //开启全局中断 sleep_cpu(); //进入休眠 sleep_disable(); //关闭休眠功能 sei(); //开启全局中断
所以,在休眠前是否要开关ADC/ACD,进入休眠的方式是否要使用sleep_mode()或者我的分步进入,看个人所需。
|