在一些使用电池的场合,单片机有低功耗的需求。
这不仅需要在硬件电路设计上降低功耗,我们的软件设计也要考虑。
软件方面就是要尽量降低单片机和外设的功耗,像单片机的一些不必要的外设,如ADC等不使用时关闭其电源等。
甚至我们可以关掉CPU来节省功耗,但是关闭的CPU单片机就没法干活了,这时候我们需要想办法在必要时叫醒CPU继续干活,
AWU就是干这事的,自动唤醒单元,说白了就是个定时器。
先来看看结构
图上可以看到,AWU单元的时钟来源有两个,一个是外部时钟的分频,一个是内部RC震荡。
时钟选择后还能接通到定时器测量频率偏差,然后根据偏差调整后面的定时时长。
AWU时钟源选定后成为LS,LS再经一个6位计数器分频,送入AWU计数器。
当AWU计数器的值与AWUTB选定的时基相等且AWU功能置位,单片机处于等待或者停机模式时触发AWU中断,唤醒CPU。
最终CPU还是被中断唤醒。
看看配置流程
第一步的测量时钟频率可根据实际情况选择。
这里讲的是设置好AWU_APR、AWU_TBR、AWU_CSR后执行halt就能开启AWU功能。
但是实际上还是有些问题的。这个后面再讲,先看看如何设置。
看下表
这里是时基选择,共15种,决定了定时区间,根据计算公式与定时时间可以求出分频系数APR的值。
最后将AWU功能开启即可。
再看看这段提示
计数器在进入活跃停机模式时开始计数,AWU中断同时开启。
这句话有意思,进入活跃停机模式后开始计数,并且中断开启,这意味着不需要再执行中断允许。同时在停机时程序不运行,也不需要rim指令来使能中断。
再看看中断标志位
这里的意思是,中断标志位被硬件置位,只能通过读取的方式来复位,写入无效。
上面的两点很有意思,停机模式下没有程序运行,因此AWU中断产生时能直接进入处理程序,所以不需要用rim指令降低主程序优先级。
AWUF标志位需要通过读取来复位,如果不复位会造成AWU中断会不停进入,无法退出。
特别是AWUF这个位,因为这个弄了好久才明白,手册也没有明确说明。
今天实验很简单,就是最简单的自动唤醒,使用LED做指示。每唤醒一次LED改变一次状态,之后马上进入停机模式。
这里设置唤醒间隔1S。
看LED唤醒间隔
由于频率误差等多种原因,实际使用可以直接用示波器或者逻辑分析仪掐时间。
看看仿真
看错误提示,停机模式下无法中断调试。
说明单片机确实进入了停机模式。
最后贴上测试程序
- #include<iostm8s105k4.h>
- #define LED PE_ODR_ODR5
- void init()
- {
- CLK_SWCR=0x02; //时钟切换
- CLK_SWR=0xb4; //外部时钟
- CLK_CKDIVR=0x00; //不分频
-
- PE_DDR_DDR5=1; //输出口配置
- PE_CR1_C15=1;
- PE_CR2_C25=0;
-
- AWU_APR=0x3e; //分频
- AWU_TBR=0x0c; //时基
- AWU_CSR1|=0x10; //开唤醒
-
- }
- #pragma vector=AWU_vector
- __interrupt void AWU() //唤醒中断服务
- {
- AWU_CSR1; //读中断标志,自动复位
- }
- int main( void )
- {
- init();
-
- while(1)
- {
-
- LED=~LED;
- asm("halt"); //进入停机模式
-
- }
-
- }
程序很简单,实验也很简单。
THE END!