历史上的今天

今天是:2024年11月14日(星期四)

2019年11月14日 | STM8的停机模式

发布者:小熊掌心 来源: 51hei关键字:STM8  停机模式  低功耗 手机看文章 扫描二维码
随时随地手机看文章

首先,STM8有三种低功耗模式,即等待、活跃停机和停机。具体它们三者有什么区别自己看官方手册去吧,


这里只讲停机模式的应用,其他的一笔带过!



一、进入的方式:

等待模式进入用的指令是WFI,而活跃停机和停机用的都是halt(),所不同的是,在执行halt指令之前,如果开


启了AWU,则是活跃停机,反之则是停机。还有一点要说明的是,在停机模式下独立看门狗是不能养的,而只


能养窗口看门狗。


二、具体进入的步骤:

1、首先,你声明一个标志位,名字自己取。这个标志位是用来判断系统是该处于运行模式还是处于停机模式的。


我这里用fPowerOn_flag,如下:


bool fPowerOn_flag = FALSE;

有了这个标志位以后就写下面的部分了:



int main(void)

{

  //设置内部16M晶振为系统时钟

  Clk_Init(); //系统时钟初始化函数

  MWWDG_Init();//窗口看门狗初始化函数

 

  while (1)

  {  

    Free_WWDG();//喂狗函数

    if(fPowerOn_flag == FALSE){

      Halt_OffDevice();//停机前关闭不需要的外设

      halt();//进入停机模式

      System_Init();//系统初始化函数

    }

    

    if(fPowerOn_flag){

    //运行代码在这里添加

    }

  }

}

以上就是一个停机模式的模板了,大家参照着用就可以了。系统上电默认是进入停机模式,然后通过按键唤醒

进入运行模式。下面为大家讲一下主函数中每个函数的写法和功能吧!


2、各函数说明:

a、时钟初始化函数:



void Clk_Init(void)                

{

  CLK_DeInit();//复位时钟寄存器

  CLK_HSICmd(ENABLE);//使能内部高速时钟

  CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV4);//配置内部高速时钟(时钟分频器:4分频),系统时钟4MHz

  CLK_ClockSecuritySystemEnable();//开启时钟安全系统

}

这个函数我想不用多讲了,大家都懂的。

b、窗口看门狗函数:


void MWWDG_Init(void)

{

  WWDG_Init(COUNTERINIT, WINDOW);//COUNTERINIT = 0x7f,WINDOW = 0x77

}

这个是窗口看门狗初始化函数。

void Free_WWDG(void)

{

  INT8U CounterValue;

  CounterValue = (INT8U)(WWDG_GetCounter() & 0x7F);

  

  /* 

   * 判断是否小于所设置的窗口上限值 

   * 只有小于窗口上限值才能清零

   */

  if(CounterValue < WINDOW){

    WWDG_SetCounter(COUNTERINIT);

  }

}

这个是窗口看门狗喂狗函数,防止看门狗复位。

c、停机前外设设置函数:


void Halt_OffDevice(void)

{

  //关闭设备前,设置系统主时钟,和中断 

  Clk_Init();  

  

  //CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV4);

  

  ADC1_DeInit();

  TIM1_DeInit();

 

  //停机前关闭不需要的功能模块的时钟  

  CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER3,DISABLE);

  CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1,DISABLE);

  CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC,DISABLE);

  CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2,DISABLE);

  CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4,DISABLE);

  CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU,DISABLE);

  CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C,DISABLE);

  CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART2,DISABLE);

  

  GPIO_Init(GPIOA,GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3,GPIO_MODE_OUT_PP_LOW_SLOW);

  

  GPIO_Init(GPIOB,GPIO_PIN_HNIB,GPIO_MODE_OUT_PP_LOW_SLOW);

  GPIO_Init(GPIOB,GPIO_PIN_2|GPIO_PIN_3,GPIO_MODE_OUT_PP_LOW_SLOW);

  

  GPIO_Init(GPIOC,GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4,GPIO_MODE_OUT_PP_HIGH_SLOW);

  GPIO_Init(GPIOC,GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7,GPIO_MODE_OUT_PP_LOW_SLOW);

  

  GPIO_Init(GPIOD,GPIO_PIN_LNIB,GPIO_MODE_OUT_PP_LOW_SLOW);

  GPIO_Init(GPIOD,GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6,GPIO_MODE_OUT_PP_LOW_SLOW);

  

  GPIO_Init(GPIOE,GPIO_PIN_LNIB,GPIO_MODE_OUT_PP_LOW_SLOW);

  GPIO_Init(GPIOE,GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7,GPIO_MODE_OUT_PP_LOW_SLOW);

  

  GPIO_Init(GPIOG,GPIO_PIN_0,GPIO_MODE_OUT_PP_LOW_SLOW);

  GPIO_Init(GPIOG,GPIO_PIN_1,GPIO_MODE_OUT_PP_HIGH_SLOW);

  

  InPut_Init();

  enableInterrupts();

}

这个函数主要就是在停机前设置好系统的时钟,并且关闭一切不必要的外设的时钟,如AD,定时器等等的时钟。

并且最重要的是要设置好系统唤醒的条件和使能中断。对于IO口的设置,对于外设是高电平工作的,那么设置成


推挽输出低,对于是低电平工作的那么设置成推挽输出高。这里说明一下,浮空输入我不知道可不可以,大家可


以试试。

d、唤醒口初始化设置函数:


void InPut_Init(void)

{

  //与按键相连的引脚设置为输入模式

  GPIO_Init(P_PortD,Power,GPIO_MODE_IN_PU_IT);      

  //将PD7引脚的TLI中断设置为下降沿中断,TLI是最高优先级中断

  EXTI_SetTLISensitivity(EXTI_TLISENSITIVITY_FALL_ONLY);

  

  GPIO_Init(P_PortA,CHARGE_IN,GPIO_MODE_IN_PU_IT);    

  //将GPIOD端口设置为上升沿触发中断--因为充电器插入时产生一个高电平,拔出时产生一个下降沿

  EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOA,EXTI_SENSITIVITY_RISE_FALL);   

}

系统可以通过两个IO口里唤醒CPU,一个是按键,设置成最高优先级中断TLI,并且是下降沿中断。还有一个

就是充电器插入唤醒中断,这里我的移动电源是要充电的,所以要做充电器的插入拔除检测,因此要设置成


上升沿下降沿中断方式。讲完以上的函数,大部分的功能都讲完了,剩下的就是在stm8s_it.c里面处理中断了。


按键唤醒中断处理:


INTERRUPT_HANDLER(TLI_IRQHandler, 0)

{

  /* In order to detect unexpected events during development,

     it is recommended to set a breakpoint on the following instruction.

  */

  delay_ms(20);//延时消抖

  if(!GPIO_ReadInputPin(P_PortD,Power)){

    delay_ms(20);

    time_count = 0;

    if(fPowerOn_flag == FALSE){

      fPowerOn_flag = TRUE;

    }

    else{

      if(fExitDCPower_flag == FALSE) fPowerOn_flag = FALSE;

    }

  }

}

首先是20ms的延时,然后再次检测IO口的电平,如果为低,那么说明按键按下了,再延时20ms。然后处理

系统工作的标志位。如果系统在停机模式,那么按下按键以后,系统进入工作模式;反之,系统进入停机模


式。这里说明一下,那个else里面的处理要加入一个限制条件,就是在运行模式下再次按下唤醒按键时,要先


判断充电器有没有插入,如果没有插入,则系统进入停机模式,如果插入了,系统则不处理,继续保持运行模


式对电池充电。


充电器插入唤醒中断处理:


INTERRUPT_HANDLER(EXTI_PORTA_IRQHandler,3)

{

  /* In order to detect unexpected events during development,

     it is recommended to set a breakpoint on the following instruction.

  */

  delay_ms(20);

  if(GPIO_ReadInputPin(P_PortA,CHARGE_IN)){

    delay_ms(20);

    if(fPowerOn_flag == FALSE) fPowerOn_flag = TRUE;

    

    if(fExitDCPower_flag == FALSE) fExitDCPower_flag = TRUE;

  }   

  else{

  delay_ms(20);

  if(fExitDCPower_flag == TRUE) fExitDCPower_flag = FALSE;

  }  

}


关键字:STM8  停机模式  低功耗 引用地址:STM8的停机模式

上一篇:halt低功耗模式
下一篇:STM8L低功耗调试总结

推荐阅读

印度《经济时报》今日援引可靠消息称,苹果公司已任命诺基亚通信前高管周德翰(Ashish Chowdhary)为印度市场负责人。 该行业人士证实,周德翰将于明年1月正式出任苹果印度市场主管。业内人士称,苹果此举是为了在印度市场谋求长期发展。当前,印度智能手机市场发展迅速,但苹果的市场份额仍微乎其微。 因此,苹果此次...
图1. 90000-X示波器捕获板 图1是90000-X示波器的捕获板。90000-X示波器使用磷化铟技术,其硬件带宽可达33GHz,实时采样率可达80GSa/s,存储深度可达2GB。这些指标都达到了业界顶尖的水平。但是随着采样速率和存储深度的提升,数字信号处理能力成为一大挑战,传统的使用内置计算机的Matlab软件处理方式已经不能满足测试速度的要求。现在,90000和90000...
近日,有研新材创新及成果转化基地传来新消息。据大众网报道,该项目预计2021年6月份投产。今年4月27日,有研新材创新及成果转化基地在乐陵市循环经济示范园奠基。该项目旨在建成具有国际先进水平的新材料研发及产业化平台,建设超高纯稀有金属及化合物、稀土功能材料、高端晶体材料及器件9条生产线,涵盖企业电磁光板块主营业务,重点研发集成电路、智能...

史海拾趣

问答坊 | AI 解惑

LCD Scope 40MSPS

网上找到的一个示波器网站 http://www.eosystems.ro/…

查看全部问答∨

有调通过marvell wifi 8686 sdio接口驱动来讨论下???

正在调sdio接口的wifi 8686驱动,sdio确认好的,读写寄存器,加载固件都没问题。有以下问题: 1. 我是直接把驱动放在bsp中编的,wince启动后自动加载wifi驱动, 并且这个wifi驱动会自行搜索热点。我的理解是wifi驱动加载固件启动完wifi芯片注册网络 ...…

查看全部问答∨

protel 99se中,sp232E在哪个库中?

如题。 protel 99se中,SP232E所在的库叫什么?…

查看全部问答∨

求救,自己定制系统不能显示中文??

奇怪,在pb5.0自己定制的系统不能显示中文,只能显示"_",但用mobile Hansheld作系统的话就能显示中文,什么回事呢? …

查看全部问答∨

看看我的成果

本人长期从事单片机开发应用,积累了一定的经验。本人将毕生研究心得集成了文字,放在我的博客里,希望大家光临指导,并给点意见。我的博客地址;http://blog.mcuol.com/user/Article/500.html…

查看全部问答∨

STM32的FLASH使能和禁止半周期访问对运行有什么区别吗

                                 如题…

查看全部问答∨

f2812AD转换波动很大,不知是什么原因?

用电位器输出一个电压值,从我watch窗口看到的ADCresult值都在变化,变化比较大。如0xabc0,b为都会能差4,帮忙分析一下可能那里设置不对。谢谢!…

查看全部问答∨

LM3S811使用心得之ADC

从参加抢LM3S811的活动后,每天都期待啊,终于在4.26的下午,顺风快递发来信息去取快递,其实已经料到是811到啦,好兴奋的跑到校门口外迎接顺风,领到包裹后,回寝室迫不及待的打开它,没错是811 。用811把我以前的LCD有重新驱动了起来,下面是我这 ...…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
更多往期活动
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved