低電壓檢測(cè)器(LVD)適用于監(jiān)測(cè)VDDA電源電壓或外部引腳輸入電壓,當(dāng)被監(jiān)測(cè)電壓與LVD閾值的比較結(jié)果滿足觸發(fā)的條件時(shí),LVD將會(huì)產(chǎn)生中斷或者復(fù)位信號(hào),通常用來處理一些緊急任務(wù)。LVD產(chǎn)生的中斷或復(fù)位標(biāo)志,只能通過軟件程序清零,只有當(dāng)中斷或復(fù)位標(biāo)志被清零后,在再次達(dá)到觸發(fā)條件時(shí),LVD才能再次產(chǎn)生中斷或復(fù)位信號(hào)。本文以CW32L083為例,介紹LVD的使用方法。
低電壓檢測(cè)器(LVD)的主要特性:
1. 4路監(jiān)測(cè)電壓源:VDDA電源電壓,PA00、PB00、PB11引腳輸入
2. 16階閾值電壓,范圍2.02V-3.76V
3. 3種觸發(fā)條件,可以組合使用
電平觸發(fā):電壓低于閾值
下降沿觸發(fā):電壓跌落到閾值以下的下降沿
上升沿觸發(fā):電壓回升到閾值以上的上升沿
4. 可觸發(fā)產(chǎn)生中斷或復(fù)位信號(hào),二者不能同時(shí)產(chǎn)生
5. 8階濾波可配置
6. 支持遲滯功能
7. 支持低功耗模式下運(yùn)行,中斷喚醒MCU
上圖為CW32L083低電壓檢測(cè)器(LVD)的功能框圖,LVD不僅可以監(jiān)測(cè)VDDA電源電壓,也可以監(jiān)測(cè)外部引腳 (PA00、PB00、PB11)輸入電壓,通過控制寄存器LVD_CR0的SOURCE位域來選擇,當(dāng)使用外部引腳來監(jiān)測(cè)電壓時(shí),需將對(duì)應(yīng)的GPIO端口配置為模擬輸入模式(GPIOx_ANALOG.PINy = 1)。
LVD的輸出結(jié)果可以從PA01/PA08/PC12/PE02/PF02引腳輸出,需將對(duì)應(yīng)的GPIO口配置為數(shù)字輸出模式,同時(shí)選擇功能復(fù)用,下面為具體配置
//LVD I/O口初始化
void LVD_PortInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
//打開GPIOA時(shí)鐘
__RCC_GPIOA_CLK_ENABLE();
//將PA08設(shè)置為LVD比較結(jié)果輸出
GPIO_InitStructure.Pins = GPIO_PIN_8;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Init(CW_GPIOA, &GPIO_InitStructure);
//將PA08復(fù)用為LVD比較結(jié)果輸出
PA08_AFx_LVDOUT();
//將PA00設(shè)置為LVD的輸入口
PA00_ANALOG_ENABLE();
}
遲滯功能
LVD 內(nèi)置的電壓比較器具有遲滯功能,可避免當(dāng) LVD 的被監(jiān)測(cè)電壓在閾值電壓附近時(shí),電壓比較器的輸出結(jié)果發(fā)生頻繁翻轉(zhuǎn),增強(qiáng)系統(tǒng)抗干擾能力。只有當(dāng)被監(jiān)測(cè)電壓高于或低于閾值電壓達(dá)到20mV時(shí),比較器輸出信號(hào)才會(huì)發(fā)生翻轉(zhuǎn)。具體波形如下圖所示:
LVD的閾值電壓根據(jù)LVD控制寄存器LVD_CR0的VTH位值決定,有效值0 ~ 15,如下表所示:
數(shù)字濾波功能
CW32L083的LVD支持?jǐn)?shù)字濾波功能,以增強(qiáng)系統(tǒng)的魯棒性,可將LVD電壓比較的輸出結(jié)果信號(hào)進(jìn)行數(shù)字濾波,小于濾波寬度的信號(hào)被濾除,不會(huì)觸發(fā)中斷或復(fù)位,如下圖所示:
通過設(shè)置控制寄存器LVD_CR1的FLTEN位域?yàn)?,可使能數(shù)字濾波模塊。設(shè)置控制寄存器 LVD_CR1 的 FLTCLK 位域可以選擇數(shù)字濾波的時(shí)鐘:
? FLTCLK位為1,選擇HSIOSC作為濾波時(shí)鐘
? FLTCLK位為0,選擇內(nèi)置RC振蕩器時(shí)鐘作為濾波時(shí)鐘,其頻率約150kHz
相關(guān)的宏定義如下所示:
#define LVD_FilterClk_RC150K ((uint32_t)0x00000000)
#define LVD_FilterClk_HSI ((uint32_t)0x00000010)
控制寄存器LVD_CR1的FLTTIME位域用于選擇數(shù)字濾波的時(shí)鐘個(gè)數(shù),如下表所示:
從LVD狀態(tài)寄存器LVD_SR的FLTV位域,可以讀出經(jīng)LVD數(shù)字濾波后的信號(hào)電平;當(dāng) GPIO 的功能復(fù)用為LVD_OUT時(shí),數(shù)字濾波后的信號(hào)就可以從GPIO輸出,以方便觀察測(cè)量。
LVD中斷
LVD支持在低功耗模式下工作,中斷輸出可將芯片從低功耗模式下喚醒。當(dāng)被監(jiān)測(cè)電壓與LVD閾值的比較結(jié)果滿足觸發(fā)條件時(shí),可產(chǎn)生中斷或復(fù)位信號(hào)。產(chǎn)生中斷還是復(fù)位信號(hào)由控制寄存器LVD_CR0的ACTION位域控制:
? ACTION為1,LVD觸發(fā)產(chǎn)生復(fù)位 #define LVD_Action_Reset ((uint32_t)0x00000002)
? ACTION為0,LVD觸發(fā)產(chǎn)生中斷 #define LVD_Action_Irq ((uint32_t)0x00000000)
通過設(shè)置控制寄存器LVD_CR0的IE位域?yàn)?,使能LVD中斷,滿足觸發(fā)條件時(shí)將產(chǎn)生LVD中斷,中斷標(biāo)志位LVD_SR.INTF會(huì)被硬件置1,用戶可以向INTF位寫0,清除中斷標(biāo)志。設(shè)置控制寄存器LVD_CR1的LEVEL、FALL、RISE位域,可選擇不同的中斷或復(fù)位觸發(fā)方式,三者可組合使用:
? LEVEL為1,被監(jiān)測(cè)電壓低于閾值時(shí)觸發(fā)中斷或產(chǎn)生復(fù)位
? FALL為1,被監(jiān)測(cè)電壓跌落到閾值以下的下降沿觸發(fā)中斷或產(chǎn)生復(fù)位
? RISE為1,被監(jiān)測(cè)電壓回升到閾值以上的上升沿觸發(fā)中斷或產(chǎn)生復(fù)位
相關(guān)的寄存器具體位域可參考下表:
根據(jù)上述內(nèi)容,簡單介紹配置電壓監(jiān)測(cè)例程。LVD的輸入通道設(shè)置為PA00,輸出端口為PA08,門限電壓為2.02V,利用LVD的中斷實(shí)現(xiàn)當(dāng)LVD輸入通道電壓低于或者高于門限電壓時(shí)刻(利用上升沿和下降沿),PC03輸出電平翻轉(zhuǎn)一次。
void LVD_PortInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
//打開GPIOA時(shí)鐘
__RCC_GPIOA_CLK_ENABLE();
//將PA08設(shè)置為LVD比較結(jié)果輸出
GPIO_InitStructure.Pins = GPIO_PIN_8;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Init(CW_GPIOA, &GPIO_InitStructure);
//將PA08復(fù)用為LVD比較結(jié)果輸出
PA08_AFx_LVDOUT();
//將PA00設(shè)置為LVD的輸入口
PA00_ANALOG_ENABLE();
}
int main(void)
{
LVD_InitTypeDef LVD_InitStruct = {0};
//LED初始化
LED_Init();
//配置測(cè)試IO口
LVD_PortInit();
LVD_InitStruct.LVD_Action = LVD_Action_Irq; //配置中斷功能
LVD_InitStruct.LVD_Source = LVD_Source_PA00; //配置LVD輸入口為PA00
LVD_InitStruct.LVD_Threshold = LVD_Threshold_2p02V; //配置LVD基準(zhǔn)電壓為2.02v
LVD_InitStruct.LVD_FilterEn = LVD_Filter_Enable; //LVD濾波模塊開啟
LVD_InitStruct.LVD_FilterClk = LVD_FilterClk_RC150K;//LVD濾波時(shí)鐘為150KHz
LVD_InitStruct.LVD_FilterTime = LVD_FilterTime_4095Clk;
LVD_Init(&LVD_InitStruct);
LVD_TrigConfig(LVD_TRIG_FALL | LVD_TRIG_RISE, ENABLE); //LVD中斷為上升沿和下降沿觸發(fā)
LVD_EnableIrq(LVD_INT_PRIORITY);
LVD_ClearIrq();
FirmwareDelay(4800);
LVD_Enable(); //LVD使能
while (1)
{
if (gFlagIrq)
{
PC03_TOG();
gFlagIrq = FALSE;
}
}
}
/** @brief LED I/O初始化**/
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
//打開GPIOC時(shí)鐘
__RCC_GPIOC_CLK_ENABLE();
/* Configure the GPIO_LED pin */
GPIO_InitStructure.Pins = GPIO_PIN_2 | GPIO_PIN_3;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Init(CW_GPIOC, &GPIO_InitStructure);
//LEDs are off.
PC02_SETLOW();
PC03_SETLOW();
}
//LVD中斷服務(wù)函數(shù)
void LVD_IRQHandler(void)
{
LVD_ClearIrq(); //清除中斷標(biāo)志
gFlagIrq = TRUE; //將gFlagIrq賦值為TURE,使main函數(shù)中的if判斷語句生效
}
上述例程中的LVD_PortInit()為前文LVD的IO口配置函數(shù),下面例程為通過寄存器配置LVD,具體功能與上述例程一樣。
void LVD_PortInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
//打開GPIOA時(shí)鐘
__RCC_GPIOA_CLK_ENABLE();
//將PA08設(shè)置為LVD比較結(jié)果輸出
GPIO_InitStructure.Pins = GPIO_PIN_8;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Init(CW_GPIOA, &GPIO_InitStructure);
//將PA08復(fù)用為LVD比較結(jié)果輸出
PA08_AFx_LVDOUT();
//將PA00設(shè)置為LVD的輸入口
PA00_ANALOG_ENABLE();
}
int main(void)
{
//LED初始化
LED_Init();
//配置測(cè)試IO口
LVD_PortInit();
CW_LVD->CR0_f.SOURCE=1; //選擇待監(jiān)測(cè)的電壓來源為PA00
CW_LVD->CR0_f.VTH=0; //選擇閾值電壓為2.02V
CW_LVD->CR1_f.FLTTIME=7; //選擇 LVD 濾波寬度為4095個(gè)時(shí)鐘周期信號(hào)
CW_LVD->CR1_f.FLTCLK=0; //選擇濾波時(shí)鐘為150KHz的RC振蕩時(shí)鐘
CW_LVD->CR1_f.FLTEN=1; //使能 LVD 濾波
CW_LVD->CR1_f.RISE=1; //下降沿觸發(fā)
CW_LVD->CR1_f.FALL=1; //上升沿觸發(fā)
CW_LVD->CR0_f.ACTION=0; //選擇LVD觸發(fā)為中斷
CW_LVD->CR0_f.IE=1; //使能LVD中斷
NVIC_ClearPendingIRQ(LVD_IRQn); //使能NVIC中斷向量表中的LVD中斷
NVIC_SetPriority(LVD_IRQn, 3);
NVIC_EnableIRQ(LVD_IRQn);
FirmwareDelay(4800);
CW_LVD->CR0_f.EN=1; //使能LVD
CW_LVD->SR_f.INTF=0; //清除LVD中斷標(biāo)志
while (1)
{
if (gFlagIrq)
{
PC03_TOG();
gFlagIrq = FALSE;
}
}
}
/**@brief LED I/O初始化**/
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
//打開GPIOC時(shí)鐘
__RCC_GPIOC_CLK_ENABLE();
/* Configure the GPIO_LED pin */
GPIO_InitStructure.Pins = GPIO_PIN_2 | GPIO_PIN_3;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Init(CW_GPIOC, &GPIO_InitStructure);
//LEDs are off.
PC02_SETLOW();
PC03_SETLOW();
}
//LVD中斷服務(wù)函數(shù)
void LVD_IRQHandler(void)
{
LVD_ClearIrq(); //清除中斷標(biāo)志
gFlagIrq = TRUE; //將gFlagIrq賦值為TURE,使main函數(shù)中的if判斷語句生效
}
上述例程功能為在PA00的輸入電壓值低于2.02v或高于2.02v的時(shí)刻,LVD會(huì)產(chǎn)生中斷,PC03的輸出電平會(huì)產(chǎn)生翻轉(zhuǎn),可利用CW32L083的開發(fā)板和數(shù)字電源進(jìn)行測(cè)試,將PA00和數(shù)字電源連接,調(diào)節(jié)數(shù)字電源輸出電壓,在升高至門限電壓以上或者下降至門限電壓以下,LED1的狀態(tài)會(huì)發(fā)生翻轉(zhuǎn)。
LVD的相關(guān)函數(shù)及功能,可參考下述介紹。
1.void LVD_EnableNvic(uint8_t intPriority);
//使能NVIC中LVD中斷
2.void LVD_DisableNvic(void);
//禁止NVIC中LVD中斷
3.void LVD_TrigConfig(uint16_t LVD_TRIG, FunctionalState NewState);
//配置LVD中斷/系統(tǒng)復(fù)位觸發(fā)方式
4.void LVD_EnableIrq(uint8_t intPriority);
//使能LVD中斷
5.void LVD_DisableIrq(void);
//禁止LVD中斷
6.void LVD_ClearIrq(void);
//清除LVD中斷標(biāo)志
7.boolean_t LVD_GetIrqStatus(void);
//獲取LVD中斷標(biāo)志
8.FlagStatus LVD_GetFlagStatus(uint16_t LVD_FLAG);
//獲取LVD指定的狀態(tài)位
9.boolean_t LVD_GetFilterResult(void);
//獲取Filter結(jié)果
10.void LVD_Init(LVD_InitTypeDef* LVD_InitStruct);
//LVD初始化
11.void LVD_DeInit(void);
//LVD去初始化
12.void LVD_Enable(void);
//使能LVD
13.void LVD_Disable(void);
//停止LVD
CW32的LVD的使用介紹到此結(jié)束。
-
微控制器
+關(guān)注
關(guān)注
48文章
7542瀏覽量
151316 -
單片機(jī)
+關(guān)注
關(guān)注
6035文章
44554瀏覽量
634634 -
mcu
+關(guān)注
關(guān)注
146文章
17123瀏覽量
350983
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論