STM32F103:SWJ调试端口设置成普通I/O口——PA13,PA14,PA15,PB3,PB4

本文章技术信息均出自:STM32F103系列超详细参考手册-中文版


一、SWJ调试端口

STM32有两种程序调试接口(程序烧写口),具体如下:
SWD调试接口: PA13、PA14共两个引脚。
JTAG调试接口: PA13、PA14、PA15、PB3、PB4共五个引脚。
在这里插入图片描述
单片机启动后,初始状态这五个引脚就默认是调试接口。
而实际使用中,一般只使用 SWCLK、SWDIO这两个引脚用做SW调试接口。
其余的三个引脚可以空出来,重新定义为普通I/O来使用。
如果需要将它们用作普通IO口,需要进行引脚复用,禁止调试功能。

二、SWJ调试端口设置成普通I/O口步骤

1. 配置复用时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE ); //配置复用时钟

2. 禁用调试功能

GPIO_PinRemapConfig(GPIO_Remap_SWJ_NoJTRST, ENABLE); //全功能SW+JTAG,禁用JTRST,PB4可用
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); //启用SW,禁用JTAG,PA15、PB3、PB4可用
GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE); //完全禁用SW+JTAG,PA13、PA14、PA15、PB3、PB4可用

SWJ调试端口,只能使用以上3种重映射方法,不可对单独引脚设置。

三、SWJ调试端口设置成普通I/O口程序

/* 禁用 JTAG,PB3、PB4、PA15重定义为普通IO */
	GPIO_InitTypeDef  GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);//使能PA和PB端口时钟
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE ); //配置复用时钟
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);//启用SW,禁用JTAG,PA15、PB3、PB4可用
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_3;	//端口配置
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;		//推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		//IO口速度为50MHz
	GPIO_Init(GPIOB, &GPIO_InitStructure);					//根据设定参数初始化
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;				//端口配置
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;		//推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		//IO口速度为50MHz
	GPIO_Init(GPIOA, &GPIO_InitStructure);					//根据设定参数初始化

注意:第三种方法,完全禁用SW+JTAG后,就没有程序烧写口了,谨慎使用!!!


<think>好的,我现在需要处理用户关于STM32F103C8T6如何通过PA0、PB1、PB3PB4来唤醒STOP模式的问题。首先,我得回忆一下STM32的STOP模式以及唤醒机制的相关知识。 首先,STOP模式是STM32的一种低功耗模式,它会关闭大部分时钟和 peripherals,但保留RAM和寄存器的内容。要唤醒STOP模式,通常可以通过外部中断或事件,或者特定的唤醒引脚。不过,不同型号的STM32可能有不同的唤醒源,所以需要确认F103C8T6的具体情况。 接下来,用户提到的PA0、PB1、PB3PB4这几个引脚是否能作为唤醒源。根据STM32F1系列的参考手册,外部中断线EXTI0到EXTI15都可以用于唤醒STOP模式,但每个EXTI线对应特定的GPIO引脚。例如,PA0对应EXTI0,PB0也对应EXTI0,但同一时间只能有一个引脚连接到同一个EXTI线。所以可能需要配置这些引脚为EXTI模式,并确保它们连接到正确的EXTI线。 然后,需要确定这些GPIO是否可以配置为外部中断。例如,PA0对应EXTI0,PB1对应EXTI1,PB3对应EXTI3PB4对应EXTI4。这样的话,每个引脚都可以独立配置为对应的EXTI线,从而作为唤醒源。但要注意,在STOP模式下,系统时钟会被关闭,所以需要配置这些EXTI线为事件或中断模式,并且可能需要在进入STOP模式前启用相应的中断。 接下来,考虑配置步骤。首先,启用GPIO和AFIO时钟,因为配置外部中断需要复用功能。然后,配置各个GPIO引脚为输入模式,并启用上拉或下拉电阻,根据外部触发信号的电平来决定。接着,配置EXTI线,选择对应的GPIO端口,例如PA0对应EXTI0,需要配置AFIO的EXTICR寄存器,将EXTI0的源选择为PA0。同样的,PB1对应EXTI1,需要设置EXTICR寄存器为PB1,依此类推。然后,配置EXTI线的触发方式,比如上升沿、下降沿或双边沿触发。之后,需要使能EXTI的中断或事件,并在NVIC中配置相应的中断通道,如果使用中断的话。 但是,在STOP模式下,是否必须使用中断,还是事件也可以唤醒?根据资料,STOP模式可以通过外部事件(不需要中断服务程序)来唤醒,但可能需要配置为事件模式。不过,通常唤醒STOP模式需要将EXTI配置为中断模式,并且在进入STOP前使能相应的中断,并且在唤醒后,系统会继续执行进入STOP模式后的代码。因此,可能需要配置这些EXTI线为中断,并且编写相应的中断服务函数,但中断处理函数中是否需要清除标志位呢? 另外,进入STOP模式后,系统时钟会被关闭,唤醒后会使用HSI作为系统时钟,所以用户需要在唤醒后重新配置系统时钟,比如切换回HSE或其他时钟源。这一点需要提醒用户注意,否则程序可能运行异常。 还有,PB3PB4STM32F10x系列中默认是JTAG引脚,如果用户没有禁用JTAG,那么这两个引脚可能无法作为普通GPIO使用。因此,需要确保在配置PB3PB4之前,禁用JTAG功能,通过AFIO的配置寄存器将SWJ调试设置为SWD模式,从而释放PB3PB4作为普通GPIO。 接下来,总结一下步骤: 1. 配置PA0、PB1、PB3PB4为输入模式,并设置上拉/下拉电阻。 2. 禁用JTAG(针对PB3PB4),启用SWD模式。 3. 配置AFIO的EXTICRx寄存器,将每个引脚连接到对应的EXTI线。 4. 配置EXTI触发条件(上升沿、下降沿等)。 5. 使能EXTI中断,并在NVIC中配置中断优先级。 6. 进入STOP模式前,确保PWR_CR中的唤醒位设置正确。 7. 进入STOP模式后,当任一引脚触发EXTI中断,系统唤醒,时钟恢复为HSI,需要重新配置系统时钟。 8. 处理中断标志位,可能需要清除相应的EXTI挂起位。 同时,用户需要注意,在进入STOP模式前,应该关闭不需要的外设以节省功耗,并且在唤醒后重新初始化系统时钟和外设。 可能遇到的问题包括:PB3PB4无法配置为EXTI,因为没有禁用JTAG;唤醒后时钟未正确配置导致程序错误;或者多个EXTI线共享同一个中断向量,需要在中继函数中判断具体的中断源。 最后,需要给出一个示例代码的大致框架,帮助用户理解配置过程,并提醒注意事项,比如JTAG、时钟配置等。</think>以下是如何配置STM32F103C8T6通过PA0、PB1、PB3PB4引脚唤醒STOP模式的步骤详解: --- ### **1. 原理说明** - **STOP模式**:关闭主时钟(HCLK、PCLK1/2),仅保留SRAM和寄存器内容,功耗极低。唤醒后需重新配置系统时钟。 - **唤醒源**:支持外部中断(EXTI)的引脚,触发条件为上升沿、下降沿或双边沿。每个GPIO可映射到对应的EXTI线(如PA0→EXTI0,PB1→EXTI1等)。 --- ### **2. 关键配置步骤** #### **(1) 释放PB3PB4引脚** PB3(JTDO)和PB4(JNTRST)默认用于JTAG,需禁用JTAG以复用为GPIO: ```c RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); // 仅保留SWD调试 ``` #### **(2) 配置GPIO为输入模式** ```c GPIO_InitTypeDef GPIO_InitStruct; // PA0配置 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD; // 下拉输入(根据实际信号选择) GPIO_Init(GPIOA, &GPIO_InitStruct); // PB1、PB3PB4配置(同理) GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_3 | GPIO_Pin_4; GPIO_Init(GPIOB, &GPIO_InitStruct); ``` #### **(3) 映射GPIO到EXTI线** ```c // PA0 → EXTI0 GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); // PB1 → EXTI1 GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1); // PB3 → EXTI3 GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource3); // PB4 → EXTI4 GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource4); ``` #### **(4) 配置EXTI触发条件** ```c EXTI_InitTypeDef EXTI_InitStruct; EXTI_InitStruct.EXTI_Line = EXTI_Line0 | EXTI_Line1 | EXTI_Line3 | EXTI_Line4; EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; // 中断模式 EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising; // 上升沿触发(按需修改) EXTI_InitStruct.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStruct); ``` #### **(5) 使能NVIC中断** ```c NVIC_InitTypeDef NVIC_InitStruct; // EXTI0中断(PA0) NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x0F; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x0F; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct); // EXTI1(PB1)、EXTI3PB3)、EXTI4PB4)同理配置 ``` --- ### **3. 进入与唤醒STOP模式** #### **(1) 进入STOP模式** ```c // 清除唤醒标志 PWR_ClearFlag(PWR_FLAG_WU); // 进入STOP模式(设置低功耗调节器) PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); ``` #### **(2) 唤醒后处理** 唤醒后系统时钟切换为HSI(8MHz),需重新配置时钟: ```c SystemInit(); // 重新初始化HSE等时钟 // 重新配置外设(如GPIO、USART等) ``` --- ### **4. 中断服务函数示例** ```c // EXTI0中断处理(PA0) void EXTI0_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line0) != RESET) { EXTI_ClearITPendingBit(EXTI_Line0); // 清除中断标志 } } // EXTI1(PB1)、EXTI3PB3)、EXTI4PB4)同理 ``` --- ### **注意事项** 1. **JTAG问题**:若未禁用JTAG,PB3/PB4无法作为普通GPIO。 2. **时钟恢复**:唤醒后需调用`SystemInit()`重新配置时钟(如使用HSE)。 3. **功耗优化**:进入STOP模式前关闭ADC、定时器等外设。 4. **中断冲突**:同一EXTI线(如EXTI0)不可同时分配给多个引脚。 通过以上配置,PA0、PB1、PB3PB4任一引脚触发信号均可唤醒STOP模式。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

根号五

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值