SYD8801低功耗【深度睡眠模式】【浅度睡眠模式】【进入睡眠模式后要等待硬件进入睡眠】【内部上拉电阻对功耗的影响】【测试低功耗步骤】
SYD8801是一款低功耗高性能蓝牙低功耗SOC,集成了高性能2.4GHz射频收发机、32位ARM Cortex-M0处理器、128kB Flash存储器、以及丰富的数字接口。SYD8801片上集成了Balun无需阻抗匹配网络、高效率DCDC降压转换器,适合用于可穿戴、物联网设备等。具体可咨询:http://www.sydtek.com/
SYD8801的低功耗模式分为浅度睡眠和深度睡眠,其中浅度睡眠内存数据依旧能够保持,而深度睡眠下内存会被清空,两者比较如下:
注意:不管是深度睡眠还是浅度睡眠,在配置睡眠之前必须保证作为唤醒源的GPIO管脚对MCU而言是低电平,也就是说如果在睡眠的时候唤醒源GPIO外部状态为高电平,这里就必须要配置上gpio模块输入的反相器,也就是 PIN_CONFIG->PIN_13_POL寄存器,否则芯片不能够正确进入睡眠!
注意:如果调用协议栈lib提供的SystemSleep接口进入浅度睡眠,设置为唤醒源的IO口必须有中断的功能(使能该IO口的中断并且配置正确的回调函数)。
SYD8801深度睡眠低功耗模式
SYD8801的深度睡眠模式下芯片各部份工作情况如下:
主函数判断轮询读取按键0,如果发现按键0被按下,则调用PowerDown进行深度睡眠:
if(get_key()==1){
PowerDown();
}
PowerDown函数具体代码如下:
static void PowerDown()
{
struct gap_wakeup_config pw_cfg;
GPIO_Set_Input(KEY1,KEY1,KEY1); //key1 ·´Ïà
PIN_CONFIG->PIN_13_POL = PIN_INPUT_IVERTED;
if(GPIO_Pin_Read(KEY1)) return;
pw_cfg.wakeup_type = POWERDOWN_WAKEUP;
pw_cfg.timer_wakeup_en = 0;
pw_cfg.gpi_wakeup_en = 1;
pw_cfg.gpi_wakeup_cfg = KEY1;
WakeupConfig(&pw_cfg);
SystemPowerDown();
delay_ms(1);
}
这里配置了唤醒配置结构体 pw_cfg,其中有三个元素。pw_cfg.timer_wakeup_en代表定时器是否能唤醒MCU,为1代表定时器能够唤醒,为0代表定时器不能够唤醒;pw_cfg.gpi_wakeup_en代表GPIO管脚是否能唤醒MCU,为1代表GPIO能够唤醒,为0代表GPIO不能够唤醒,在GPIO能够唤醒的情况下pw_cfg.gpi_wakeup_cfg代表具体哪个GPIO能够唤醒MCU,比如0x00C00000代表gpio22和gpio23能够唤醒。
这里要注意:在SystemPowerDown函数之后调用 delay_ms(1);的微小延时,等待数字电路进入深度睡眠模式,否则深度睡眠很有可能不能够被按键唤醒!
注意:在配置深度睡眠之前必须保证作为唤醒源的GPIO管脚对MCU而言是低电平,也就是说如果在睡眠的时候唤醒源GPIO外部状态为高电平,这里就必须要配置上gpio模块输入的反相器,也就是 PIN_CONFIG->PIN_13_POL寄存器,否则芯片不能够正确进入睡眠!
这里上传本博客使用到的工程代码:
http://download.csdn.net/detail/chengdong1314/9818412
SYD8801浅度睡眠低功耗模式
SYD8801的浅度睡眠模式下芯片各部份工作情况如下:
当程序调用了SystemSleep函数的时候,MCU将进入浅度睡眠模式,所以必须把SystemSleep函数的调用放在合适的位置,建议放在主函数的主循环的最后面:
这里列出一个程序的主函数作为例子:
int main()
{
__disable_irq();
gpio_init();
#ifdef _DEBUG_
dbg_init();
dbg_printf("SYD Inc.\r\n");
#endif
ble_init();
oled_init();
oled_8x16str(0,0,"SYD Inc.");
timer_0_enable(32768, timer0_adv_callback);
StartAdv();
__enable_irq();
timer1s_inting=0;
while(1)
{
ble_sched_execute();
if(timer1s_inting){
timer1s_inting=0;
led_turn(LED0); // ·×ªLED0 ָʾ³ÌÐòÔËÐÐ
cnt_1s++;
if(cnt_1s>=180)
{
cnt_1s=0;
#ifdef USER_32K_CLOCK_RCOSC
LPOCalibration(); //ÕâÊÇÄÚ²¿RC32k¾§ÕñµÄУ׼º¯Êý ¾¹ý¸Ãº¯Êýºó¶¨Ê±Æ÷Äܹ»µÃµ½Ò»¸ö±È½Ï׼ȷµÄÖµ
//timer_calender_handle(); ÄÚ²¿¾§Õñ¼´Ê¹Ð£×¼ÒÀ¾ÉÓÐÒ»¸ö¹Ì¶¨µÄÆ«²î
#else
ClockSwitch(SYSTEM_32K_CLOCK_XOSC);
#endif
}
}
if(get_key()==1){
PowerDown();
}
#ifdef USER_MARCHE_STATE
march_state_process();
#endif
SystemSleep();
}
}
执行了SystemSleep();函数之后MCU就停止了,定时器中断发生或者IO口唤醒源的电平发生变化的时候,MCU从停止的地方开始执行;如果是定时器中断唤醒了MCU,那么MCU醒来的第一步就是执行定时器中断服务函数,如果IO口唤醒源配置成中断模式并且MCU由IO口唤醒,那么MCU醒来的第一步就会去执行外部中断服务函数!
如果蓝牙处于连接状态,那么不用做任何配置,当底层硬件发现蓝牙的状态发生改变的的时候(比如发生了断线或者和主机之间发生了数据通信)MCU也会被蓝牙硬件唤醒,进入蓝牙的中断!
注意:当发生了唤醒事件的时候,只有再次调用SystemSleep();函数之后MCU才会再次休眠!
浅度睡眠配置在ble_init函数中,其源代码如下:
static void ble_init()
{
struct gap_evt_callback evt;
struct smp_pairing_req sec_params;
struct gap_wakeup_config pw_cfg;
struct gap_ble_addr ble_addr;
BleInit();
MCUClockSwitch(SYSTEM_CLOCK_8M_RCOSC);
#ifdef USER_32K_CLOCK_RCOSC
ClockSwitch(SYSTEM_32K_CLOCK_RCOSC);
LPOCalibration();
#else
ClockSwitch(SYSTEM_32K_CLOCK_XOSC);
#endif
GetGATTReportHandle(&g_report);
/* security parameters */
sec_params.io = IO_NO_INPUT_OUTPUT;
sec_params.oob = OOB_AUTH_NOT_PRESENT;
sec_params.flags = AUTHREQ_BONDING;
sec_params.mitm = 0;
sec_params.max_enc_sz = 16;
sec_params.init_key = 0;
sec_params.rsp_key = (SMP_KEY_MASTER_IDEN |SMP_KEY_ADDR_INFO);
SetSecParams(&sec_params);
evt.evt_mask=(GAP_EVT_CONNECTION_SLEEP|GAP_EVT_CONNECTION_INTERVAL);
evt.p_callback=&ble_evt_callback;
SetEvtCallback(&evt);
/* Bond Manager (MAX:10) */
SetBondManagerIndex(0x00);
setup_adv_data();
pw_cfg.wakeup_type = SLEEP_WAKEUP;
pw_cfg.timer_wakeup_en = 1;
pw_cfg.gpi_wakeup_en = 0;
pw_cfg.gpi_wakeup_cfg = 0x00C00000;
WakeupConfig(&pw_cfg);
}
其中配置了唤醒配置结构体 pw_cfg,其中有三个元素。pw_cfg.timer_wakeup_en代表定时器是否能唤醒MCU,为1代表定时器能够唤醒,为0代表定时器不能够唤醒;pw_cfg.gpi_wakeup_en代表GPIO管脚是否能唤醒MCU,为1代表GPIO能够唤醒,为0代表GPIO不能够唤醒,在GPIO能够唤醒的情况下pw_cfg.gpi_wakeup_cfg代表具体哪个GPIO能够唤醒MCU,比如0x00C00000代表gpio22和gpio23能够唤醒。
注意:在配置浅度睡眠之前必须保证作为唤醒源的GPIO管脚对MCU而言是低电平,也就是说如果在睡眠的时候唤醒源GPIO外部状态为高电平,这里就必须要配置上gpio模块输入的反相器,也就是 PIN_CONFIG->PIN_13_POL寄存器,否则芯片不能够正确进入睡眠!
这里上传上本节的代码:http://download.csdn.net/detail/chengdong1314/9865161
内部上拉电阻对功耗造成的影响
SYD8801每个IO口都可以配置成上拉输入,通过PIN_CONFIG->GPIO_PULL_UP寄存器打开或关闭芯片IO口内部的上拉电阻,因为上拉电阻的一端连接VDDIO,一端连接外部输入管脚,一般情况下把VDDIO连接到芯片的供电端,也就是3.3V电源供电口。
如果外部管脚为高电平,外部管脚电压等于VDDIO,所以上拉电阻没有电流流过,也就没有了电流损耗。
如果外部管脚为低电平,电流就会通过VDDIO流经上拉电阻R到管脚地,这样不可避免的产生漏电电流造成功耗增大,因为SYD8801内部上拉为80K欧姆,所以将有41.25ua的电流流过上拉电阻,也就是说这个IO口将增加41.25UA的功耗。
在追求功耗的时候,为了避免上面这个IO口的41.25UA的功耗,必须去掉芯片内部的IO口上拉电阻!因为在追求功耗的时候,整体芯片的电流都没有这个上拉电阻大!SYD8801手环整机电流才是22UA左右!
另外对于配置成输入的IO口而言,管脚电平必须是一个明确的状态,也就是说当某个管脚配置成输入模式,那么这个管脚要么是高电平,要么是低电平,不能是除此之外的电压值,否则会造成漏电,并且这个IO口也是极其不稳定的。如果外部连接的是按键,在未按下按键的时候很有可能管脚状态就是悬空状态。所以这时候就必须要使能内部上拉电阻,让悬空状态变成高电平状态!
但是如果使能了上拉电阻,那么上面说到的IO口上拉电阻造成的41.25UA的电流就不可避免了!
如果在必须要用上拉电阻但是又要追求功耗,那么建议关闭内部上拉电阻,在外部电路做一个1M以上的上拉电阻,能把功耗减小到3.3UA。但是这样的电路在干扰强的情况下很有可能受到干扰,所以请开发者综合考虑!
进入睡眠模式后要等待硬件进入睡眠
void SystemSleepSYD(enum WAKEUP_TYPE wakeup ,uint8_t timer_wakeup_en,uint8_t gpio_wakeup_en,uint32_t io)
{
PW_CTRL->WAKE_PIN_EN |= io ;
PW_CTRL->TMR_WAKE_EN = timer_wakeup_en;
PW_CTRL->PIN_WAKE_EN = gpio_wakeup_en;
PW_CTRL->DSLP_WAKE_EN = wakeup;
if(wakeup==SLEEP_WAKEUP)
{
PW_CTRL->MCU_SLEEP=1; //执行这句话后马上进入浅睡眠模式,任何东西都不会丢失
}
else
{
led_close(LEDALL);
PW_CTRL->DSLP_SYS = 1; // 执行这句话后马上进入深度睡眠模式,唤醒将会进入复位状态,任何东西都将会丢失
while(1);
}
}
上面的代码在else分支中“led_close(LEDALL);”语句必须要在“PW_CTRL->DSLP_SYS = 1;”语句之前,因为“PW_CTRL->DSLP_SYS = 1;”之后软件虽然向硬件发送了进入深度低功耗的请求,但是硬件并没有马上能够进入深度睡眠,会顺延执行下面几条命令后硬件才能够反应过来。如果“led_close(LEDALL);”语句必须要在“PW_CTRL->DSLP_SYS = 1;”语句之后,那么在软件配置了深度睡眠之后又重新给gpio赋值,这就相当于唤醒了MCU,造成进入深度睡眠之后MCU马上又被唤醒复位了,也就是深度睡眠的现象变成了复位的现象!
当然这里也可以把“led_close(LEDALL);”语句放在“PW_CTRL->DSLP_SYS = 1;”语句之后,但是这两个语句之间必须要加上100us以上的延时,但是这时候“led_close(LEDALL);”语句永远也得不到运行了!
上面函数可做如下调用:
PIN_CONFIG->PIN_8_POL = PIN_INPUT_IVERTED;
SystemSleepSYD(POWERDOWN_WAKEUP, 0, 1, BIT8);
注意:软件要等待硬件的现象在其他系统行为中也有可能存在,必须说调用复位命令让MCU复位的时候在调用命令之后也必须等待硬件相应!复位行为请看:SYD8801代码解析二【复位等特殊系统行为要等待硬件响应】:http://blog.csdn.net/chengdong1314/article/details/73929998
低功耗测试步骤:
低功耗的测试步骤分为三步:分别烧录4K_setting、service、hex三个文件,其中4K_setting由原厂提供,只有这样才能够得到正确的低功耗!
下面简单的列出了烧录步骤,更加详细的步骤请看:http://blog.csdn.net/chengdong1314/article/details/70161095
对于批量生产的时候有专门的批量烧录工具,请看:http://blog.csdn.net/chengdong1314/article/details/68489039
1. 电脑连接上开发板的串口,打开串口,并且按下复位键,这时候PC上的工具界面如下:
2、在“setting”选项中选择官方提供的4k固件(已改在得到的工程文件中都有,以4K开头的bin文件),选择结束之后这个工具自动把固件下载到芯片中:
2. 烧写配置ROM代码的服务配置文件(随软件一起提供的TXT文件),比如《Vendor_Service_GATT_DB_160804.txt》,如下:
3. 最后烧写工程代码生成的hex文件,比如《Ble_Vendor_Service.hex》:
对于SYD8801开发板:
芯片消耗的电流是VBAT,而IO口的漏电是VDDIO,这两者加起来是SYD8801消耗的总电流,这两个电流在开发板上的J7上可以测试,原理图如下:
这里可以把J7的2和4管脚短路,这时候从3.3V电源留到J7的2和4的电流总和就是要测试的芯片电流,连线示意图如下:
SYD8801低功耗【深度睡眠模式】【浅度睡眠模式】【进入睡眠模式后要等待硬件进入睡眠】【内部上拉电阻对功耗的影响】【测试低功耗步骤】相关推荐
- stm32设置内部上拉电阻_不知道STM32的GPIO8种模式如何设置?-------看这里
一.推挽输出: 可以输出高.低电平,连接数字器件:推挽结构一般是指两个三极管分别受两个互补信号的控制,总是在一个三极管导通的时候另一个截止.高低电平由IC的电源决定. 推挽电路是两个参数相同的三极管或 ...
- IIC通信为什么使用开漏输出+上拉电阻的模式
目录 前言 一.什么是开漏输出和推挽输出 推挽输出和开漏输出 二.开漏和推挽的区别 三.开漏输出上下拉电阻应用 总结 前言 最近遇到技术群里有小伙伴在问为什么IIC通信需要挂上拉电阻,查阅了一些资料做 ...
- 计算机睡眠状态好处,电脑待机后怎么唤醒的方法 睡眠待机优势介绍
当我们把鼠标拖动到惯技处时,我们可以发现,实际上电脑包括关机.重启与睡眠三种选择.睡眠的意思是指你暂时不需要用到电脑,但是等你需要用的时候所以界面都能保持原样.但是很多人不知道睡眠之后应该如何唤醒呢? ...
- 芯片管脚工作在各个模式的特点和优缺点(持续更新)加上下拉电阻的作用
一.推挽输出:可以输出高.低电平,连接数字器件:推挽结构一般是指两个三极管分别受两个互补信号的控制,总是在一个三极管导通的时候另一个截止.高低电平由IC的电源决定. 推挽电路是两个参数 ...
- STM32八种IO口模式区别,以及上拉输入、下拉输入、浮空输入、模拟输入的区别
最近在看数据手册的时候,发现在 Cortex-M3 里,对于 GPIO 的配置种类有 8 种之多: (1)GPIO_Mode_AIN 模拟输入 (2)GPIO_Mode_IN_FLOATING 浮空输 ...
- wringPi 初始化GPIO 为上拉_你彻底弄清GPIO内部结构和各种模式了吗?
据说能将处理器的GPIO(General Purpose Input and Output)内部结构和各种模式彻底弄清楚的人并不多?那现在就让多一点 GPIO的功能,简单说就是可以根据自己的需要去配置 ...
- stm32f103 spi slave从机模式miso需要上拉
stm32f103t8u6 spi slave从机模式 miso管脚需要上拉电阻!! 测试了20K阻值的无效,2K有效!
- 进程线程(六) 深度睡眠 和 浅度睡眠
1.深度睡眠TASK_UNINTERRUPTIBLE和浅度睡眠TASK_INTERRUPTIBLE 浅度睡眠代码模板 2.为什么需要深度睡眠? 深度睡眠是不可避免的 读磁盘的时候,就是深度睡眠. 程序 ...
- 计算机休眠快还是关机快,电脑关机、休眠、睡眠、快速启动模式的区别介绍
大家的电脑在关机的时候,一般都可以看到有好几个选项,包括睡眠.休眠.待机.关机.重启等等,不同的场景使用不同的模式,合理使用会使得工作效率事半功倍. 电脑电源模式你都了解吗? 那么,电脑睡眠和休眠有什 ...
最新文章
- 如何设置 Linux 上 SSH 登录的 Email 提醒
- 拉格朗日乘子法学习[转载]
- Python 私有变量的访问和赋值
- JPA教程:实体映射-第3部分
- android 视图覆盖,如何在Android中添加覆盖视图超过其他视图?
- 轻松实现无刷新三级联动菜单[VS2005与AjaxPro]
- HTML 事件响应函数,HTML5: 事件处理函数的this指向问题
- 温故js系列(4)-运算符详解
- 【PL/SQL】PL/SQL介绍
- redis 主从不同步连接不上
- cadnaa噪声分析测试软件,Cadna/A软件介绍
- 最新泛微java面试题及答案
- C语言IDE推荐code::blocks
- 预测模型构建利器——基于logistic的列线图(R语言)
- zigbee加PA信号增强方案:rfx2401+cc2530
- java多页码分页_对页码进行分页
- Matplotlib-散点图详解
- 为什么我们要掌握Linux系统编程?
- 互联网等三行业跻身VC投资前三甲
- git安装配置及第一次上传项目到github