时钟安全系统应用LSE
前言
某公司用 ST STM32L476 在水表上,在开启时钟安全系统(CSS)之后,发现 MCU 重启后,
LSE 无法正常启动,通过示波器看,发现 LSE 已经正常起振。这是由于他们对 CSS 的了解不够,应
用错误导致,下面我们来深入了解一下 MCU 内部的时钟安全系统。
时钟安全系统
功能介绍
时钟安全系统主要功能是检测外部时钟(HSE LSELSE 只有在某些系列存在,如
STM32L4),当外部时钟发生故障时,此振荡器将自动禁止,一个时钟故障时间将发送到高级控制定
时器 TIM1 TIM8 的断路输出(刹车),并同时产生一个中断来向软件通知此故障(时钟系统中断
CSSI),以使 MCU 能够执行救援操作,这是一个不可屏蔽中断(NMI)。
关键因素
1LCECSSON 必须在 LSERDY 置位后设置。
2CSS 可以工作在系统复位上(除了上电复位),因为它受控于备份域,所以要注意
RCC_BDCR 上的寄存器,并不会在系统复位后被清除
3CSS_LSE RTC Tamper,TimeStamp 复用 EXIT Line19.所以不仅要使 NVIC(复用
TAMP_STAMP_IRQn),还要使能 EXITEXTI->IMR1 |= ((uint32_t)0x00080000))。
实际应用
1:时钟使能
SystemClock_Config(); //里面主要设置主时钟,LSE 的使能
2CSS 以及中断使能
HAL_RCCEx_EnableLSECSS_IT(); //CSS 中断使能
HAL_NVIC_SetPriority(TAMP_STAMP_IRQn, 0, 1); //CSS 的优先级以及 NVIC 使能
HAL_NVIC_EnableIRQ(TAMP_STAMP_IRQn);
__HAL_RTC_TAMPER_TIMESTAMP_EXTI_ENABLE_IT(); //CSS EXIT 以及触发条件使
__HAL_RTC_TAMPER_TIMESTAMP_EXTI_ENABLE_RISING_EDGE();
3CSS 的中断处理
void TAMP_STAMP_IRQHandler(void) //中断函数和 TAMP&STAMP 复用,
{ //HAL_RCC_NMI_IRQHandler();二次检测即可
HAL_RCC_NMI_IRQHandler();
}
void HAL_RCC_NMI_IRQHandler(void)
{
/* Check RCC CSSF interrupt flag */
if(__HAL_RCC_GET_IT(RCC_IT_CSS)|__HAL_RCC_GET_IT(RCC_IT_LSECSS)) //二次判断
{
/* RCC Clock Security System interrupt user callback */
HAL_RCC_CSSCallback();
}
}
void HAL_RCC_CSSCallback(void) //中断函数处理
{
RCC_OscInitTypeDef RCC_OscInitStruct;
HAL_RCCEx_DisableLSECSS();
__HAL_RCC_ENABLE_IT(RCC_CICR_LSECSSC); //清除相关标志位
__HAL_RCC_ENABLE_IT(RCC_CICR_CSSC);
__HAL_RCC_CLEAR_IT(RCC_IT_CSS);
__HAL_RCC_CLEAR_IT(RCC_IT_LSECSS);
__HAL_RCC_BACKUPRESET_FORCE(); //这部份最重要, CSS 中断触发之,LSECSSD 被置位了,
__HAL_RCC_BACKUPRESET_RELEASE(); //必须要在中断内复位清除, 不然会一直被触发,就算系统
//复位了,也会导致 LSE 不能置位 LSERDY
__HAL_RTC_TAMPER_TIMESTAMP_EXTI_CLEAR_FLAG(); // LSE EXIT 标志
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI; //转为 LSI
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
}