[范例教程] 【M0】 MG32F02A 学习笔记⑮ BOD唤醒

[复制链接]
1045|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中,可用于系统唤醒的功能。
      上一下源码:

  1. #include "MG32x02z_DRV.H"
  2. #include "MG32x02z_ADC_DRV.h"
  3. #include "MG32x02z_PW_DRV.h"
  4. #include <stdio.h>

  5. typedef uint8_t u8;
  6. typedef uint16_t u16;
  7. typedef uint32_t u32;
  8. typedef uint64_t u64;

  9. void CSC_Init (void)
  10. {
  11.         CSC_PLL_TyprDef CSC_PLL_CFG;
  12.    
  13.        
  14.     UnProtectModuleReg(MEMprotect);             // Setting flash wait state
  15.     MEM_SetFlashWaitState(MEM_FWAIT_ONE);        // 50MHz> Sysclk >=25MHz
  16.     ProtectModuleReg(MEMprotect);

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

  20.        
  21.         /* CK_HS selection */
  22.         CSC_IHRCO_Select(IHRCO_12MHz);                        // IHRCO Sel 12MHz
  23.         CSC_IHRCO_Cmd(ENABLE);
  24.         while(CSC_GetSingleFlagStatus(CSC_IHRCOF) == DRV_Normal);
  25.         CSC_ClearFlag(CSC_IHRCOF);
  26.         CSC_CK_HS_Select(HS_CK_IHRCO);                        // CK_HS select IHRCO


  27.         /* PLL */
  28.         /**********************************************************/
  29.         CSC_PLL_CFG.InputDivider=PLLI_DIV_2;        // 12M/2=6M
  30.         CSC_PLL_CFG.Multiplication=PLLIx16;                // 6M*16=96M
  31.         CSC_PLL_CFG.OutputDivider=PLLO_DIV_2;        // PLLO=96M/2=48M
  32.         CSC_PLL_Config(&CSC_PLL_CFG);
  33.         CSC_PLL_Cmd(ENABLE);
  34.         while(CSC_GetSingleFlagStatus(CSC_PLLF) == DRV_Normal);
  35.         CSC_ClearFlag(CSC_PLLF);
  36.         /**********************************************************/

  37.        
  38.         /* CK_MAIN */
  39.         CSC_CK_MAIN_Select(MAIN_CK_HS);       


  40.         /* Configure ICKO function */
  41.                
  42.         /* Configure peripheral clock */
  43.         CSC_PeriphOnModeClock_Config(CSC_ON_PortA,ENABLE);
  44.         CSC_PeriphOnModeClock_Config(CSC_ON_PortE,ENABLE);

  45.   ProtectModuleReg(CSCprotect);
  46.    
  47. }

  48. void EXIC_Init(void)
  49. {
  50.     PIN_InitTypeDef  PINX_InitStruct;
  51.     EXIC_TRGSTypeDef EXIC_TRGS;
  52.    
  53.     //===Set CSC init====
  54.     //MG32x02z_CSC_Init.h(Configuration Wizard)
  55.     //Select CK_HS source = CK_IHRCO
  56.     //Select IHRCO = 11.0592M
  57.     //Select CK_MAIN Source = CK_HS
  58.     //Configure PLL->Select APB Prescaler = CK_MAIN/1
  59.     //Configure Peripheral On Mode Clock->Port A = Enable if EXIC Port is PortA
  60.    
  61.    
  62.     //====GPIO Initial====
  63.     PINX_InitStruct.PINX_Pin                = PX_Pin_All;                     // Select Pin of the port to initial (PX_Pin_All is all pin of the port.)
  64.     PINX_InitStruct.PINX_Mode                                                                = PINX_Mode_OpenDrain_O;          // Select GPIO mode
  65.                                                                               //     1.QB: Quasi-Bidirection mode only for PC )
  66.     PINX_InitStruct.PINX_PUResistant        = PINX_PUResistant_Enable;        // Select wether enable internal pull-up R or not.
  67.     PINX_InitStruct.PINX_Speed              = PINX_Speed_Low;                 // Select wehter enable high speed mode
  68.                                                                               //     1.(PINX_Speed_High mode only for PC0~3 , PD0~3 )   
  69.     PINX_InitStruct.PINX_OUTDrive           = PINX_OUTDrive_Level0;           // Select output drive strength
  70.                                                                               //     1.(Level 0 & level 3 only for PE0~PE3)
  71.     PINX_InitStruct.PINX_FilterDivider      = PINX_FilterDivider_Bypass;      // Select input filter divider.
  72.     PINX_InitStruct.PINX_Inverse            = PINX_Inverse_Disable;           // Select input signal whether inverse or not.
  73.                                                                               //     1.PINX_Inverse_Disable = L level or falling edge.
  74.                                                                               //     2.PINX_Inverse_Enable  = H level or Rising edge.
  75.     PINX_InitStruct.PINX_Alternate_Function = 0;                              // Select GPIO mode
  76.     GPIO_PortMode_Config(IOMA,&PINX_InitStruct);                              // (Pin0 & Pin1) of PorA configuration
  77.                 GPIO_WritePort(GPIOA,0xFFFF);                                                                                                                                                                                 // Initial PortA
  78.    
  79.     //====EXIC Initial====
  80. //   EXIC_TRGS.EXIC_Pin = EXIC_TRGS_ALL;                                       // The pin trigger mode select.
  81.     EXIC_TRGS.EXIC_Pin = EXIC_TRGS_PIN2 | EXIC_TRGS_PIN3 | EXIC_TRGS_PIN4;  //     1. You can selec any pin of the port.
  82.     EXIC_TRGS.EXIC_TRGS_Mode = Level;                                          // External interrupt pin edge/level trigger event select.
  83.     EXIC_PxTriggerMode_Select(EXIC_PA,&EXIC_TRGS);                            // EXIC trigger mode configuration.
  84.    
  85.     EXIC_PxTriggerAndMask_Select(EXIC_PA , 0x0003);                           // EXIC_PA  AF trigger event select.
  86.                                                                               //     1. Select PA_AF trigger pin(PA0, PA1).
  87.                                                                               //     2. PA_AF is set if trigger event of select pin have to happen at same time(PA0 & PA1).  
  88.     EXIC_PxTriggerOrMask_Select(EXIC_PA  , 0x000C);                           // EXIC_PA  OF trigger event select.
  89.                                                                               //     1. Select PA_OF trigger pin(PA2, PA3).
  90.                                                                               //     2. PA_OF is set if anyone trigger event of select pin happen(PA2 | PA3).   
  91.     EXIC_ClearPxTriggerEventFlag(EXIC_PA, EXIC_PX_AllPIN );                   // Clear All pin of the port event flag.   
  92.    
  93.     EXIC_PxTriggerITEA_Cmd(EXIC_PA_IT , ENABLE);                              // Enable EXIC interrupt
  94.     NVIC_EnableIRQ(EXINT0_IRQn);                                              //
  95.    
  96.     //===Interrupt handle====
  97.     //Please refer to MG32x02z_EXIC_IRQ.c

  98. }

  99. void EXINT0_IRQHandler(void)
  100. {

  101.          PE14=~PE14;
  102.          EXIC_ClearPxTriggerEventFlag(EXIC_PA, EXIC_PX_AllPIN );
  103.    EXIC_ClearPxTriggerITFlag(EXIC_PA_ITF,EXIC_PX_OF);
  104. }

  105. void PW_Init()
  106. {
  107.         UnProtectModuleReg(PWprotect);
  108.         NVIC_EnableIRQ(SYS_IRQn);
  109.         PW_StopModeLDO_Select(PW_LowPower_LDO);
  110.         PW_OnModeLDO_Select(PW_Normal_LDO);
  111.         PW_BOD1Threshold_Select (PW_BOD1_3V7);      //detecting voltage
  112.         PW_BOD1Trigger_Select(PW_BOD1_FallingEdge);
  113.         PW_BOD1_Cmd(ENABLE);
  114.         PW_IntVoltageRef(ENABLE);
  115.         PW_PeriphStopModeContinuous_Config(PW_STPPO_BOD1, ENABLE);
  116.         PW_PeriphStopModeWakeUp_Config(PW_WKSTP_BOD1, ENABLE);
  117.         PW_IT_Config((PW_INT_WK | PW_INT_BOD1), ENABLE);
  118.         PW_ClearFlag(PW_BOD1F);
  119.         PW_ITEA_Cmd(ENABLE);
  120.         ProtectModuleReg(PWprotect);
  121. }

  122. void SYS_IRQHandler(void)
  123. {
  124.   if(PW_GetSingleFlagStatus(PW_BOD1F) == DRV_Happened)
  125.   {
  126.                 PE13=~PE13;
  127.     PW_ClearFlag(PW_BOD1F);
  128.   }
  129. }

  130. int main()
  131. {
  132.         int i,j;
  133.         PIN_InitTypeDef PINX_InitStruct;
  134.         CSC_Init();
  135.         EXIC_Init();
  136.         PW_Init();
  137.         PINX_InitStruct.PINX_Mode                                 = PINX_Mode_PushPull_O;          // Pin select digital input mode
  138.         PINX_InitStruct.PINX_PUResistant                 = PINX_PUResistant_Enable;  // Enable pull up resistor
  139.         PINX_InitStruct.PINX_Speed                                   = PINX_Speed_Low;                         
  140.         PINX_InitStruct.PINX_OUTDrive                         = PINX_OUTDrive_Level0;         // Pin output driver full strength.
  141.         PINX_InitStruct.PINX_FilterDivider                   = PINX_FilterDivider_Bypass;// Pin input deglitch filter clock divider bypass
  142.         PINX_InitStruct.PINX_Inverse                         = PINX_Inverse_Disable;         // Pin input data not inverse
  143.         PINX_InitStruct.PINX_Alternate_Function = 0;                                                 // Pin AFS = 0
  144.         GPIO_PinMode_Config(PINE(13),&PINX_InitStruct);                                          // D6 setup at PE15
  145.         GPIO_PinMode_Config(PINE(14),&PINX_InitStruct);                                          // D6 setup at PE15
  146.   GPIO_PinMode_Config(PINE(15),&PINX_InitStruct);                                          // D6 setup at PE15
  147.         i=0;
  148.         j=0;
  149.         while(1)
  150.         {
  151.                 i++;
  152.                 if(i>=500000){
  153.                         i=0;
  154.                         PE15=~PE15;
  155.                         j++;
  156.                         if(j>10)
  157.                         {
  158.                           PE15=1;                               
  159.                                 SCB->SCR  = (SCB_SCR_SLEEPDEEP_Msk);  //into stop
  160.                                 __WFI();             //This is the command of cmsis_arm.cc.  __WFI();is wait for interrupt while __WFE();is wait for event();
  161.                                 j=0;
  162.                         }         
  163.                 }
  164.         }
  165. }
       在配置中,我设置为下降沿触发,也就是说,是从高于3.7V到低于3.7V的过程中才会触发,而反过来,不会触发。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

26

主题

82

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部