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低功耗【深度睡眠模式】【浅度睡眠模式】【进入睡眠模式后要等待硬件进入睡眠】【内部上拉电阻对功耗的影响】【测试低功耗步骤】相关推荐

  1. stm32设置内部上拉电阻_不知道STM32的GPIO8种模式如何设置?-------看这里

    一.推挽输出: 可以输出高.低电平,连接数字器件:推挽结构一般是指两个三极管分别受两个互补信号的控制,总是在一个三极管导通的时候另一个截止.高低电平由IC的电源决定. 推挽电路是两个参数相同的三极管或 ...

  2. IIC通信为什么使用开漏输出+上拉电阻的模式

    目录 前言 一.什么是开漏输出和推挽输出 推挽输出和开漏输出 二.开漏和推挽的区别 三.开漏输出上下拉电阻应用 总结 前言 最近遇到技术群里有小伙伴在问为什么IIC通信需要挂上拉电阻,查阅了一些资料做 ...

  3. 计算机睡眠状态好处,电脑待机后怎么唤醒的方法 睡眠待机优势介绍

    当我们把鼠标拖动到惯技处时,我们可以发现,实际上电脑包括关机.重启与睡眠三种选择.睡眠的意思是指你暂时不需要用到电脑,但是等你需要用的时候所以界面都能保持原样.但是很多人不知道睡眠之后应该如何唤醒呢? ...

  4. 芯片管脚工作在各个模式的特点和优缺点(持续更新)加上下拉电阻的作用

    一.推挽输出:可以输出高.低电平,连接数字器件:推挽结构一般是指两个三极管分别受两个互补信号的控制,总是在一个三极管导通的时候另一个截止.高低电平由IC的电源决定.         推挽电路是两个参数 ...

  5. STM32八种IO口模式区别,以及上拉输入、下拉输入、浮空输入、模拟输入的区别

    最近在看数据手册的时候,发现在 Cortex-M3 里,对于 GPIO 的配置种类有 8 种之多: (1)GPIO_Mode_AIN 模拟输入 (2)GPIO_Mode_IN_FLOATING 浮空输 ...

  6. wringPi 初始化GPIO 为上拉_你彻底弄清GPIO内部结构和各种模式了吗?

    据说能将处理器的GPIO(General Purpose Input and Output)内部结构和各种模式彻底弄清楚的人并不多?那现在就让多一点 GPIO的功能,简单说就是可以根据自己的需要去配置 ...

  7. stm32f103 spi slave从机模式miso需要上拉

    stm32f103t8u6 spi slave从机模式 miso管脚需要上拉电阻!! 测试了20K阻值的无效,2K有效!

  8. 进程线程(六) 深度睡眠 和 浅度睡眠

    1.深度睡眠TASK_UNINTERRUPTIBLE和浅度睡眠TASK_INTERRUPTIBLE 浅度睡眠代码模板 2.为什么需要深度睡眠? 深度睡眠是不可避免的 读磁盘的时候,就是深度睡眠. 程序 ...

  9. 计算机休眠快还是关机快,电脑关机、休眠、睡眠、快速启动模式的区别介绍

    大家的电脑在关机的时候,一般都可以看到有好几个选项,包括睡眠.休眠.待机.关机.重启等等,不同的场景使用不同的模式,合理使用会使得工作效率事半功倍. 电脑电源模式你都了解吗? 那么,电脑睡眠和休眠有什 ...

最新文章

  1. 如何设置 Linux 上 SSH 登录的 Email 提醒
  2. 拉格朗日乘子法学习[转载]
  3. Python 私有变量的访问和赋值
  4. JPA教程:实体映射-第3部分
  5. android 视图覆盖,如何在Android中添加覆盖视图超过其他视图?
  6. 轻松实现无刷新三级联动菜单[VS2005与AjaxPro]
  7. HTML 事件响应函数,HTML5: 事件处理函数的this指向问题
  8. 温故js系列(4)-运算符详解
  9. 【PL/SQL】PL/SQL介绍
  10. redis 主从不同步连接不上
  11. cadnaa噪声分析测试软件,Cadna/A软件介绍
  12. 最新泛微java面试题及答案
  13. C语言IDE推荐code::blocks
  14. 预测模型构建利器——基于logistic的列线图(R语言)
  15. zigbee加PA信号增强方案:rfx2401+cc2530
  16. java多页码分页_对页码进行分页
  17. Matplotlib-散点图详解
  18. 为什么我们要掌握Linux系统编程?
  19. 互联网等三行业跻身VC投资前三甲
  20. git安装配置及第一次上传项目到github

热门文章

  1. 耳鸣是什么原因造成的?
  2. 当心做友情链接导致你网站被降权
  3. 国产W806 SPI主机/从机驱动程序
  4. Minix3进程概述
  5. 天载股票资讯低估值高分红个股仍是布局方向
  6. Android Studio安装教程(超级详细)
  7. 怎么购买 nest_购买Nest恒温器时如何省钱
  8. python模拟别人说话的声音_如何用100行Python代码做出魔性声控游戏“八分音符酱”...
  9. 【多视图几何】TUM 课程 第3章 透视投影
  10. 家用燃气灶点火电路图