低功耗STOP2模式下,外部串口唤醒


前言

有些电池供电设备,为了保持正常工作时电量消耗降到最低。因此,我们需要为MCU设置低功耗模式,并设置引脚的状态。
近期我有一个蓝牙近端配置的需求,就是通过蓝牙串口唤醒MCU,并给MCU传输一些数据。


一、如何唤醒

首先,我们需要设置一个RX引脚为外部中断、低电平触发中断。然后在唤醒后,在将引脚配置为串口模式收发数据。同理在睡眠前,我们需要将引脚从串口模式配置为普通的中断,以便唤醒(原理是 串口收到数据时RX上会有一个电平变化,这样就能触发中断来唤醒)。

二、使用步骤

1.RX引脚配置为外部中断

代码如下(示例):

void Wake_RX_InputExtiInit(void)
{
    GPIO_InitType GPIO_InitStructure;
    EXTI_InitType EXTI_InitStructure;
    NVIC_InitType NVIC_InitStructure;

    /* Check the parameters */
    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);
    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE);
    GPIO_InitStructure.Pin        = GPIO_PIN_10;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPD;   //这边配置为输入上拉,如果不行,你自己要配置为其它模式试试
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);

    /*Configure RXEXTI Line to key input Pin*/
    GPIO_ConfigEXTILine(GPIOA_PORT_SOURCE, GPIO_PIN_SOURCE10);

    /*Configure key EXTI line*/
    EXTI_InitStructure.EXTI_Line    = EXTI_LINE10;
    EXTI_InitStructure.EXTI_Mode    = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿 (根据引脚配置状态来配置)
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_InitPeripheral(&EXTI_InitStructure);

    /*Set RXinput interrupt priority*/
    NVIC_InitStructure.NVIC_IRQChannel                   = EXTI15_10_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x06;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}
/* 关闭引脚外部中断 */
void Wake_RX_Close(void)
{
    EXTI_InitType EXTI_InitStructure;
    EXTI_InitStructure.EXTI_Line    = EXTI_LINE10;
    EXTI_InitStructure.EXTI_Mode    = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // EXTI_Trigger_Rising;
    EXTI_InitStructure.EXTI_LineCmd = DISABLE;
    EXTI_InitPeripheral(&EXTI_InitStructure);
}

/* 中断程序 */
void EXTI15_10_IRQHandler(void)
{
    if (RESET != EXTI_GetITStatus(EXTI_LINE10))
    {
        EXTI_ClrITPendBit(EXTI_LINE10); 
    }
}

2.引脚由串口转外部中断配置

   /* 关闭DEBUG串口,切换为中断唤醒模式 */
    USART_ConfigInt(LOG_USARTx, USART_INT_RXDNE, DISABLE);
    USART_Enable(LOG_USARTx, DISABLE);
    USART_DeInit(LOG_USARTx);
    Wake_RX_InputExtiInit();

3.外部中断配置转串口配置

	/* 先关闭引脚外部中断 (这个是关键)*/
	 Wake_RX_Close();
	 /* 配置串口 (这个只是写在这边给大家看,大家可以自己去找一下串口初始化程序)*/
    GPIO_InitType GPIO_InitStructure;
    USART_InitType USART_InitStructure;
    NVIC_InitType NVIC_InitStructure;
    /* Enable the USAR1 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel            = LOG_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
    NVIC_InitStructure.NVIC_IRQChannelCmd         = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
   

    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO | LOG_PERIPH_GPIO, ENABLE);
    LOG_ENABLE_PERIPH_CLK(LOG_PERIPH, ENABLE);


    GPIO_InitStructure.Pin        = LOG_TX_PIN;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitPeripheral(LOG_GPIO, &GPIO_InitStructure);

    GPIO_InitStructure.Pin       = LOG_RX_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitPeripheral(LOG_GPIO, &GPIO_InitStructure);

    USART_InitStructure.BaudRate            = 9600;
    USART_InitStructure.WordLength          = USART_WL_8B;
    USART_InitStructure.StopBits            = USART_STPB_1;
    USART_InitStructure.Parity              = USART_PE_NO;
    USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
    USART_InitStructure.Mode                = USART_MODE_TX|USART_MODE_RX;
    
    // init uart    
    USART_Init(LOG_USARTx, &USART_InitStructure);
    
    USART_ConfigInt(LOG_USARTx, USART_INT_RXDNE, ENABLE);
    // enable uart
    USART_Enable(LOG_USARTx, ENABLE);

总结

如果有不懂的,留言,我懂就帮你看看。麻烦兄弟们看完点个赞吧。

  • 12
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值