首先,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;
}
}
上一篇:halt低功耗模式
下一篇:STM8L低功耗调试总结
推荐阅读
史海拾趣
为了进一步增强市场影响力,Dialog Semiconductor通过一系列的收购策略来扩大其业务范围。例如,在2020年,公司收购了Adesto Technologies,这是一家专注于非易失性存储器(NVM)解决方案的公司。此次收购为Dialog Semiconductor带来了近5,000家新客户,并补充了其在无线连接产品之外的有线连接解决方案。同年,Dialog Semiconductor还收购了另一家公司,获得了强大的核心IC产品组合和经验丰富的工程师团队,进一步巩固了其在IoT市场的地位。
在日本市场,Ettinger同样取得了巨大的成功。Ettinger Flagship Store位于东京银座,其年营业额甚至即将赶超Ettinger在英国伦敦的销售业绩。这一成就不仅展示了Ettinger在日本市场的受欢迎程度,也体现了品牌在全球范围内的强大竞争力。Ettinger通过不断拓展海外市场,进一步巩固了其作为皮具奢侈品牌的地位。
背景:在闪存市场取得成功后,Galaxy Microelectronics开始探索多元化发展道路。
发展:公司决定进入DRAM市场,并投入大量资源进行技术研发。经过几年的努力,Galaxy Microelectronics成功推出了多款高性能DRAM产品,进一步丰富了其产品线。此外,公司还开始涉足SSD固态硬盘领域,推出了多款具有竞争力的产品,进一步巩固了其在存储市场的地位。
Comax Industrial Co Ltd公司自创立之初,便明确了其在电子行业中的定位与发展方向。公司初期便注重技术研发,引进了一批高素质的技术人才,并投入大量资源进行技术研发与创新。通过不懈的努力,Comax成功开发出一系列具有竞争力的电子产品,并在市场上获得了良好的口碑。这些产品不仅满足了客户的需求,也为公司的发展奠定了坚实的技术基础。
在无线射频和传感器领域,HOPERF始终保持着技术创新的领先地位。公司独创的“NextGenRF”算法专利技术,填补了国内在该领域的空白,并获得了多项企业认证、发明专项和软件著作权。这些技术创新不仅推动了公司产品性能的持续提升,还引领了整个行业的发展方向。此外,HOPERF还积极参与国际标准制定,不断提升自身在全球行业中的话语权和影响力。
凭借卓越的产品性能和完善的解决方案,HOPERF的产品在多个领域得到了广泛应用。从户外运动、电子导航到工业测量、环境监测,再到医疗健康、智能家居等领域,HOPERF的产品几乎覆盖了人们生活的方方面面。公司不仅提供标准化的产品,还根据客户的实际需求提供个性化定制服务,极大地满足了市场的多样化需求。这种灵活多变的市场策略使得HOPERF在全球市场上迅速拓展,赢得了大量品牌客户的青睐和合作。
以上五个故事展示了HOPERF公司在电子行业中的发展历程和成就,充分体现了其在技术创新、产业链整合、全球化布局、质量控制以及市场拓展等方面的综合实力。
有调通过marvell wifi 8686 sdio接口驱动来讨论下??? 正在调sdio接口的wifi 8686驱动,sdio确认好的,读写寄存器,加载固件都没问题。有以下问题: 1. 我是直接把驱动放在bsp中编的,wince启动后自动加载wifi驱动, 并且这个wifi驱动会自行搜索热点。我的理解是wifi驱动加载固件启动完wifi芯片注册网络 ...… 查看全部问答∨ |
|
用电位器输出一个电压值,从我watch窗口看到的ADCresult值都在变化,变化比较大。如0xabc0,b为都会能差4,帮忙分析一下可能那里设置不对。谢谢!… 查看全部问答∨ |
从参加抢LM3S811的活动后,每天都期待啊,终于在4.26的下午,顺风快递发来信息去取快递,其实已经料到是811到啦,好兴奋的跑到校门口外迎接顺风,领到包裹后,回寝室迫不及待的打开它,没错是811 。用811把我以前的LCD有重新驱动了起来,下面是我这 ...… 查看全部问答∨ |