需求:需要将uart中的rx脚(PA3)在MCU处于休眠时,初始化为普通的GPIO脚,然后设置中断,当电平变化时产生中断唤醒
①uart口改普通GPIO(重映射)
在保护板休眠时,初始化该引脚,主要是红框处的重映射函数
并且在对引脚进行重映射后,需要开启复用时钟【RCC_APB2Periph_AFIO】
当前USART1用到的引脚是PA9(USART1_TX),PA10(USART1_RX),但是这个时候刚好PA9和PA10这两个引脚已经用于其他用途了,那么我们就不能用这两个引脚了,那么问题来了,那我们是不是就不能使用USART1了呢?NO,这个时候重映射就发挥了他的作用了,我们可以通过将USART1的功能引脚重新映射到PB6(USART1_TX),PB7(USART1_RX)。
使用端口的重映射的时候,需要开启复用时钟AFIO
【RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); 】
之后配置中断
这里配置为普通GPIO口中断时,最好还是需要重映射一下
注意:此时uart的rx脚为PA3,那么中断线路、中断通道也一定要选Line3!
如果其他不同端口同一pin需要中断是不可能的,不同端口同一pin只能用一个通道,不能共用或想其他办法用,例如PA3与PB3只能一个用中断通道line3,要么PA3用,要么PB3用。
该中断配置为上拉输入 下降沿触发中断
产生中断后,会进入到这个中断函数来
代码如下
//休眠时重定义为普通IO口 IO.c
void JlinkGPIOInit(void)//Jlink功能口PB3、PB4,定义为普通GPIO
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA| RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
/* Push-pill output, it can be other output types */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
//WAKEUP.c 中断配置
void HAL_UART_INTERR_WAKEUP_EN(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);//使能GPIOA和复用功能时钟
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_3; //PA.0
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPU;
//GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化IO
//使用外部中断方式
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource3); //中断线0连接GPIOA.0
EXTI_InitStructure.EXTI_Line = EXTI_Line3; //设置按键所有的外部线路
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //设外外部中断模式:EXTI线路为中断请求
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //边沿触发
//EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; //边沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure); // 初始化外部中断
NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn; //使能按键所在的外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级2级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级2级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
}