大家好,我是单片机爱好者-MCU起航。这里说下使用库函数方式控制STM8S103F3P6实现AWU自动唤醒的功能。
首先打开数据手册,看一下关于AWU功能的简介。AWU是Auto-wakeup的缩写,也就是自动唤醒的意思。什么时候唤醒?
当MCU进入低功耗的活跃停机(Active Halt)模式时来唤醒,所以需要给它提供一个内部的唤醒时间基准。否则,它无法知道多久后唤醒。
那么时钟源从哪来?两个来源:1、外部高速时钟,分频后提供;2、内部的低速128KHZ。STM8S103F3P6单片机出厂时默认选择第二个时钟源,如果要修改时钟源,需要修改单片机的选项字:option byte。这部分内容没有在寄存器相关的收据手册里,在STM8S103系列的选型数据手册里有说明,我这里放个图,大家知道就好:
那么该功能如何使用?数据手册里写的比较繁琐,需要按照以下几个步骤操作:
1. 使用AWU_CSR寄存器的MSR位和TIM3的输入捕捉通道1来检测LS的时钟频率;
2. 通过写AWU_APR的APR[5:0]位来定义适当的预分频值;
3. 通过写AWU_TBR的AWUTB[3:0]来选择需要的自动唤醒延时;
4. 置位AWU_CSR 的AWUEN位;
5. 执行HALT指令。
但经过我实际测试,发现在库函数下用法是比较简单的,步骤如下:
1、使能LSI时钟
2、配置延时时间
3、使能AWU功能
4、使能全局中断
代码如下,我们实现以下功能:LED闪烁一下,然后进入halt模式,2秒后mcu被唤醒,LED继续闪烁,进入halt模式,这样一个循环操作。
/* Includes ------------------------------------------------------------------*/
#include "stm8s.h"
/* Private defines -----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
void Delay(uint16_t nCount)
{
/* Decrement nCount value */
while (nCount != 0)
{
nCount--;
}
}
char INT_FLAG = 1;
/***************************************************
* AWU初始化子函数
* 每隔2秒自动唤醒一次
****************************************************/
void Awu_Init(void)
{
CLK_LSICmd(ENABLE); //打开LSI时钟
AWU_Init(AWU_TIMEBASE_2S);
enableInterrupts(); //全局中断
}
void main(void)
{
GPIO_Init(GPIOB, GPIO_PIN_4, GPIO_MODE_OUT_PP_HIGH_SLOW);
Awu_Init();
while (1)
{
if(INT_FLAG == 1)
{
INT_FLAG = 0;
GPIO_WriteReverse(GPIOB, GPIO_PIN_4);
Delay(5000);
GPIO_WriteReverse(GPIOB, GPIO_PIN_4);
Delay(5000);
GPIO_WriteHigh(GPIOB, GPIO_PIN_4); //LED熄灭
halt();
}
}
}
主函数部分比较简单,LED部分的操作之前讲过,不说了,只看AWU部分。对AWU进行了初始化,首先打开LSI时钟,然后设置AWU唤醒时间,最后开启中断。
因为在库函数下,很多寄存器的操作都隐藏了,时间或者模式都被写成了宏定义,这种方式既简单又好理解,实在是方便。
AWU功能计时到达以后,会触发中断,所以中断相关的函数也要编写,如下:
INTERRUPT_HANDLER(AWU_IRQHandler, 1)
{
/* In order to detect unexpected events during development,
it is recommended to set a breakpoint on the following instruction.
*/
FlagStatus flag_status;
flag_status = AWU_GetFlagStatus();
if (flag_status == SET) // SET or RESET
{
INT_FLAG = 1;
}
}
进入AWU中断函数,只进行两个操作:1、清除AWU中断标准;2、置一自定义的标志。
编译、下载、上电!现象OK!
很简单,打完收工!
要获取该程序完整的工程文件,可以关注公众号:单片机爱好者,然后回复关键词:STM8S。可以获取完整的下载链接,里面包含工程文件、视频、PPT、数据手册等所有相关资料。
再加上校准步骤好点哈
哈哈,好的