欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

stm32之PVD可编程电压监测器(掉电保存数据)

发布时间:2024/10/14 编程问答 68 豆豆
生活随笔 收集整理的这篇文章主要介绍了 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可编程电压监测器(掉电保存数据)的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。