[范例教程]

【M0】 MG32F02A 学习笔记⑮ BOD唤醒

[复制链接]
542|0
手机看帖
扫描二维码
随时随地手机跟帖
noctor|  楼主 | 2018-10-22 13:09 | 显示全部楼层 |阅读模式
     上回我们说到了MG32F02A的EXIC唤醒的使用。帖子详情:https://bbs.21ic.com/icview-2570536-1-1.html

      这次,我们讲一下MG32F02A的BOD功能使用。
      首先,讲一下,BOD是什么,BOD,全程Brown-Out-Detect,俗称低压检测器。功能如其名字,检测低压供电的功能。MG32F02A有两路BOD,其中,BOD0是固死检测1.7V的,而BOD1则是可编程用于检测2.0V/2.4V/3.7V/4.2V。当电压到达这个监测点时,BOD就会发送一个系统事件到CPU中,可用于系统唤醒的功能。
      上一下源码:

#include "MG32x02z_DRV.H"
#include "MG32x02z_ADC_DRV.h"
#include "MG32x02z_PW_DRV.h"
#include <stdio.h>

typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;

void CSC_Init (void)
{
        CSC_PLL_TyprDef CSC_PLL_CFG;
   
       
    UnProtectModuleReg(MEMprotect);             // Setting flash wait state
    MEM_SetFlashWaitState(MEM_FWAIT_ONE);        // 50MHz> Sysclk >=25MHz
    ProtectModuleReg(MEMprotect);

  UnProtectModuleReg(CSCprotect);
        CSC_CK_APB_Divider_Select(APB_DIV_1);        // Modify CK_APB divider        APB=CK_MAIN/1
        CSC_CK_AHB_Divider_Select(AHB_DIV_1);        // Modify CK_AHB divider        AHB=APB/1

       
        /* CK_HS selection */
        CSC_IHRCO_Select(IHRCO_12MHz);                        // IHRCO Sel 12MHz
        CSC_IHRCO_Cmd(ENABLE);
        while(CSC_GetSingleFlagStatus(CSC_IHRCOF) == DRV_Normal);
        CSC_ClearFlag(CSC_IHRCOF);
        CSC_CK_HS_Select(HS_CK_IHRCO);                        // CK_HS select IHRCO


        /* PLL */
        /**********************************************************/
        CSC_PLL_CFG.InputDivider=PLLI_DIV_2;        // 12M/2=6M
        CSC_PLL_CFG.Multiplication=PLLIx16;                // 6M*16=96M
        CSC_PLL_CFG.OutputDivider=PLLO_DIV_2;        // PLLO=96M/2=48M
        CSC_PLL_Config(&CSC_PLL_CFG);
        CSC_PLL_Cmd(ENABLE);
        while(CSC_GetSingleFlagStatus(CSC_PLLF) == DRV_Normal);
        CSC_ClearFlag(CSC_PLLF);
        /**********************************************************/

       
        /* CK_MAIN */
        CSC_CK_MAIN_Select(MAIN_CK_HS);       


        /* Configure ICKO function */
               
        /* Configure peripheral clock */
        CSC_PeriphOnModeClock_Config(CSC_ON_PortA,ENABLE);
        CSC_PeriphOnModeClock_Config(CSC_ON_PortE,ENABLE);

  ProtectModuleReg(CSCprotect);
   
}

void EXIC_Init(void)
{
    PIN_InitTypeDef  PINX_InitStruct;
    EXIC_TRGSTypeDef EXIC_TRGS;
   
    //===Set CSC init====
    //MG32x02z_CSC_Init.h(Configuration Wizard)
    //Select CK_HS source = CK_IHRCO
    //Select IHRCO = 11.0592M
    //Select CK_MAIN Source = CK_HS
    //Configure PLL->Select APB Prescaler = CK_MAIN/1
    //Configure Peripheral On Mode Clock->Port A = Enable if EXIC Port is PortA
   
   
    //====GPIO Initial====
    PINX_InitStruct.PINX_Pin                = PX_Pin_All;                     // Select Pin of the port to initial (PX_Pin_All is all pin of the port.)
    PINX_InitStruct.PINX_Mode                                                                = PINX_Mode_OpenDrain_O;          // Select GPIO mode
                                                                              //     1.QB: Quasi-Bidirection mode only for PC )
    PINX_InitStruct.PINX_PUResistant        = PINX_PUResistant_Enable;        // Select wether enable internal pull-up R or not.
    PINX_InitStruct.PINX_Speed              = PINX_Speed_Low;                 // Select wehter enable high speed mode
                                                                              //     1.(PINX_Speed_High mode only for PC0~3 , PD0~3 )   
    PINX_InitStruct.PINX_OUTDrive           = PINX_OUTDrive_Level0;           // Select output drive strength
                                                                              //     1.(Level 0 & level 3 only for PE0~PE3)
    PINX_InitStruct.PINX_FilterDivider      = PINX_FilterDivider_Bypass;      // Select input filter divider.
    PINX_InitStruct.PINX_Inverse            = PINX_Inverse_Disable;           // Select input signal whether inverse or not.
                                                                              //     1.PINX_Inverse_Disable = L level or falling edge.
                                                                              //     2.PINX_Inverse_Enable  = H level or Rising edge.
    PINX_InitStruct.PINX_Alternate_Function = 0;                              // Select GPIO mode
    GPIO_PortMode_Config(IOMA,&PINX_InitStruct);                              // (Pin0 & Pin1) of PorA configuration
                GPIO_WritePort(GPIOA,0xFFFF);                                                                                                                                                                                 // Initial PortA
   
    //====EXIC Initial====
//   EXIC_TRGS.EXIC_Pin = EXIC_TRGS_ALL;                                       // The pin trigger mode select.
    EXIC_TRGS.EXIC_Pin = EXIC_TRGS_PIN2 | EXIC_TRGS_PIN3 | EXIC_TRGS_PIN4;  //     1. You can selec any pin of the port.
    EXIC_TRGS.EXIC_TRGS_Mode = Level;                                          // External interrupt pin edge/level trigger event select.
    EXIC_PxTriggerMode_Select(EXIC_PA,&EXIC_TRGS);                            // EXIC trigger mode configuration.
   
    EXIC_PxTriggerAndMask_Select(EXIC_PA , 0x0003);                           // EXIC_PA  AF trigger event select.
                                                                              //     1. Select PA_AF trigger pin(PA0, PA1).
                                                                              //     2. PA_AF is set if trigger event of select pin have to happen at same time(PA0 & PA1).  
    EXIC_PxTriggerOrMask_Select(EXIC_PA  , 0x000C);                           // EXIC_PA  OF trigger event select.
                                                                              //     1. Select PA_OF trigger pin(PA2, PA3).
                                                                              //     2. PA_OF is set if anyone trigger event of select pin happen(PA2 | PA3).   
    EXIC_ClearPxTriggerEventFlag(EXIC_PA, EXIC_PX_AllPIN );                   // Clear All pin of the port event flag.   
   
    EXIC_PxTriggerITEA_Cmd(EXIC_PA_IT , ENABLE);                              // Enable EXIC interrupt
    NVIC_EnableIRQ(EXINT0_IRQn);                                              //
   
    //===Interrupt handle====
    //Please refer to MG32x02z_EXIC_IRQ.c

}

void EXINT0_IRQHandler(void)
{

         PE14=~PE14;
         EXIC_ClearPxTriggerEventFlag(EXIC_PA, EXIC_PX_AllPIN );
   EXIC_ClearPxTriggerITFlag(EXIC_PA_ITF,EXIC_PX_OF);
}

void PW_Init()
{
        UnProtectModuleReg(PWprotect);
        NVIC_EnableIRQ(SYS_IRQn);
        PW_StopModeLDO_Select(PW_LowPower_LDO);
        PW_OnModeLDO_Select(PW_Normal_LDO);
        PW_BOD1Threshold_Select (PW_BOD1_3V7);      //detecting voltage
        PW_BOD1Trigger_Select(PW_BOD1_FallingEdge);
        PW_BOD1_Cmd(ENABLE);
        PW_IntVoltageRef(ENABLE);
        PW_PeriphStopModeContinuous_Config(PW_STPPO_BOD1, ENABLE);
        PW_PeriphStopModeWakeUp_Config(PW_WKSTP_BOD1, ENABLE);
        PW_IT_Config((PW_INT_WK | PW_INT_BOD1), ENABLE);
        PW_ClearFlag(PW_BOD1F);
        PW_ITEA_Cmd(ENABLE);
        ProtectModuleReg(PWprotect);
}

void SYS_IRQHandler(void)
{
  if(PW_GetSingleFlagStatus(PW_BOD1F) == DRV_Happened)
  {
                PE13=~PE13;
    PW_ClearFlag(PW_BOD1F);
  }
}

int main()
{
        int i,j;
        PIN_InitTypeDef PINX_InitStruct;
        CSC_Init();
        EXIC_Init();
        PW_Init();
        PINX_InitStruct.PINX_Mode                                 = PINX_Mode_PushPull_O;          // Pin select digital input mode
        PINX_InitStruct.PINX_PUResistant                 = PINX_PUResistant_Enable;  // Enable pull up resistor
        PINX_InitStruct.PINX_Speed                                   = PINX_Speed_Low;                         
        PINX_InitStruct.PINX_OUTDrive                         = PINX_OUTDrive_Level0;         // Pin output driver full strength.
        PINX_InitStruct.PINX_FilterDivider                   = PINX_FilterDivider_Bypass;// Pin input deglitch filter clock divider bypass
        PINX_InitStruct.PINX_Inverse                         = PINX_Inverse_Disable;         // Pin input data not inverse
        PINX_InitStruct.PINX_Alternate_Function = 0;                                                 // Pin AFS = 0
        GPIO_PinMode_Config(PINE(13),&PINX_InitStruct);                                          // D6 setup at PE15
        GPIO_PinMode_Config(PINE(14),&PINX_InitStruct);                                          // D6 setup at PE15
  GPIO_PinMode_Config(PINE(15),&PINX_InitStruct);                                          // D6 setup at PE15
        i=0;
        j=0;
        while(1)
        {
                i++;
                if(i>=500000){
                        i=0;
                        PE15=~PE15;
                        j++;
                        if(j>10)
                        {
                          PE15=1;                               
                                SCB->SCR  = (SCB_SCR_SLEEPDEEP_Msk);  //into stop
                                __WFI();             //This is the command of cmsis_arm.cc.  __WFI();is wait for interrupt while __WFE();is wait for event();
                                j=0;
                        }         
                }
        }
}
       在配置中,我设置为下降沿触发,也就是说,是从高于3.7V到低于3.7V的过程中才会触发,而反过来,不会触发。
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

26

主题

82

帖子

3

粉丝