GD32F10x的SleepMode

#include "SleepMode.h"

u8 WFE_CMD_EnterSleepModeFlag;

void Enter_SleepMode0_Use_WFI_CMD(void);
void Enter_SleepMode0_Use_WFE_CMD(void);
void Enter_SleepMode1_Use_WFE_CMD(void);
void USART0_Init(unsigned int bound);
void KEY2_Init(void);

//函数功能:使用WFI命令使CPU进入睡眠模式
void Enter_SleepMode0_Use_WFI_CMD(void)
{
    rcu_periph_clock_enable(RCU_PMU);//使能RCU_PMU外设时钟

    WFE_CMD_EnterSleepModeFlag=0;
    pmu_to_sleepmode(WFI_CMD);
    //SLEEPDEEP=0,使用WFI命令使CPU进入睡眠模式,仅关闭CPU时钟
  //唤醒:若通过WFI进入,则任何中断均可唤醒,本程序使用USART0接收中断;
}

//函数功能:使用WFE命令使CPU进入睡眠模式
void Enter_SleepMode0_Use_WFE_CMD(void)
{
    rcu_periph_clock_enable(RCU_PMU);//使能RCU_PMU外设时钟

    system_lowpower_set(SCB_LPM_WAKE_BY_ALL_INT);//设置SEVONPEND=1
    WFE_CMD_EnterSleepModeFlag=1;
    pmu_to_sleepmode(WFE_CMD);
    //SLEEPDEEP=0,使用WFE命令使CPU进入睡眠模式,仅关闭CPU时钟
  //唤醒:若通过WFE进入,则任何事件(或SEVONPEND=1时的中断)均可唤醒,本程序使用USART0接收中断;
}

//函数功能:使用WFE命令使CPU进入睡眠模式,换醒使用外部事件
void Enter_SleepMode1_Use_WFE_CMD(void)
{
    rcu_periph_clock_enable(RCU_PMU);//使能RCU_PMU外设时钟

    system_lowpower_reset(SCB_LPM_WAKE_BY_ALL_INT);//设置SEVONPEND=0
    WFE_CMD_EnterSleepModeFlag=2;
    pmu_to_sleepmode(WFE_CMD);
    //SLEEPDEEP=0,使用WFE命令使CPU进入睡眠模式,仅关闭CPU时钟
  //唤醒:若通过WFE进入,则任何事件(或SEVONPEND=1时的中断)均可唤醒,本程序使用外部事件唤醒;
}

//函数功能:初始化USART0
void USART0_Init(unsigned int bound)
{
    //NVIC_PRIGROUP_PRE4_SUB0:抢占优先级为4bit(取值为0~15),子优先级为0bit(没有响应优先级)
    //NVIC_PRIGROUP_PRE3_SUB1:抢占优先级为3bit(取值为0~7),子优先级为1bit(取值为0~1)
    //NVIC_PRIGROUP_PRE2_SUB2:抢占优先级为2bit(取值为0~3),子优先级为2bit(取值为0~3)
    //NVIC_PRIGROUP_PRE1_SUB3:抢占优先级为1bit(取值为0~1),子优先级为3bit(取值为0~7)
    //NVIC_PRIGROUP_PRE0_SUB4:抢占优先级为0bit(没有抢占优先级),子优先级为3bit(取值为0~15)
    //nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);//设置系统中断优先级"抢占优先级为4bit,子优先级为0bit"
    nvic_irq_enable(USART0_IRQn, 0, 0);
    //设置USART0_IRQn的中断优先级,抢占优先级为0,子优先级为0,USART interrupt configuration

串口初始化开始/
    rcu_periph_clock_enable(RCU_GPIOA);  //使能GPIOA时钟,enable GPIO clock 
    rcu_periph_clock_enable(RCU_USART0); //使能USART时钟,enable USART clock

    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
    //将GPIOA9设置为AFIO口(复用IO口),输出上拉

    gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
    //将GPIOA10设置为浮空输入口

    usart_deinit(USART0);                        //复位USART0,USART configure
    usart_baudrate_set(USART0,bound);          //设置USART0的波特率
    usart_word_length_set(USART0,USART_WL_8BIT); //设置USART0数据传输格式为8位
    usart_stop_bit_set(USART0,USART_STB_1BIT);   //设置USART0停止位为1位
    usart_parity_config(USART0,USART_PM_NONE);   //设置USART0无需奇偶校验
    usart_hardware_flow_rts_config(USART0,USART_RTS_DISABLE);  //设置不使能USART0的RTS引脚功能
    usart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE); //设置不使能USART0的CTS引脚功能

    usart_receive_config(USART0, USART_RECEIVE_ENABLE);
    //根据USART_RECEIVE_ENABLE,设置串口控制寄存器USART_CTL0的串口接收使能
    usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
    //根据USART_TRANSMIT_ENABLE,设置串口控制寄存器USART_CTL0的串口发送使能
    usart_enable(USART0);//使能串口模块
串口初始化结束/

    USART0_Init(115200);//初始化USART0
    usart_interrupt_enable(USART0, USART_INT_RBNE);
    //根据USART_INT_RBNE指定,使能串口接收寄存区为非空时产生中断
    //read data buffer not empty interrupt and overrun error interrupt
    //enable USART0 receive interrupt

/在串口中断服务函数中发送数据配置开始//
    usart_interrupt_enable(USART0, USART_INT_TBE);
    //根据USART_INT_TBE指定,使能串口发送缓冲区为空中断
    usart_interrupt_disable(USART0, USART_INT_TC);
    //根据USART_INT_TC指定,不使能串口发送完成中断
/在串口中断服务函数中发送数据配置结束//
}

//函数功能:串口中断服务程序
void USART0_IRQHandler(void)
{
    if(RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE))
    {
        if(WFE_CMD_EnterSleepModeFlag)
        {//使用WFE命令使CPU进入睡眠模式,中断唤醒需要将SEVONPEND=0
            system_lowpower_reset(SCB_LPM_WAKE_BY_ALL_INT);
        }
        usart_interrupt_flag_clear(USART0, USART_INT_FLAG_RBNE);
    }
}

//函数功能:初始化KEY2
void KEY2_Init(void)
{
    rcu_periph_clock_enable(RCU_GPIOC);//使能GPIOC时钟,enable GPIO clock
    rcu_periph_clock_enable(RCU_AF);//使能复用功能时钟

    gpio_init(GPIOC, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_13);//将GPIOC13设置为浮空输入

    nvic_irq_enable(EXTI10_15_IRQn, 2U, 0U);//设置EXTI10_15_IRQn的中断优先级,抢占优先级为2,子优先级为0
    gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOC, GPIO_PIN_SOURCE_13);
    //设置GC13引脚为外部中断源,select GPIO pin exti sources
  exti_init(EXTI_13, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
    //配置外部中断线使用外部中断13(EXTI_13)
    //中断模式为外部中断(EXTI_INTERRUPT)
    //中断触发方式为下降沿中断(EXTI_TRIG_FALLING)
    exti_interrupt_flag_clear(EXTI_13);//使能外部中断13(EXTI_13)
}

//this function handles external lines 10 to 15 interrupt request
//函数功能:外部中断10~外部中断15的中断服务函数
void EXTI10_15_IRQHandler(void)
{
    FlagStatus ret;

    ret=exti_interrupt_flag_get(EXTI_13);
    //读取外部中断13(EXTI_13)的中断标志
    //get EXTI lines flag when the interrupt flag is set
    if(RESET != ret)
    {
    }
    exti_interrupt_flag_clear(EXTI_13);
}

 

#include "gd32f10x.h" //使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t,bool
#include "delay.h"

#include "LED.h"

#include "SleepMode.h"

//PC13仅可以作为RTC功能引脚
//PC14和PC15可以作为通用I/O口或外部32.768KHz低速晶振引脚
int main(void)
{
    //MySystemClockInit(1,1);

    //NVIC_PRIGROUP_PRE4_SUB0:抢占优先级为4bit(取值为0~15),子优先级为0bit(没有响应优先级)
    //NVIC_PRIGROUP_PRE3_SUB1:抢占优先级为3bit(取值为0~7),子优先级为1bit(取值为0~1)
    //NVIC_PRIGROUP_PRE2_SUB2:抢占优先级为2bit(取值为0~3),子优先级为2bit(取值为0~3)
    //NVIC_PRIGROUP_PRE1_SUB3:抢占优先级为1bit(取值为0~1),子优先级为3bit(取值为0~7)
    //NVIC_PRIGROUP_PRE0_SUB4:抢占优先级为0bit(没有抢占优先级),子优先级为3bit(取值为0~15)
    nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);//设置系统中断优先级"抢占优先级为4bit,子优先级为0bit"

  INTX_ENABLE();//开启所有中断

    LED2_Init();//初始化LED2端口

    delay_init();//系统时钟配置
    LED2_Off();

    USART0_Init(115200);
    KEY2_Init();
    Enter_SleepMode0_Use_WFI_CMD();   //使用WFI命令使CPU进入睡眠模式
    //Enter_SleepMode0_Use_WFE_CMD(); //使用WFE命令使CPU进入睡眠模式
    //Enter_SleepMode1_Use_WFE_CMD(); //使用WFE命令使CPU进入睡眠模式,换醒使用外部事件
    while(1)//唤醒后,则灯闪烁
    {
        delay_ms(500);
        LED2_Toggle();
    }
}
 

你可能感兴趣的:(产品研发,程序人生,经验分享,面试,单片机,嵌入式)