上回我们说到了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的过程中才会触发,而反过来,不会触发。
|