Skip to main content
richard23
Associate II
December 18, 2013
Question

Monitoring VDD using the PVD feature

  • December 18, 2013
  • 6 replies
  • 5123 views
Posted on December 18, 2013 at 23:00

I am using a STM32F203IGT6 trying to detect low VDD using the PVD feature.  This seems simple, but I cannot make it work.  My initialization code is below.  I start the peripheral clock set the PLS and PVDE bits (CS = 0x00F0), but the PVDO bit is the CSR does not change when I lower VDD from 3.3 to 2.5V.

The reference manual claims that the PVD monitors VDD/VDDA.  Do both of these voltages need to be blow the threshold?

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

    

    PWR->CR |= 0xe0;  //PV26;  // Set power voltage detection threshold 

    PWR->CR |= PVDE;  // Enable power voltage detection  

    This topic has been closed for replies.

    6 replies

    jpeacock2399
    Associate III
    December 19, 2013
    Posted on December 19, 2013 at 15:57

    Here's how I set up the PVD to trap Vdd falling below 2.9V, early warning for power fail. Inside the PVDinterupt handler check the register

    PWR

    ->

    CSR

    &

    PWR_CSR_PVDO to determine rising or falling edge on the PVD (e.g. 0 is falling edge, voltage rising above 2.9V).

    // Enable the EXTI16 (PVD) Power Supervisor Interrupt 
    // EXTI16 rising edge for falling voltage, falling edge for rising voltage on PVD 
    NVIC_InitStructure.NVIC_IRQChannel = PVD_IRQn; // PVD programmable voltage detect 
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = BKPDEV_PVD_PRIORITY; 
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
    NVIC_Init(&NVIC_InitStructure); 
    PWR_PVDCmd(DISABLE); // disable PVD before change 
    PWR_PVDLevelConfig(PWR_PVDLevel_7); // level falling to trigger powerfail 
    PWR_PVDCmd(ENABLE); // enable PVD 
    EXTI_ClearITPendingBit(EXTI_Line16); // clear pending IRQs 
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; 
    EXTI_InitStructure.EXTI_Line = EXTI_Line16; // set up irq trigger 
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; // trigger power rising edge (voltage drop) 
    EXTI_InitStructure.EXTI_LineCmd = ENABLE; // alert if power status changes 
    EXTI_Init(&EXTI_InitStructure); 

    This gives me a short warning as power drops. How long the CPU will run depends on the discharge rate in the capacitors as Vdd drops, so you can't do much. I save some context in backup RAM so I have a record of the power fail. And yes, monitoring Vdda is important too because it supplies the power to the PLL clock multiplier in addition to the ADC. As the volatge drops on Vdda the PLL will shut down. Jack Peacock
    richard23
    richard23Author
    Associate II
    December 19, 2013
    Posted on December 19, 2013 at 18:29

    Shouldn't it be posible to monitor the PVDO bit in PWR->CSR without setting up the interrupt?

    jpeacock2399
    Associate III
    December 19, 2013
    Posted on December 20, 2013 at 00:26

    Sure, you can poll the PVD status, but you have so little time to react to falling power that you can't guarantee you'll catch the flag in time if you poll occasionally.  And if you do nothing else but poll you don't have any time left for useful work.

    richard23
    richard23Author
    Associate II
    December 23, 2013
    Posted on December 23, 2013 at 14:32

    The issue is that both VDD and VDDA must be below the threshold for the PVDO bit to be set .  This is the case for the brown out as well.   The board I have has  separate VDD and VDDA.  Hence, the BOR and PVD have no effect when VDD falls below the threshold.

    Thanks for your help DeeDeee

    jpeacock2399
    Associate III
    December 23, 2013
    Posted on December 23, 2013 at 23:27

    You can monitor Vdda if you can spare a channel on ADC1.  Use the bandgap voltage reference ADC channel, it averages very close to 1.2VDC.  If your Vdda starts to drop the bandgap sample will start to rise.  Set up an analog watchdog interrupt on the bandgap channel, a narrow range for the AWD and a fast sampling rate on ADC1.  Along with the PVD for Vdd you can monitor both voltages.

      Jack Peacock
    jfcote
    Associate
    November 24, 2014
    Posted on November 24, 2014 at 17:51

    I'm using PVD in polling mode and i also got problem with PVD.  I made a function ReadBattery that is a basically a ''for'' loop setting all PVD threshold level one after the other starting with the lowest one (1.9V) until the PVDO bit is set.  Meaning the VDD is now lower than PVD voltage.  When i was in debug mode tracing step-by-step in my code, everything worked fine.  As soon as i removed the breakpoint and execute the code at normal speed, PVD bit is always LOW.  My problem was that i needed a stabilization delay after setting the new threshold level and polling the PVDO bit.  A 1ms delay seems alright.  I did not find anything in datasheet and reference manual regarding a delay.  The delay explains why everyone using PVD with interrupt did not get any problem because regardless the delay, the interrupt will eventually be trigerred.  But while polling PVDO bit in a for loop, you need a delay.