[范例教程]

【M0】 MG32F02A 学习笔记⑭ EXIC唤醒

[复制链接]
1204|1
手机看帖
扫描二维码
随时随地手机跟帖
noctor|  楼主 | 2018-10-19 13:57 | 显示全部楼层 |阅读模式
本帖最后由 noctor 于 2018-10-19 13:57 编辑
      上回我们说到了MG32F02A的SLEEP以及STOP的使用。帖子详情:https://bbs.21ic.com/icview-2570532-1-1.html

       但是上次没有讲怎么唤醒,哈哈,那这次来讲讲唤醒的方法吧,首先,我们要了解,我们进入的SLEEP以及STOP,支持什么方式唤醒呢?
       326935bc96b4cf28ba.png
      这图够直观了吧,SLEEP可以被所有的中断或者唤醒事件唤醒,而STOP模式只支持BOD/CMP/RTC/EXIC/IIC唤醒,那么,我就直接讲从STOP下唤醒吧,毕竟只要能从STOP唤醒,SLEEP自然不在话下。
      那么,这次先讲EXIC的方式唤醒吧。
      所谓EXIC,就是外部中断,简单来讲的话就像键盘中断,只要引脚来个低电平,EXIC就会被触发,而MG32F02A内置的终端控制器会在STOP模式下自动发送一个系统事件给CPU,从而唤醒CPU。
      代码放在二楼。      你们实验的时候可能会发现:明明STOP模式只支持检测LEVEL唤醒,为什么我EXIC_TRGS.EXIC_TRGS_Mode = Edge;  也能唤醒呢?是不是进的是SLEEP而根本不是STOP呢?
884995bc97231d73d5.png
      硬件会强行修改为level模式进行检测,还挺人性化哈。

noctor|  楼主 | 2018-10-19 13:57 | 显示全部楼层
附上代码,烧入代码后,PE15闪烁5次后进入STOP模式,然后只需要将PA2“或”PA3,或者PA0“和”PA1接地即可触发中断,并唤醒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 PWR_Init()
{
        UnProtectModuleReg(PWprotect);
        PW_IT_Config(PW_INT_WK , ENABLE);
        PW_ITEA_Cmd(ENABLE);
        ProtectModuleReg(PWprotect);
}

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_PIN0 | EXIC_TRGS_PIN1 | EXIC_TRGS_PIN2 | EXIC_TRGS_PIN3;  //     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);
}

int main()
{
        int i,j;
        double x,y;
        PIN_InitTypeDef PINX_InitStruct;
        CSC_Init();
        EXIC_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(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;
                        }         
                }
        }
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

26

主题

82

帖子

3

粉丝