每日更新教程,评论区答疑解惑,小白也能变大神!"
目录
一.低电压检测器 (LVD) 概述
1.1概述
低电压检测器 (LVD) 用于监测 VDDA 电源电压或外部引脚输入电压,当被监测电压与 LVD 阈值的比较结果满足触 发条件时,将产生 LVD 中断或复位信号,通常用于处理一些紧急任务。 LVD 产生的中断和复位标志,只能由软件清零;只有当中断或复位标志被清零后,在再次达到触发条件时,LVD 才能再次产生中断或者复位信号。
1.2主要特性
- 4 路监测电压源: VDDA 电源电压、PA00、PB00、PB11 引脚输入。
- 16 阶阈值电压,范围 2V ~ 3.67V。
- 3 种触发条件,可组合使用:
- ‒ 电平触发:电压低于阈值。
- ‒ 下降沿触发:电压跌落到阈值以下的下降沿。
- ‒ 上升沿触发:电压回升到阈值以上的上升沿。
- 可触发产生中断或复位信号,二者不能同时产生。
- 8 阶滤波可配置。
- 支持迟滞功能。
- 支持低功耗模式下运行,中断唤醒 MCU。
1.3功能描述
1.4迟滞功能
- LVD 内置的电压比较器具有迟滞功能,可避免当 LVD 的被监测电压在阈值电压附近时,电压比较器的输出结果发 生频繁翻转,增强系统抗干扰能力。
- 只有当被监测电压高于或低于阈值电压达到 20mV 时,比较器输出信号才会发生翻转。具体波形如下图所示:
1.5数字滤波
1.6 LVD 中断
- LVD 支持在低功耗模式下工作,中断输出可将芯片从低功耗模式下唤醒。 当被监测电压与 LVD 阈值的比较结果满足触发条件时,可产生中断或复位信号。产生中断还是复位信号由控制寄 存器 LVD_CR0 的 ACTION 位域控制:
- ACTION 为 1,LVD 触发产生复位。
- ACTION 为 0,LVD 触发产生中断。
- 设置控制寄存器 LVD_CR0 的 IE 位域为 1,使能 LVD 中断,满足触发条件时将产生 LVD 中断,中断标志位 LVD_SR.INTF 会被硬件置 1,用户可以向 INTF 位写 0,清除中断标志。 设置控制寄存器 LVD_CR1 的 LEVEL、FALL、RISE 位域,可选择不同的中断或复位触发方式,三者可组合使用:
- LEVEL 为 1,被监测电压低于阈值时触发中断或产生复位。
- FALL 为 1,被监测电压跌落到阈值以下的下降沿触发中断或产生复位。
- RISE 为 1,被监测电压回升到阈值以上的上升沿触发中断或产生复位。
1.7欠压复位编程示例
- 在此示例中,被监测电压低于阈值电压时复位 MCU,使用数字滤波功能。 配置方法如下所示:
- 步骤 1:配置 LVD_CR0.SOURCE,选择待监测的电压来源;
- 步骤 2:配置 LVD_CR0.VTH,设置阈值电压;
- 步骤 3:配置 LVD_CR1.FLTTIME,选择 LVD 滤波时间;
- 步骤 4:配置 LVD_CR1.FLTCLK,选择滤波时钟;
- 步骤 5:配置 LVD_CR1.FLTEN,使能 LVD 滤波;
- 步骤 6:设置 LVD_CR1.LEVEL 为 1,选择被监测电压低于阈值时触发 LVD 动作;
- 步骤 7:设置 LVD_CR0.ACTION 为 1,选择 LVD 触发动作为系统复位;
- 步骤 8:设置 LVD_CR0.EN 为 1,使能 LVD。
1.8中断编程示例
- 在此示例中,被监测电压高于或低于阈值电压时产生中断,使用数字滤波功能。 配置方法如下所示:
- 步骤 1:配置 LVD_CR0.SOURCE,选择待监测的电压来源;
- 步骤 2:配置 LVD_CR0.VTH,选择阈值电压;
- 步骤 3:配置 LVD_CR1.FLTTIME,选择 LVD 滤波时间;
- 步骤 4:配置 LVD_CR1.FLTCLK,选择滤波时钟;
- 步骤 5:配置 LVD_CR1.FLTEN,使能 LVD 滤波;
- 步骤 6:设置 LVD_CR1.RISE 和 FALL 均为 1,选择上升沿和下降沿触发;
- 步骤 7:设置 LVD_CR0.ACTION 为 0,选择 LVD 触发动作为中断;
- 步骤 8:设置 LVD_CR0.IE 为 1,使能 LVD 中断;
- 步骤 9:使能 NVIC 中断向量表中的 LVD 中断;
- 步骤 10:设置 LVD_CR0.EN 为 1,使能 LVD;
- 步骤 11:分别在 LVD 初始化程序和 LVD 中断服务程序中,对 LVD_SR.INTF 位写入 0,以清除中断标志,允许产 生新的 LVD 中断。
二.寄存器列表
三.案例-LVD模块的上升沿、下降沿触发中断功能
全局变量
volatile boolean_t gFlagIrq = FALSE; // LVD中断标志位,volatile防止编译器优化
LVD端口初始化函数
void LVD_PortInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
// 使能GPIOA和GPIOB的AHB总线时钟
REGBITS_SET(CW_SYSCTRL->AHBEN, SYSCTRL_AHBEN_GPIOA_Msk | SYSCTRL_AHBEN_GPIOB_Msk);
// 配置PA08为推挽输出模式(LVD输出引脚)
GPIO_InitStructure.Pins = GPIO_PIN_8;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_Init(CW_GPIOA, &GPIO_InitStructure);
// 设置PA08为LVD模块输出功能
PA08_AFx_LVDOUT();
// 配置PB11为模拟输入模式(LVD信号输入引脚)
PB11_ANALOG_ENABLE();
}
主函数
int main(void)
{
LVD_InitTypeDef LVD_InitStruct = {0};
// 初始化LED控制引脚
LED_Init();
// 初始化LVD相关GPIO
LVD_PortInit();
// 配置LVD模块参数
LVD_InitStruct.LVD_Action = LVD_Action_Irq; // 触发模式:中断
LVD_InitStruct.LVD_Source = LVD_Source_PB11; // 信号源:PB11引脚
LVD_InitStruct.LVD_Threshold = LVD_Threshold_2p0V; // 阈值电压:2.0V
LVD_InitStruct.LVD_FilterEn = LVD_Filter_Enable; // 启用滤波器
LVD_InitStruct.LVD_FilterClk = LVD_FilterClk_RC150K; // 滤波器时钟源
LVD_InitStruct.LVD_FilterTime = LVD_FilterTime_4095Clk; // 滤波时间
// 初始化LVD模块
LVD_Init(&LVD_InitStruct);
// 配置双沿触发(上升沿和下降沿)
LVD_TrigConfig(LVD_TRIG_FALL | LVD_TRIG_RISE, ENABLE);
// 使能LVD中断并设置优先级
LVD_EnableIrq(LVD_INT_PRIORITY);
// 清除中断标志
LVD_ClearIrq();
// 延时等待硬件稳定
FirmwareDelay(4800);
// 使能LVD模块
LVD_Enable();
// 主循环检测中断标志
while (1)
{
if (gFlagIrq) // 中断触发时翻转PB09状态
{
PB09_TOG();
gFlagIrq = FALSE; // 清除标志位
}
}
}
LED初始化函数
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
// 使能GPIOB的AHB总线时钟
REGBITS_SET(CW_SYSCTRL->AHBEN, SYSCTRL_AHBEN_GPIOB_Msk);
// 配置PB8/PB9为推挽输出模式(LED控制引脚)
GPIO_InitStructure.Pins = GPIO_PIN_8 | GPIO_PIN_9;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_Init(CW_GPIOB, &GPIO_InitStructure);
// 初始状态:关闭LED
PB08_SETLOW();
PB09_SETLOW();
}
中断函数
/**
* @brief 低电压检测(LVD)中断服务函数
* @note 当芯片电压低于设定的LVD阈值时触发该中断
*/
void LVD_IRQHandler(void)
{
/* USER CODE BEGIN */
// 清除LVD中断标志位,防止重复进入中断
LVD_ClearIrq();
// 设置全局中断标志位,用于主程序检测中断发生
gFlagIrq = TRUE;
/* USER CODE END */
}
关键点说明
volatile
关键字确保中断标志变量不会被编译器优化- LVD模块配置包含电压阈值检测和数字滤波功能
PB09_TOG()
在中断发生时切换LED状态用于指示