前言
有些电池供电设备,为了保持正常工作时电量消耗降到最低。因此,我们需要为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);
总结
如果有不懂的,留言,我懂就帮你看看。麻烦兄弟们看完点个赞吧。