首先说一下问题的现象,如果有这种现象的同学可以看看博主的这篇博文 程序download一次后,第二次download就提示no target connect,除非长按reset键才能继续下载程序 首先上一组stm32的TIM2的端口使用组合有下面四种: 1.当不重映射时,默认TIM2四个的IO口是PA0、PA1、PA2、PA3 开启重映射__HAL_AFIO_REMAP_TIM2_ENABLE() 2.要使用PA15、PB3、PA2、PA3的端口组合,要调用下面的语句进行部分重映射: __HAL_AFIO_REMAP_TIM2_PARTIAL_1() 3.要使用PA0、PA1、PB10、PB11的端口组合,要调用下面的语句进行部分重映射: __HAL_AFIO_REMAP_TIM2_PARTIAL_2() 4.要使用PA15、PB3、PB10、PB11的端口组合,要调用下面的语句进行完全重映射: __HAL_AFIO_REMAP_TIM2_ENABLE() 同时还要禁用JTAG功能,PA15、PB3、PB10、PB11才会正常输出。 那么使用了重映射之后会导致一个问题,程序download一次后,第二次download就提示no target connect,除非长按reset键才能继续下载程序。 该问题讨论可在此问答中找到答案 从该帖子找到的精辟回答如下 The problem is that the STM32F1 series has one register See this extract from the STM32F1Reference Manual: This means that any attempt to change the settings of thevarious "peripheral remap" bits, by doing a read-modify-writesequence to this register, could read differentvalues instead of the real current valuesin the JTAG/SWD bits. Then, when the write to the register is done, your debugger access stopsbecause whatever was read from those JTAG/SWD bits, is written back to them.(Other effects have also been reported, but I won't go into that now). From what I could find without installing the HAL, the macrosused are:
and
So as you see, The "fix" I have used with the SPL, is to change anyremapping code to specifically set the JTAG/SWD bits which you want, wheneveryou write to the · Read AFIO_MAPR register intotemp variable · Change desired peripheralremap bits in the temp variable · Mask out bits 24-26 in thetemp variable · Set bits 24-26 in the tempvariable to whatever I wanted (therefore ignoring whatever their, likelyincorrect, "read" value was) · Write temp variable toAFIO_MAPR 基本上导致这个问题的原因在于SWJ_CFG[2]位是Write Only的, __HAL_AFIO_REMAP_I2C1_ENABLE()中会执行类似reg |= xxx_enable的操作 该操作会读寄存器,然后或上某个使能位 然而由于SWJ_CFG[2]位的Write Only特性,导致寄存器读出来后不是实际的值 解决方法:在使用了引脚复用的宏之后需要调用一次__HAL_AFIO_REMAP_SWJ_NOJTAG(),该宏的解释如下: /** * @brief Enable the Serial wire JTAG configuration * @note NOJTAG: JTAG-DP Disabledand SW-DP Enabled * @retval None */ #define__HAL_AFIO_REMAP_SWJ_NOJTAG() do{CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_SWJ_CFG); \ SET_BIT(AFIO->MAPR, AFIO_MAPR_SWJ_CFG_JTAGDISABLE); \ }while(0U) 我们追一下CLEAR_BIT(AFIO->MAPR,AFIO_MAPR_SWJ_CFG); 可以发现#defineCLEAR_BIT(REG, BIT) ((REG) &=~(BIT)) 继续追该宏使用的参数AFIO->MAPR,AFIO_MAPR_SWJ_CFG,其中MAPR为复用寄存器,而AFIO_MAPR_SWJ_CFG追到最后为0x07000000(过程比较多,就不赘述了),再通过&= ~(BIT)操作,得出&=~(0111000000000000000000000000) 最后结果为&=11111000111111111111111111111111 这个时候可以看出来在CLEAR_BIT(AFIO->MAPR,AFIO_MAPR_SWJ_CFG);宏的作用是使得MAPR寄存器的Bits 26:24重置为0。 这个时候博主把MAPR寄存器放出来 可以发现是重新复位了SWJ,也就是重置了JTAG位的功能。
接下来我们再看SET_BIT(AFIO->MAPR,AFIO_MAPR_SWJ_CFG_JTAGDISABLE); 功能函数#defineSET_BIT(REG, BIT) ((REG) |= (BIT)) 直接追AFIO_MAPR_SWJ_CFG_JTAGDISABLE,最后得出该值是0x02000000 所以该值操作为|=02000000,即|=00000 010 000000000000000000000000 重新看该值010在寄存器的作用,可以发现现在使能了SWD的调试功能了。 |
|