简介
AWU是用来当MCU进入低功耗的活跃停机(Active Halt)模式时提供一个内部的唤醒时间基准。 该时间基准的时钟是由内部的低速RC振荡器时钟(LSI)或者通过预分频的HSE晶振时钟来提供 的。
校准LSI
LSI 时钟测量 在使用LSI低速内部时钟时,为了确保好的精度,它的频率可以通过TIMX的输入捕捉1来测定。
- 将AWU_CSR的MSR位置1来把LSI的内部时钟连接到TIMX定时器的ICAP1;
- 通过定时器的输入捕捉中断来测量LSI的时钟频率;
- 到向AWU_APR的 APR [5:0] 位写入一个适当的值来调整AWU定时间隔到期望的时间间隔。AWUTB[3:0]位可以被更改来选择不同的时间间隔。 LSI的时钟频率测量方法也可以被用来校准蜂鸣器的频率。
参考例程如下:
uint32_t LSIMeasurment(void)
{
nt32_t lsi_freq_hz = 0x0;//测到的lsi的频率
uint32_t fmaster = 0x0;//主时钟频率
uint16_t ICValue1 = 0x0;//捕捉到的第一个值
uint16_t ICValue2 = 0x0;//捕捉到的第二个值
fmaster = CLK_GetClockFreq();//获取主时钟
AWU->CSR |= AWU_CSR_MSR;将AWU->CSR的MSR置一来把LSI的内部时钟连接到TIM1定时器的ICAP1
TIM1_ICInit(TIM1_CHANNEL_1,//通道1
TIM1_ICPOLARITY_RISING, //上升沿捕获
TIM1_ICSELECTION_DIRECTTI, //IC1映射在TI1FP1上
TIM1_ICPSC_DIV8,//捕捉预分频为八分频
0x00//无滤波器,fSAMPLING=fMASTER
);
TIM1_Cmd(ENABLE);//使能TIM1计时器
while((TIM1->SR1 & TIM1_FLAG_CC1) != TIM1_FLAG_CC1);//等待捕获标志
ICValue1 = TIM1_GetCapture1();//捕获值1
TIM1_ClearFlag(TIM1_FLAG_CC1);//清除捕获标志
while((TIM1->SR1 & TIM1_FLAG_CC1) != TIM1_FLAG_CC1);//等待捕获标志
ICValue2 = TIM1_GetCapture1();//捕获值2
TIM1_ClearFlag(TIM1_FLAG_CC1);//清除捕获标志
TIM1->CCER1 &= (uint8_t)(~TIM1_CCER1_CC1E);//禁止输入捕获
TIM1_Cmd(DISABLE);//禁止TIM1
lsi_freq_hz = (8 * fmaster) / (ICValue2 - ICValue1);//计算lsi的频率
AWU->CSR &= (uint8_t)(~AWU_CSR_MSR);//禁止LSI测量,断开LSI与捕获通道的连接
return (lsi_freq_hz);//将LSI的值返回
}
//时钟配置函数
static void CLK_Config(void)
{
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);//HSI时钟(主时钟)初始化为1分频
}
//自动唤醒功能初始化
void AWU_Config(void)
{
AWU_LSICalibrationConfig(LSIMeasurment());//对AWU时钟即LSI进行校准
AWU_Init(AWU_TIMEBASE_12S);//12s后唤醒
}
主函数
void main(void)
{
CLK_Config();
AWU_Config();
enableInterrupts();
halt(); //运行到此语句后会自动唤醒AWU,唤醒后不会复位, 而是进入了中断, 如果没有写复位语句, 那么就一直在中断了,不会唤醒系统
while(1);
中断函数:
INTERRUPT_HANDLER(AWU_IRQHandler, 1)
{
/*Clear AWU peripheral pending bit */
AWU_GetFlagStatus();//复位函数(用以跳出中断,很重要!!!)
}