stm32之PVD可编程电压监测器(掉电保存数据)
生活随笔
收集整理的這篇文章主要介紹了
stm32之PVD可编程电压监测器(掉电保存数据)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
前言:stm32系列提供了可編程電壓檢測器PVD,它是實時檢測VDD的電壓,當檢測到電壓低于或者高于PVD設置的閾值時,會想內核產生一個PVD中斷(EXTI線中斷)以使內核在復位前進行緊急處理。該電壓閾值可通過PWR_CSR設置。
PVD可配置8個等級:
代碼設計:
#include "stm32f10x.h" #include "stdio.h"static void EXTI_Configuration(void); static void PVD_NVIC_Configuration(void); static void USART1_Config(void); static void Delay(__IO u32 nCount);int main(void) { USART1_Config();//使用串口1來打印調試信息RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); //使能PVD電壓檢測模塊的時鐘//通過執行下面兩個中斷配置函數后,當VDD電壓高于或者低于閾值時,就會進入PVD_IRQHandler中斷EXTI_Configuration();//配置EXTI_Line16外部中斷PVD_NVIC_Configuration();//PVD中斷優先級PWR_PVDLevelConfig(PWR_PVDLevel_2V9);//設置PVD閾值PWR_PVDCmd(ENABLE);//使能PVD電壓檢測while(1){Delay(0xfffff);printf("STM32正常工作中...\r\n");//去掉上面兩個中斷配置函數,也可以在while循環里不斷查詢PWR狀態來判斷VDD電壓是否高于或低于閾值,如下#if 0if(PWR_GetFlagStatus(PWR_FLAG_PVDO)){ printf("電壓低于閾值.\r\n");}else{printf("電壓高于閾值.\r\n");}#endif} }void EXTI_Configuration(void) {EXTI_InitTypeDef EXTI_InitStructure;EXTI_DeInit();EXTI_StructInit(&EXTI_InitStructure);EXTI_InitStructure.EXTI_Line = EXTI_Line16;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;//上升沿和下降沿都觸發EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure); }void PVD_NVIC_Configuration(void) {NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); NVIC_InitStructure.NVIC_IRQChannel = PVD_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure); }void USART1_Config(void) {GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;//配置串口1(USART1)時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);//配置串口1(USART1 Tx (PA.09))GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);//配置串口1 USART1 Rx (PA.10)GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStructure);//串口1模式(USART1 mode)配置 USART_InitStructure.USART_BaudRate = 9600;//一般設置為9600;USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_Parity = USART_Parity_No ;USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode = USART_Mode_Tx;USART_Init(USART1, &USART_InitStructure);USART_Cmd(USART1, ENABLE); //使能串口 }int fputc(int ch, FILE *f)//重寫標準庫的fputc函數 {//將Printf內容發往串口USART_SendData(USART1, (unsigned char) ch);while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET); return (ch); }void Delay(__IO u32 nCount) //簡單的延時函數 {for(; nCount != 0; nCount--); }在stm32f10x_it.c文件加入:
void PVD_IRQHandler(void) {if (EXTI_GetITStatus(EXTI_Line16) != RESET){if(PWR_GetFlagStatus(PWR_FLAG_PVDO)==0) //高于閾值{ printf("進入PVD中斷,電壓高于閾值\r\n");}else //低于閾值{printf("進入PVD中斷,電壓低于閾值\r\n");} EXTI_ClearITPendingBit(EXTI_Line16);} }代碼附帶了不少注釋,相信不難理解。編譯下載到板子后,還需要一個可調電源來改變芯片的供電電壓,當電壓低于或者高于閾值的時候,就會進入PVD_IRQHandler中斷,在PC端串口上位機可接受到進入中斷打印的信息。
只要電壓超過2.0v芯片就能正常工作,不是低于閾值就不能工作。所以在實際運用中,如果是用電池給芯片供電,當電池電量不足時,電池的供電電壓就會下降,下降到低于閾值時就會觸發PVD中斷,那么這時候需要進行數據備份處理或者進行低電量提醒。
如果直接切斷電源,進入中斷只能維持很短很短的時間,連一句打印信息也無法完整輸出。解決這個問題,需要在電源輸入點加大電容,當掉電的時候由電容提供電源維持芯片運行一段時候,以做緊急數據保存。所選用電容的參數影響掉電后芯片維持運行的時間,根據掉電中斷處理所需的時間長短來選用電容。
?
?
?
<< 騏驥一躍,不能十步;駑馬十駕,功在不舍。———荀子 >>
總結
以上是生活随笔為你收集整理的stm32之PVD可编程电压监测器(掉电保存数据)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: stm32之电源管理(实现低功耗)
- 下一篇: stm32之实时时钟RTC(掉电计时保持